我的编程空间,编程开发者的网络收藏夹
学习永远不晚

一文吃透接口调用神器RestTemplate

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

一文吃透接口调用神器RestTemplate

文末可以领取所有系列高清 pdf。

大家好,我是路人,这是 SpringMVC 系列第 21 篇。

本文介绍 Spring web 中特别牛逼的一个类 RestTemplate。

目录

  • RestTemplate 概述

  • 案例代码

    • 1、git 地址

    • 2、关键代码位置

    • 3、如何运行测试用例?

  • 发送 Get 请求

    • 1、普通请求

    • 2、url 中含有动态参数

    • 3、接口返回值为泛型

    • 4、下载小文件

    • 5、下载大文件

    • 6、传递头

    • 7、综合案例:含头、url 动态参数

  • POST 请求

    • 1、post 请求常见的 3 种类型

    • 2、普通表单请求

    • 3、上传本地文件

    • 4、通过流或字节数组的方式上传文件

    • 5、复杂表单:多个普通元素+多文件上传

    • 6、发送 json 格式数据:传递 java 对象

    • 7、发送 json 格式数据:传递 java 对象,返回值为泛型

    • 8、发送 json 字符串格式数据

  • DELETE、PUT、OPTION 请求

    • 1、DELETE 请求

    • 2、PUT 请求

    • 3、OPTIONS 请求

  • 集成 HttpClient

  • 集成 okhttp

  • 总结

  • SpringMVC 系列目录

  • 更多好文章

  • 【路人甲 Java】所有系列高清 PDF

1、RestTemplate 概述

发送 http 请求,估计很多人用过 httpclient 和 okhttp,确实挺好用的,而 Spring web 中的 RestTemplate 和这俩的功能类似,也是用来发送 http 请求的,不过用法上面比前面的 2 位要容易很多。

spring 框架提供的 RestTemplate 类可用于在应用中调用 rest 服务,它简化了与 http 服务的通信方式,统一了 RESTful 的标准,封装了 http 链接, 我们只需要传入 url 及返回值类型即可。相较于之前常用的 HttpClient,RestTemplate 是一种更优雅的调用 RESTful 服务的方式。

