4.6、发送 json 格式数据:传递 java 对象
接口
/** * body中json格式的数据,返回值非泛型 * * @param bookDto * @return */ @PostMapping("/test/form4") @ResponseBody public BookDto form4(@RequestBody BookDto bookDto) { return bookDto; }
RestTemplate 调用接口
@Test public 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 对象,返回值为泛型
接口
/** * body中json格式的数据,返回值为泛型 * * @param bookDtoList * @return */ @PostMapping("/test/form5") @ResponseBody public List<BookDto> form5(@RequestBody List<BookDto> bookDtoList) { return bookDtoList; }
用 RestTemplate 调用这个接口,代码如下
@Test public void test16() { RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/chat16/test/form5"; //①:请求体,发送的时候会被转换为json格式数据 List<BookDto> 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<List<BookDto>> responseEntity = restTemplate.exchange( requestEntity, new ParameterizedTypeReference<List<BookDto>>() { }); //⑤:获取结果 List<BookDto> 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,写法如下:
@Test public 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系列\"}]"; /** * ②:若请求体为json字符串的时候,需要在头中设置Content-Type=application/json; * 若body是普通的java类的时候,无需指定这个,RestTemplate默认自动配上Content-Type=application/json */ HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); //③:请求实体(body,头、请求方式,uri) RequestEntity requestEntity = new RequestEntity(body, headers, HttpMethod.POST, URI.create(url)); //④:发送请求(请求实体,返回值需要转换的类型) ResponseEntity<List<BookDto>> responseEntity = restTemplate.exchange( requestEntity, new ParameterizedTypeReference<List<BookDto>>() { }); //⑤:获取结果 List<BookDto> 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<String, ?> uriVariables); public void delete(URI url);
5.2、PUT 请求
PUT 请求和 POST 请求类似,将类型改为 PUT 就可以了。
5.3、OPTIONS 请求
OPTIONS 请求用来探测接口支持哪些 http 方法
public Set<HttpMethod> optionsForAllow(String url, Object... uriVariables); public Set<HttpMethod> optionsForAllow(String url, Map<String, ?> uriVariables); public Set<HttpMethod> optionsForAllow(URI url);
6、集成 HttpClient
RestTemplate 内部默认用的是 jdk 自带的 HttpURLConnection 发送请求的,性能上面并不是太突出。 可以将其替换为 httpclient 或者 okhttp。 先来看下如何替换为 HttpClient。
引入 maven 配置
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.7</version> </dependency>
创建 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<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>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<Header> 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()); } @Test public 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 配置
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.3.1</version> </dependency>
创建 RestTemplate
new RestTemplate(new OkHttp3ClientHttpRequestFactory());