本文共 10435 字,大约阅读时间需要 34 分钟。
Http请求在服务端开发中是必不可少的,本文将使用Spring Boot中的RestTemplate作为门面,HttpClient作为实现,演示基础的Http请求例子。
RestTemplate在Spring-Web模块中内置,Spring Boot会自动引入。以下是需要添加的依赖:
org.apache.httpcomponents httpclient 4.5.5 io.netty netty-all 4.1.5.Final org.springframework.boot spring-boot-configuration-processor true
# yml配置的优先级高于java配置;如果yml配置和java配置同时存在,则yml配置会覆盖java配置spring: restTemplate: maxTotalConnect: 1000 #连接池的最大连接数,0代表不限;如果取0,需要考虑连接泄露导致系统崩溃的后果 maxConnectPerRoute: 200 connectTimeout: 3000 readTimeout: 5000 charset: UTF-8
@Configuration@ConfigurationProperties(prefix = "spring.restTemplate")@ConditionalOnClass(value = {RestTemplate.class, CloseableHttpClient.class})public class RestTemplateConfig { // java配置的优先级低于yml配置;如果yml配置不存在,会采用java配置 private int maxTotalConnection = 500; private int maxConnectionPerRoute = 100; private int connectionTimeout = 2000; private int readTimeout = 30000; private String charset = "UTF-8"; public void setMaxTotalConnection(int maxTotalConnection) { this.maxTotalConnection = maxTotalConnection; } public void setMaxConnectionPerRoute(int maxConnectionPerRoute) { this.maxConnectionPerRoute = maxConnectionPerRoute; } public void setConnectionTimeout(int connectionTimeout) { this.connectionTimeout = connectionTimeout; } public void setReadTimeout(int readTimeout) { this.readTimeout = readTimeout; } public void setCharset(String charset) { this.charset = charset; } @Bean(name = "clientHttpRequestFactory") public ClientHttpRequestFactory clientHttpRequestFactory() { return createClientHttpRequestFactory(this.connectionTimeout, this.readTimeout); } @Bean(name = "restTemplate") @ConditionalOnMissingBean(RestTemplate.class) public RestTemplate restTemplate(ClientHttpRequestFactory factory) { return createRestTemplate(factory); } @Bean(name = "asyncRestTemplate") @ConditionalOnMissingBean(AsyncRestTemplate.class) public AsyncRestTemplate asyncRestTemplate(RestTemplate restTemplate) { final Netty4ClientHttpRequestFactory factory = new Netty4ClientHttpRequestFactory(); factory.setConnectTimeout(this.connectionTimeout); factory.setReadTimeout(this.readTimeout); return new AsyncRestTemplate(factory, restTemplate); } private ClientHttpRequestFactory createClientHttpRequestFactory(int connectionTimeout, int readTimeout) { if (this.maxTotalConnection <= 0) { throw new IllegalArgumentException("invalid maxTotalConnection: " + maxTotalConnection); } if (this.maxConnectionPerRoute <= 0) { throw new IllegalArgumentException("invalid maxConnectionPerRoute: " + maxTotalConnection); } List headers = new LinkedList<>(); headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate")); headers.add(new BasicHeader("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6")); HttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(0, false); CloseableHttpClient httpClient = HttpClients.custom() .setDefaultHeaders(headers) .setRetryHandler(retryHandler) .build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); factory.setConnectTimeout(connectionTimeout); factory.setReadTimeout(readTimeout); return factory; } private RestTemplate createRestTemplate(ClientHttpRequestFactory factory) { RestTemplate restTemplate = new RestTemplate(factory); modifyDefaultCharset(restTemplate); restTemplate.setErrorHandler(new DefaultResponseErrorHandler()); return restTemplate; } private void modifyDefaultCharset(RestTemplate restTemplate) { List converterList = restTemplate.getMessageConverters(); HttpMessageConverter converterTarget = null; for (HttpMessageConverter item : converterList) { if (StringHttpMessageConverter.class == item.getClass()) { converterTarget = item; break; } } if (null != converterTarget) { converterList.remove(converterTarget); } Charset defaultCharset = Charset.forName(charset); converterList.add(1, new StringHttpMessageConverter(defaultCharset)); }} @RestControllerpublic class GetTestController { @Resource private RestTemplate restTemplate; @GetMapping("/baidu1/{key}") public String get1(@PathVariable String key) throws UnsupportedEncodingException { String encodeKey = URLEncoder.encode(key, "UTF-8"); String url = "http://www.baidu.com/s?bdorz_come=1&ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=" + encodeKey; return restTemplate.getForObject(url, String.class); } @GetMapping("/baidu2/{key}") public String get2(@PathVariable String key) throws UnsupportedEncodingException { HttpHeaders headers = new HttpHeaders(); headers.set("MyHeaderKey", "MyHeaderValue"); HttpEntity entity = new HttpEntity(headers); String encodeKey = URLEncoder.encode(key, "UTF-8"); String url = "http://www.baidu.com/s?bdorz_come=1&ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=" + encodeKey; ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); return response.getBody(); }} @RestControllerpublic class PostTestController { @Resource private RestTemplate restTemplate; @GetMapping("/postForm") public String testPostForm() { String url = ""; MultiValueMap form = new LinkedMultiValueMap<>(); form.add("name", "**"); form.add("age", "**"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); HttpEntity entity = new HttpEntity(form, headers); String json = restTemplate.postForObject(url, entity, String.class); return json; } @RequestMapping("/postBody") public String testPostBody() { String url = ""; String jsonBody = "{\n" + " \"name\": \"XX\",\n" + " \"age\": \"12\",\n" + " \"sex\": \"man\"\n" + "}\n"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity entity = new HttpEntity(jsonBody, headers); String json = restTemplate.postForObject(url, entity, String.class); return json; // 如果需要将json转换为Java对象,可以使用restTemplate.postForObject(url, entity, ResultVo.class) }} @RestControllerpublic class FileTestController { @Resource private RestTemplate restTemplate; @RequestMapping("/postFile") public String testPostFileBody() { String filePath = "D:/config.png"; String url = ""; String appId = ""; String secureKey = ""; String time = String.valueOf(System.currentTimeMillis()); String pubStr = "1"; String tempStr = String.format("app_id=%s&is_public=%s&time=%s&vframe=0%s", appId, pubStr, time, secureKey); MultiValueMap form = new LinkedMultiValueMap<>(); form.add("is_public", pubStr); form.add("vframe", "0"); form.add("file", new FileSystemResource(new File(filePath))); form.add("app_id", appId); form.add("time", time); form.add("sign", DigestUtils.md5(tempStr)); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity entity = new HttpEntity(form, headers); String json = restTemplate.postForObject(url, entity, String.class); return json; } @RequestMapping("/downloadFile") public ResponseEntity testDownloadFile() throws Exception { String url = "http://editor.baidu.com/editor/download/BaiduEditor(Online)_5-9-16.exe"; HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_OCTET_STREAM)); HttpEntity entity = new HttpEntity(headers); ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, byte[].class); byte[] bytes = response.getBody(); long contentLength = bytes != null ? bytes.length : 0; headers.setContentLength((int) contentLength); headers.setContentDispositionFormData("baidu.exe", URLEncoder.encode("百度安装包.exe", "UTF-8")); return new ResponseEntity<>(response.getBody(), headers, HttpStatus.OK); }} 只配@ConfigurationProperties时,不会自动创建bean
正确姿势:
@Configuration@ConfigurationProperties(prefix = "spring.restTemplate")@ConditionalOnClass(value = {RestTemplate.class, CloseableHttpClient.class})public class RestTemplateConfig {} 错误姿势:
@ConfigurationProperties(prefix = "spring.restTemplate")@ConditionalOnClass(value = {RestTemplate.class, CloseableHttpClient.class})public class RestTemplateConfig {} @ConfigurationProperties无法注入没有setter的属性
RestTemplate默认配置会乱码
正确姿势:
private void modifyDefaultCharset(RestTemplate restTemplate) { List converterList = restTemplate.getMessageConverters(); HttpMessageConverter converterTarget = null; for (HttpMessageConverter item : converterList) { if (StringHttpMessageConverter.class == item.getClass()) { converterTarget = item; break; } } if (null != converterTarget) { converterList.remove(converterTarget); } Charset defaultCharset = Charset.forName(charset); converterList.add(1, new StringHttpMessageConverter(defaultCharset));} 错误姿势:
@Beanpublic RestTemplate getRestTemplate() { RestTemplate rest = new RestTemplate(this.createFactory); return rest;} [图片描述]
有任何建议,欢迎留言探讨。
转载地址:http://jctfk.baihongyu.com/