在 Spring 应用程序中访问第三方 REST 服务与使用 Spring RestTemplate 类有关。RestTemplate 类的设计原则与许多其他 Spring 模板类(例如 JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。

RestTemplate 默认依赖 JDK 提供 http 连接的能力(HttpURLConnection),如果有需要的话也可以通过 setRequestFactory 方法替换为例如 Apache HttpComponents、Netty 或 OkHttp 等其它 HTTP library。

考虑到 RestTemplate 类是为调用 REST 服务而设计的,因此它的主要方法与 REST 的基础紧密相连就不足为奇了,后者是 HTTP 协议的方法:HEAD、GET、POST、PUT、DELETE 和 OPTIONS。例如,RestTemplate 类具有 headForHeaders()、getForObject()、postForObject()、put()和 delete()等方法。

下面给大家上案例,案例是重点,通过案例,把我知道的用法都给盘出来。

2、案例代码

2.1、git 地址

https://gitee.com/javacode2018/springmvc-series

10d8584b55c22fe2e509a0a93fc0126a.png

2.2、关键代码位置

文中的所有 controller 代码,在RestTemplateTestController类中。

所有@Test 用例的代码,在RestTemplateTest

3c0bd3eaa63e802b41c52ec909fae3a5.png

2.3、如何运行测试用例?

  • 拉取项目

  • 将 chat16-RestTemplate 模块发布到 tomcat9 中

  • 运行 RestTemplateTest 中对应的用例即可

下面咱们来看 RestTemplate 常见的用法汇总。

3、发送 Get 请求

3.1、普通请求

接口代码

@GetMapping("/test/get")@ResponseBodypublic BookDto get() {    return new BookDto(1, "SpringMVC系列");}

使用 RestTemplate 调用上面这个接口,通常有 2 种写法,如下

@Testpublic void test1() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/get";    //getForObject方法,获取响应体,将其转换为第二个参数指定的类型    BookDto bookDto = restTemplate.getForObject(url, BookDto.class);    System.out.println(bookDto);}@Testpublic void test2() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/get";    //getForEntity方法,返回值为ResponseEntity类型    // ResponseEntity中包含了响应结果中的所有信息,比如头、状态、body    ResponseEntity responseEntity = restTemplate.getForEntity(url, BookDto.class);    //状态码    System.out.println(responseEntity.getStatusCode());    //获取头    System.out.println("头:" + responseEntity.getHeaders());    //获取body    BookDto bookDto = responseEntity.getBody();    System.out.println(bookDto);}

test1 输出

BookDto{id=1, name='SpringMVC系列'}

test2 输出

200 OK头:[Content-Type:"application/json;charset=UTF-8", Transfer-Encoding:"chunked", Date:"Sat, 02 Oct 2021 07:05:15 GMT", Keep-Alive:"timeout=20", Connection:"keep-alive"]BookDto{id=1, name='SpringMVC系列'}

3.2、url 中含有动态参数

接口代码

@GetMapping("/test/get/{id}/{name}")@ResponseBodypublic BookDto get(@PathVariable("id") Integer id, @PathVariable("name") String name) {    return new BookDto(id, name);}

使用 RestTemplate 调用上面这个接口,通常有 2 种写法,如下

@Testpublic void test3() {    RestTemplate restTemplate = new RestTemplate();    //url中有动态参数    String url = "http://localhost:8080/chat16/test/get/{id}/{name}";    Map uriVariables = new HashMap<>();    uriVariables.put("id", "1");    uriVariables.put("name", "SpringMVC系列");    //使用getForObject或者getForEntity方法    BookDto bookDto = restTemplate.getForObject(url, BookDto.class, uriVariables);    System.out.println(bookDto);}@Testpublic void test4() {    RestTemplate restTemplate = new RestTemplate();    //url中有动态参数    String url = "http://localhost:8080/chat16/test/get/{id}/{name}";    Map uriVariables = new HashMap<>();    uriVariables.put("id", "1");    uriVariables.put("name", "SpringMVC系列");    //getForEntity方法    ResponseEntity responseEntity = restTemplate.getForEntity(url, BookDto.class, uriVariables);    BookDto bookDto = responseEntity.getBody();    System.out.println(bookDto);}

test3 输出

BookDto{id=1, name='SpringMVC系列'}

test4 输出

BookDto{id=1, name='SpringMVC系列'}

3.3、接口返回值为泛型

接口代码

@GetMapping("/test/getList")@ResponseBodypublic List getList() {    return Arrays.asList(            new BookDto(1, "Spring高手系列"),            new BookDto(2, "SpringMVC系列")    );}

当接口的返回值为泛型的时候,这种情况比较特殊,使用 RestTemplate 调用上面这个接口,代码如下,需要用到restTemplate.exchange的方法,这个方法中有个参数是ParameterizedTypeReference类型,通过这个参数类指定泛型类型

@Testpublic void test5() {    RestTemplate restTemplate = new RestTemplate();    //返回值为泛型    String url = "http://localhost:8080/chat16/test/getList";    //若返回结果是泛型类型的,需要使用到exchange方法,    //这个方法中有个参数是ParameterizedTypeReference类型,通过这个参数类指定泛型类型    ResponseEntity> responseEntity =            restTemplate.exchange(url,                    HttpMethod.GET,                    null,                    new ParameterizedTypeReference>() {                    });    List bookDtoList = responseEntity.getBody();    System.out.println(bookDtoList);}

输出

[BookDto{id=1, name='Spring高手系列'}, BookDto{id=2, name='SpringMVC系列'}]

3.4、下载小文件

接口代码如下,这个接口会下载服务器端的 1.txt 文件。

@GetMapping("/test/downFile")@ResponseBodypublic HttpEntity downFile() {    //将文件流封装为InputStreamResource对象    InputStream inputStream = this.getClass().getResourceAsStream("/1.txt");    InputStreamResource inputStreamResource = new InputStreamResource(inputStream);    //设置header    MultiValueMap headers = new HttpHeaders();    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=1.txt");    HttpEntity httpEntity = new HttpEntity<>(inputStreamResource);    return httpEntity;}

使用 RestTemplate 调用这个接口,代码如下,目前这个文件的内容比较少,可以直接得到一个数组。

@Testpublic void test6() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/downFile";    //文件比较小的情况,直接返回字节数组    ResponseEntity responseEntity = restTemplate.getForEntity(url, byte[].class);    //获取文件的内容    byte[] body = responseEntity.getBody();    String content = new String(body);    System.out.println(content);}

注意:如果文件大的时候,这种方式就有问题了,会导致 oom,要用下面的方式了。

3.5、下载大文件

接口代码,继续使用上面下载 1.txt 的代码

@GetMapping("/test/downFile")@ResponseBodypublic HttpEntity downFile() {    //将文件流封装为InputStreamResource对象    InputStream inputStream = this.getClass().getResourceAsStream("/1.txt");    InputStreamResource inputStreamResource = new InputStreamResource(inputStream);    //设置header    MultiValueMap headers = new HttpHeaders();    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=1.txt");    HttpEntity httpEntity = new HttpEntity<>(inputStreamResource);    return httpEntity;}

此时使用 RestTemplate 调用这个接口,代码如下

文件比较大的时候,比如好几个 G,就不能返回字节数组了,会把内存撑爆,导致 OOM,需要使用 execute 方法了,这个方法中有个 ResponseExtractor 类型的参数,restTemplate 拿到结果之后,会回调{@link ResponseExtractor#extractData}这个方法,在这个方法中可以拿到响应流,然后进行处理,这个过程就是变读边处理,不会导致内存溢出

@Testpublic void test7() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/downFile";        String result = restTemplate.execute(url,            HttpMethod.GET,            null,            new ResponseExtractor() {                @Override                public String extractData(ClientHttpResponse response) throws IOException {                    System.out.println("状态:"+response.getStatusCode());                    System.out.println("头:"+response.getHeaders());                    //获取响应体流                    InputStream body = response.getBody();                    //处理响应体流                    String content = IOUtils.toString(body, "UTF-8");                    return content;                }            }, new HashMap<>());    System.out.println(result);}

3.6、传递头

接口代码

@GetMapping("/test/header")@ResponseBodypublic Map> header(HttpServletRequest request) {    Map> header = new LinkedHashMap<>();    Enumeration headerNames = request.getHeaderNames();    while (headerNames.hasMoreElements()) {        String name = headerNames.nextElement();        Enumeration values = request.getHeaders(name);        List list = new ArrayList<>();        while (values.hasMoreElements()) {            list.add(values.nextElement());        }        header.put(name, list);    }    return header;}

使用 RestTemplate 调用接口,请求头中传递数据,代码如下,注意代码①和②,这两处是关键,用到了HttpHeadersRequestEntity

  • 请求头放在 HttpHeaders 对象中

  • RequestEntity:请求实体,请求的所有信息都可以放在 RequestEntity 中,比如 body 部分、头、请求方式、url 等信息

@Testpublic void test8() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/header";    //①:请求头放在HttpHeaders对象中    MultiValueMap headers = new HttpHeaders();    headers.add("header-1", "V1");    headers.add("header-2", "Spring");    headers.add("header-2", "SpringBoot");    //②:RequestEntity:请求实体,请求的所有信息都可以放在RequestEntity中,比如body部分、头、请求方式、url等信息    RequestEntity requestEntity = new RequestEntity(            null, //body部分数据            headers, //头            HttpMethod.GET,//请求方法            URI.create(url) //地址    );    ResponseEntity>> responseEntity = restTemplate.exchange(requestEntity,            new ParameterizedTypeReference>>() {            });    Map> result = responseEntity.getBody();    System.out.println(result);}

输出

{accept=[application/json, application    InputStream inputStream = RestTemplateTest.class.getResourceAsStream("/1.txt");    InputStreamResource inputStreamResource = new InputStreamResource(inputStream) {        @Override        public String getFilename() {            return "1.txt";        }        @Override        public long contentLength() throws IOException {            return inputStream.available();        }    };    body.add("file1", inputStreamResource);    //③:头    HttpHeaders headers = new HttpHeaders();    headers.add("header1", "v1");    headers.add("header2", "v2");    //④:请求实体    RequestEntity> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));    //⑤:发送请求(请求实体,返回值需要转换的类型)    ResponseEntity> responseEntity = restTemplate.exchange(            requestEntity,            new ParameterizedTypeReference>() {            });    Map result = responseEntity.getBody();    System.out.println(result);}

4.5、复杂表单:多个普通元素+多文件上传

接口

@PostMapping("/test/form3")@ResponseBodypublic Map form3(UserDto userDto) {    Map result = new LinkedHashMap<>();    result.put("name", userDto.getName());    result.put("headImg", userDto.getHeadImg().getOriginalFilename());    result.put("idImgList", Arrays.toString(userDto.getIdImgList().stream().                                            map(MultipartFile::getOriginalFilename).toArray()));    return result;}

UserDto:包含了多个元素(姓名、头像、多张证件照),这种可以模拟复杂的表单

public class UserDto {    //姓名    private String name;    //头像    private MultipartFile headImg;    //多张证件照    private List idImgList;    //get set 省略了...}

用 RestTemplate 调用这个接口,代码如下

@Testpublic void test14() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/form3";    //①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map>    MultiValueMap body = new LinkedMultiValueMap<>();    body.add("name", "路人");    body.add("headImg", new FileSystemResource(".\\class="lazy" data-src\\main\\resources\\1.jpg"));    //来2张证件照,元素名称一样    body.add("idImgList", new FileSystemResource(".\\class="lazy" data-src\\main\\resources\\2.jpg"));    body.add("idImgList", new FileSystemResource(".\\class="lazy" data-src\\main\\resources\\3.jpg"));    //③:头    HttpHeaders headers = new HttpHeaders();    headers.add("header1", "v1");    headers.add("header2", "v2");    //④:请求实体    RequestEntity> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));    //⑤:发送请求(请求实体,返回值需要转换的类型)    ResponseEntity> responseEntity = restTemplate.exchange(            requestEntity,            new ParameterizedTypeReference>() {            });    Map result = responseEntity.getBody();    System.out.println(result);}

输出

{name=路人, headImg=1.jpg, idImgList=[2.jpg, 3.jpg]}

4.6、发送 json 格式数据:传递 java 对象

接口

@PostMapping("/test/form4")@ResponseBodypublic BookDto form4(@RequestBody BookDto bookDto) {    return bookDto;}

RestTemplate 调用接口

@Testpublic void test15() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/form4";    BookDto body = new BookDto(1, "SpringMVC系列");    BookDto result = restTemplate.postForObject(url, body, BookDto.class);    System.out.println(result);}

输出

BookDto{id=1, name='SpringMVC系列'}

4.7、发送 json 格式数据:传递 java 对象,返回值为泛型

接口

@PostMapping("/test/form5")@ResponseBodypublic List form5(@RequestBody List bookDtoList) {    return bookDtoList;}

用 RestTemplate 调用这个接口,代码如下

@Testpublic void test16() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/form5";    //①:请求体,发送的时候会被转换为json格式数据    List body = Arrays.asList(            new BookDto(1, "SpringMVC系列"),            new BookDto(2, "MySQL系列"));    //②:头    HttpHeaders headers = new HttpHeaders();    headers.add("header1", "v1");    headers.add("header2", "v2");    //③:请求实体    RequestEntity requestEntity = new RequestEntity(body, headers, HttpMethod.POST, URI.create(url));    //④:发送请求(请求实体,返回值需要转换的类型)    ResponseEntity> responseEntity = restTemplate.exchange(            requestEntity,            new ParameterizedTypeReference>() {            });    //⑤:获取结果    List result = responseEntity.getBody();    System.out.println(result);}

输出

[BookDto{id=1, name='SpringMVC系列'}, BookDto{id=2, name='MySQL系列'}]

4.8、发送 json 字符串格式数据

上面 2 个 json 案例 body 都是 java 对象,RestTemplate 默认自动配上 Content-Type=application/json

但是如果 body 的值是 json 格式字符串的时候,调用的时候需要在头中明确指定 Content-Type=application/json,写法如下:

@Testpublic void test17() {    RestTemplate restTemplate = new RestTemplate();    String url = "http://localhost:8080/chat16/test/form5";    //①:请求体为一个json格式的字符串    String body = "[{\"id\":1,\"name\":\"SpringMVC系列\"},{\"id\":2,\"name\":\"MySQL系列\"}]";        HttpHeaders headers = new HttpHeaders();    headers.setContentType(MediaType.APPLICATION_JSON);    //③:请求实体(body,头、请求方式,uri)    RequestEntity requestEntity = new RequestEntity(body, headers, HttpMethod.POST, URI.create(url));    //④:发送请求(请求实体,返回值需要转换的类型)    ResponseEntity> responseEntity = restTemplate.exchange(            requestEntity,            new ParameterizedTypeReference>() {            });    //⑤:获取结果    List result = responseEntity.getBody();    System.out.println(result);}

输出

[BookDto{id=1, name='SpringMVC系列'}, BookDto{id=2, name='MySQL系列'}]

5、DELETE、PUT、OPTION 请求

5.1、DELETE 请求

public void delete(String url, Object... uriVariables);public void delete(String url, Map uriVariables);public void delete(URI url);

5.2、PUT 请求

PUT 请求和 POST 请求类似,将类型改为 PUT 就可以了。

5.3、OPTIONS 请求

OPTIONS 请求用来探测接口支持哪些 http 方法

public Set optionsForAllow(String url, Object... uriVariables);public Set optionsForAllow(String url, Map uriVariables);public Set optionsForAllow(URI url);

6、集成 HttpClient

RestTemplate 内部默认用的是 jdk 自带的 HttpURLConnection 发送请求的,性能上面并不是太突出。

可以将其替换为 httpclient 或者 okhttp。

先来看下如何替换为 HttpClient。

引入 maven 配置

    org.apache.httpcomponents    httpclient    4.5.7

创建 RestTemplate 时指定 HttpClient 配置,代码如下

public HttpClient httpClient() {    HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();    try {        //设置信任ssl访问        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (arg0, arg1) -> true).build();        httpClientBuilder.setSSLContext(sslContext);        HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);        Registry socketFactoryRegistry = RegistryBuilder.create()                // 注册http和https请求                .register("http", PlainConnectionSocketFactory.getSocketFactory())                .register("https", sslConnectionSocketFactory).build();        //使用Httpclient连接池的方式配置(推荐),同时支持netty,okHttp以及其他http框架        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);        // 最大连接数        poolingHttpClientConnectionManager.setMaxTotal(1000);        // 同路由并发数        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);        //配置连接池        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);        // 重试次数        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(0, true));        //设置默认请求头        List
 headers = new ArrayList<>();        httpClientBuilder.setDefaultHeaders(headers);        return httpClientBuilder.build();    } catch (Exception e) {        throw new RuntimeException(e);    }}public ClientHttpRequestFactory clientHttpRequestFactory() {    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient());    // 连接超时(毫秒),这里设置10秒    clientHttpRequestFactory.setConnectTimeout(10 * 1000);    // 数据读取超时时间(毫秒),这里设置60秒    clientHttpRequestFactory.setReadTimeout(60 * 1000);    // 从连接池获取请求连接的超时时间(毫秒),不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的    clientHttpRequestFactory.setConnectionRequestTimeout(10 * 1000);    return clientHttpRequestFactory;}public RestTemplate restTemplate(){    //创建RestTemplate的时候,指定ClientHttpRequestFactory    return new RestTemplate(this.clientHttpRequestFactory());}@Testpublic void test18() {    RestTemplate restTemplate = this.restTemplate();    String url = "http://localhost:8080/chat16/test/get";    //getForObject方法,获取响应体,将其转换为第二个参数指定的类型    BookDto bookDto = restTemplate.getForObject(url, BookDto.class);    System.out.println(bookDto);}

7、集成 okhttp

引入 maven 配置

    com.squareup.okhttp3    okhttp    4.3.1

创建 RestTemplate

new RestTemplate(new OkHttp3ClientHttpRequestFactory());

8、总结

RestTemplate 使用确实非常容易,建议大家去看一下 RestTemplate 的源码,debug 跟踪一下过程,这样用起来就非常顺手了。

尚硅谷 Java 学科全套教程(总 207.77GB)

9、SpringMVC 系列目录

  1. SpringMVC 系列第 1 篇:helloword

  2. SpringMVC 系列第 2 篇:@Controller、@RequestMapping

  3. SpringMVC 系列第 3 篇:异常高效的一款接口测试利器

  4. SpringMVC 系列第 4 篇:controller 常见的接收参数的方式

  5. SpringMVC 系列第 5 篇:@RequestBody 大解密,说点你不知道的

  6. SpringMVC 系列第 6 篇:上传文件的 4 种方式,你都会么?

  7. SpringMVC 系列第 7 篇:SpringMVC 返回视图常见的 5 种方式,你会几种?

  8. SpringMVC 系列第 8 篇:返回 json & 通用返回值设计

  9. SpringMVC 系列第 9 篇:SpringMVC 返回 null 是什么意思?

  10. SpringMVC 系列第 10 篇:异步处理

  11. SpringMVC 系列第 11 篇:集成静态资源

  12. SpringMVC 系列第 12 篇:拦截器

  13. SpringMVC 系列第 13 篇:统一异常处理

  14. SpringMVC 系列第 14 篇:实战篇:通用返回值 & 异常处理设计

  15. SpringMVC 系列第 15 篇:全注解的方式  &  原理解析

  16. SpringMVC 系列第 16 篇:通过源码解析 SpringMVC 处理请求的流程

  17. SpringMVC 系列第 17 篇:源码解析 SpringMVC 容器的启动过程

  18. SpringMVC 系列第 18 篇:强大的 RequestBodyAdvice 解密

  19. SpringMVC 系列第 19 篇:强大的 ResponseBodyAdvice 解密

  20. SpringMVC 系列第 20 篇:RestFull 详解

10、更多好文章

  1. Spring 高手系列(共 56 篇)

  2. Java 高并发系列(共 34 篇)

  3. MySql 高手系列(共 27 篇)

  4. Maven 高手系列(共 10 篇)

  5. Mybatis 系列(共 12 篇)

  6. 聊聊 db 和缓存一致性常见的实现方式

  7. 接口幂等性这么重要,它是什么?怎么实现?

  8. 泛型,有点难度,会让很多人懵逼,那是因为你没有看这篇文章!

11、【路人甲 Java】所有系列高清 PDF

领取方式,扫码发送:yyds

84e19fb78bd1cedc2cba886ea5c699bc.png

来源地址:https://blog.csdn.net/likun557/article/details/121072832

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

一文吃透接口调用神器RestTemplate

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录