Spring RestTemplate配置及讲解
2017-12-20 11:40
337 查看
HttpClient 与 RestTemplate 都是Java代码发送http请求的工具。
HttpClient
HttpClient 是apache的开源,需要引入两个包:httpclient-4.2.4.jar 和 httpcore-4.2.2.jarRestTemplate
RestTemplate 是Spring的封装,需要spring的包 spring-web-3.0.7.RELEASE.jar目前我们使用Spring boot框架作为开发主框架,以下对RestTemplate,以及我们代码中封装的发送http请求的方法做一些讲解。
同步RestTemplate配置
RestConfig.javapackage com.shanyuan.platform.ms.base.rest.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; /** * restTemplate配置 * @author yangjian 2017/09/28 * */ @Component @Configuration public class RestConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory){ return new RestTemplate(factory); } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory(){ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setReadTimeout(5000);//ms factory.setConnectTimeout(15000);//ms return factory; } }
异步RestTemplate配置
AsyncRestConfig.javapackage com.shanyuan.platform.ms.base.rest.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.AsyncClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.stereotype.Component; import org.springframework.web.client.AsyncRestTemplate; @Component @Configuration public class AsyncRestConfig { @Bean public AsyncRestTemplate asyncRestTemplate(){ return new AsyncRestTemplate(); } public AsyncClientHttpRequestFactory clientHttpRequestFactory(){ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setReadTimeout(5000); factory.setReadTimeout(5000); return factory; } }
我们项目中如果要使用Resttemplate注解的话需要对Bean进行配置。配置完成之后就可以直接注入 RestTemplate 和 AsyncRestTemplate 进行get或者post或者其他方式进行访问了,目前最常用的请求方式为get与post,所以代码中只对这两种请求进行了封装,并且针对同一类型请求,基于参数以及其他需求做了不同封装。
RestService.javapackage com.shanyuan.platform.ms.base.rest.service; import java.util.HashMap; import java.util.Map; import org.springframework.http.HttpHeaders; import org.springframework.util.LinkedMultiValueMap; import com.alibaba.fastjson.JSONObject; import com.shanyuan.platform.ms.base.common.ServiceResult; /** * restService接口 * @author yangjian 2017/09/28 * */ public interface RestService { /** * get请求 * @param map * @param url * @return */ public ServiceResult parseGetResult(Map<String, Object> map, String url); /** * get请求 * @param map * @param url * @return */ public ServiceResult parseGetResult(HashMap<String, Object> map, String url); /** * 无参或已拼接参数get请求 * @param url * @return */ public ServiceResult parseGetResult(String url); /** * post请求 * @param map * @param url * @return */ public ServiceResult parsePostResult(LinkedMultiValueMap<String, Object> map, String url); /** * 带有请求头的post请求 * @param httpHeader * @param params * @param url * @return */ public ServiceResult parsePostResultWithHeader(HttpHeaders httpHeader, JSONObject params, String url); }
AsyncService.java
package com.shanyuan.platform.ms.base.rest.service; import java.util.HashMap; import java.util.Map; import org.springframework.http.HttpHeaders; import org.springframework.util.LinkedMultiValueMap; import com.alibaba.fastjson.JSONObject; import com.shanyuan.platform.ms.base.common.ServiceResult; /** * 异步rest请求接口 * @author win10 * */ public interface AsyncRestService { /** * get请求 * @param map * @param url * @return */ public ServiceResult parseGetResult(Map<String, Object> map, String url); /** * get请求 * @param url * @return */ public ServiceResult parseGetResult(String url); /** * get请求 * @param map * @param url * @return */ public ServiceResult parseGetResult(HashMap<String, Object> map, String url); /** * post请求 * @param map * @param url * @return */ public ServiceResult parsePostResult(LinkedMultiValueMap<String, Object> map, String url); /** * 带header的http请求 * @param headers * @param params * @param url * @return */ public ServiceResult parsePostResultWithHeader(HttpHeaders headers, JSONObject params, String url); }
抽象接口,对不同请求方式及同一请求方式的不同实现进行封装
RestServiceImpl.java
package com.shanyuan.platform.ms.base.rest.service.impl; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.client.RestTemplate; import com.alibaba.fastjson.JSONObject; import com.shanyuan.platform.ms.base.common.BaseService; import com.shanyuan.platform.ms.base.common.ServiceResult; import com.shanyuan.platform.ms.base.exception.CoreServiceExcepType; import com.shanyuan.platform.ms.base.exception.CoreServiceException; import com.shanyuan.platform.ms.base.rest.service.RestService; @Service public class RestServiceImpl extends BaseService implements RestService{ protected Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private RestTemplate restTemplate; /** * 发送get请求 * @param map 参数map * @param url 请求地址,参数拼接在链接中,用通配符代表 * 示例 : * Map<String, Object> map = new HashMap<String, Object>; * map.put("channel", 1); * map.put("goodsId", 2); * String url = "http://localhost:8083/goods/goodsIndex?channel={channel}&goods_id={goodsId}"; * 根据实际情况自己添加参数 * @return */ @Override public ServiceResult parseGetResult(Map<String, Object> map, String url){ ServiceResult result = new ServiceResult(); try { String sResult = restTemplate.getForObject(url, String.class, map); JSONObject jResult = JSONObject.parseObject(sResult); result = buildSuccessResult(jResult); } catch (CoreServiceException e) { result = buildErrorResult("url:"+ url +"请求失败"); logger.info("url:{}, map:{},请求失败", url, map); e = new CoreServiceException(CoreServiceExcepType.REQUEST_CODE, "请求失败"); e.printStackTrace(); } return result; } /** * 发送get请求 * @param map 参数map * @param url 请求地址,地址中不需要拼接参数,在方法中处理 * 示例 : * HashMap<String, Object> map = new HashMap<String, Object>; * map.put("channel", 1); * map.put("goodsId", 2); * String url = "http://localhost:8083/goods/goodsIndex"; * 根据实际情况自己添加参数 * @return */ @Override public ServiceResult parseGetResult(HashMap<String, Object> map, String url) { StringBuilder sb = new StringBuilder(); sb.append(url); if(!CollectionUtils.isEmpty(map)){ Set keys = map.keySet(); sb.append("?"); for (String string : keys) { sb.append(string); sb.append("="); sb.append(map.get(string).toString()); sb.append("&"); } } String finalUrl = sb.toString(); if(finalUrl.endsWith("&")){ finalUrl = finalUrl.substring(0, finalUrl.length() - 1); } ServiceResult result = this.parseGetResult(finalUrl); return result; } /** * 发送get请求 * @param url 请求地址 * 请求为纯字符串,可以是无参数的get请求,也可以是将参数的K V都拼接好传入 * 示例 * 1、http://localhost:8083/goods/goodsIndex * 2、http://localhost:8083/goods/goodsIndex?channel=1&goods_id=2 * 以上两种方式都支持 * @return * */ @Override public ServiceResult parseGetResult(String url) { ServiceResult result = new ServiceResult(); try { String sResult = restTemplate.getForObject(url, String.class); JSONObject jResult = JSONObject.parseObject(sResult); result = buildSuccessResult(jResult); } catch (CoreServiceException e) { result = buildErrorResult("url:"+ url +"请求失败"); logger.info("url:{}, map:{},请求失败", url); e = new CoreServiceException(CoreServiceExcepType.REQUEST_CODE, "请求失败"); e.printStackTrace(); } return result; } /** * 发送post请求 * @param map 请求参数集合 * @param 请求地址 * 示例: * MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); * map.add("channel", 1); * map.add("goods_id", 2); * String url = "http://localhost:8083/goods/goodsIndex"; * 根据实际情况自己添加参数 * @return */ @Override public ServiceResult parsePostResult(LinkedMultiValueMap<String, Object> map, String url) { ServiceResult result = new ServiceResult(); try{ String sResult = restTemplate.postForObject(url, map, String.class); JSONObject jResult = JSONObject.parseObject(sResult); result = buildSuccessResult(jResult); }catch (CoreServiceException e) { result = buildErrorResult("url:"+ url +"请求失败"); logger.info("url:{}, map:{},请求失败", url, map); e = new CoreServiceException(CoreServiceExcepType.REQUEST_CODE, "请求失败"); e.printStackTrace(); } return result; } /** * 带header的http post请求 * header中的值可以自己设置 */ @Override public ServiceResult parsePostResultWithHeader(HttpHeaders httpHeader, JSONObject params, String url) { ServiceResult result = new ServiceResult(); try{ HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<Map<String,Object>>(params, httpHeader); ResponseEntity exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class); JSONObject jResult = JSONObject.parseObject(exchange.getBody()); result = buildSuccessResult(jResult); }catch (Exception e) { logger.info("url:{}, map:{},请求失败", url, params); result = buildErrorResult("url:" + url + "请求失败"); } return result; } }
AsyncServiceImpl.java
package com.shanyuan.platform.ms.base.rest.service.impl; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.StringUtils; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureCallback; import org.springframework.web.client.AsyncRestTemplate; import com.alibaba.fastjson.JSONObject; import com.shanyuan.platform.ms.base.common.BaseService; import com.shanyuan.platform.ms.base.common.ServiceResult; import com.shanyuan.platform.ms.base.exception.CoreServiceExcepType; import com.shanyuan.platform.ms.base.exception.CoreServiceException; import com.shanyuan.platform.ms.base.rest.service.AsyncRestService; /** * * @author yangjian 2017/09/28 * */ @Service public class AsyncRestServiceImpl extends BaseService implements AsyncRestService { protected Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private AsyncRestTemplate restTemplate; /** * 发送get请求 * @param map 参数map * @param url 请求地址,参数拼接在链接中,用通配符代表 * 示例 : * Map<String, Object> map = new HashMap<String, Object>; * map.put("channel", 1); * map.put("goodsId", 2); * String url = "http://localhost:8083/goods/goodsIndex?channel={channel}&goods_id={goodsId}"; * 根据实际情况自己添加参数 * @return */ @Override public ServiceResult parseGetResult(Map<String, Object> map, String url) { ServiceResult result = new ServiceResult(); ListenableFuture<ResponseEntity> forEntity = restTemplate.getForEntity(url, String.class, map); forEntity.addCallback(new ListenableFutureCallback<ResponseEntity>() { public void onSuccess(ResponseEntity resp) { String sResult = resp.getBody(); if(!StringUtils.isEmpty(sResult)){ JSONObject jResult = JSONObject.parseObject(sResult); result.setContent(jResult); result.setCode(CODE_SUCCESS); result.setMessage("success"); logger.info("url:{}, map:{} 请求成功", url, map); }else{ this.onFailure(new Throwable(new CoreServiceException(CoreServiceExcepType.REQUEST_CODE, "请求结果为空"))); } } public void onFailure(Throwable t) { result.setMessage(t.getMessage()); result.setCode(CODE_ERROR); t.printStackTrace(); logger.info("url:{}, map:{} 请求失败", url, map); } }); return result; } /** * 发送get请求 * @param url 请求地址 * 请求为纯字符串,可以是无参数的get请求,也可以是将参数的K V都拼接好传入 * 示例 * 1、http://localhost:8083/goods/goodsIndex * 2、http://localhost:8083/goods/goodsIndex?channel=1&goods_id=2 * 以上两种方式都支持 * @return * */ @Override public ServiceResult parseGetResult(String url) { ServiceResult result = new ServiceResult(); ListenableFuture<ResponseEntity> forEntity = restTemplate.getForEntity(url, String.class); forEntity.addCallback(new ListenableFutureCallback<ResponseEntity>() { public void onSuccess(ResponseEntity resp) { String sResult = resp.getBody(); if(!StringUtils.isEmpty(sResult)){ JSONObject jResult = JSONObject.parseObject(sResult); result.setContent(jResult); result.setCode(CODE_SUCCESS); result.setMessage("success"); logger.info("url:{} 请求成功", url); }else{ this.onFailure(new Throwable(new CoreServiceException(CoreServiceExcepType.REQUEST_CODE, "请求结果为空"))); } } public void onFailure(Throwable t) { result.setMessage(t.getMessage()); result.setCode(CODE_ERROR); t.printStackTrace(); logger.info("url:{} 请求失败", url); } }); return result; } /** * 发送get请求 * @param map 参数map * @param url 请求地址,地址中不需要拼接参数,在方法中处理 * 示例 : * HashMap<String, Object> map = new HashMap<String, Object>; * map.put("channel", 1); * map.put("goodsId", 2); * String url = "http://localhost:8083/goods/goodsIndex"; * 根据实际情况自己添加参数 * @return */ @Override public ServiceResult parseGetResult(HashMap<String, Object> map, String url) { StringBuilder sb = new StringBuilder(); sb.append(url); if(!CollectionUtils.isEmpty(map)){ Set keys = map.keySet(); sb.append("?"); for (String string : keys) { sb.append(string); sb.append("="); sb.append(map.get(string).toString()); sb.append("&"); } } String finalUrl = sb.toString(); if(finalUrl.endsWith("&")){ finalUrl = finalUrl.substring(0, finalUrl.length() - 1); } ServiceResult result = this.parseGetResult(finalUrl); return result; } /** * 发送post请求 * @param map 请求参数集合 * @param 请求地址 * 示例: * MultiValueMap<String, Object> map = new LinkedMultiValueMap<>(); * map.add("channel", 1); * map.add("goods_id", 2); * String url = "http://localhost:8083/goods/goodsIndex"; * 根据实际情况自己添加参数 * @return */ @Override public ServiceResult parsePostResult(LinkedMultiValueMap<String, Object> map, String url) { ServiceResult result = new ServiceResult(); String header = ""; HttpEntity httpEntity = new HttpEntity(header); ListenableFuture<ResponseEntity> forEntity = restTemplate.postForEntity(url, httpEntity, String.class, map); forEntity.addCallback(new ListenableFutureCallback<ResponseEntity>() { public void onSuccess(ResponseEntity resp) { String sResult = resp.getBody(); if(!StringUtils.isEmpty(sResult)){ JSONObject jResult = JSONObject.parseObject(sResult); result.setContent(jResult); result.setCode(CODE_SUCCESS); result.setMessage("success"); logger.info("url:{}, map:{} 请求成功", url, map); }else{ this.onFailure(new Throwable(new CoreServiceException(CoreServiceExcepType.REQUEST_CODE, "请求结果为空"))); } } public void onFailure(Throwable t) { result.setMessage(t.getMessage()); result.setCode(CODE_ERROR); t.printStackTrace(); logger.info("url:{}, map:{} 请求失败", url, map); } }); return result; } @Override public ServiceResult parsePostResultWithHeader(HttpHeaders headers, JSONObject params, String url) { ServiceResult result = new ServiceResult(); HttpEntity httpEntity = new HttpEntity(headers); ListenableFuture<ResponseEntity> forEntity = restTemplate.postForEntity(url, httpEntity, String.class, params); forEntity.addCallback(new ListenableFutureCallback<ResponseEntity>() { public void onSuccess(ResponseEntity resp) { String sResult = resp.getBody(); if(!StringUtils.isEmpty(sResult)){ JSONObject jResult = JSONObject.parseObject(sResult); result.setContent(jResult); result.setCode(CODE_SUCCESS); result.setMessage("success"); logger.info("url:{}, map:{} 请求成功", url, params); }else{ this.onFailure(new Throwable(new CoreServiceException(CoreServiceExcepType.REQUEST_CODE, "请求结果为空"))); } } public void onFailure(Throwable t) { result.setMessage(t.getMessage()); result.setCode(CODE_ERROR); t.printStackTrace(); logger.info("url:{}, map:{} 请求失败", url, params); } }); return result; } }
以上是对上边接口的实现,具体参数说明都已经写到注释里边,有不清楚的问题可以一起讨论。
补充:目前已经我们项目中已经不使用这种方式去调用接口了,直接用SpringBoot中Feign组件了。
相关文章推荐
- spring restTemplate配置
- springboot restTemplate使用以及相关配置
- SpringBoot配置RestTemplate的代理和超时时间
- Spring RestTemplate Interceptor 配置
- Springmvc RestTemplate 使用 && json xml rest 配置
- Spring RestTemplate 利用拦截器配置 HTTP请求 Header
- springboot中配置restTemplate及简单使用
- spring的RestTemplate的配置及使用
- Spring RestTemplate配置类
- Spring restTemplate 超时配置
- Spring RestTemplate 配置 SSL https (使用 Spring @MVC)
- SpringMVC RestTemplate的几种请求调用
- 通过 Spring RestTemplate 调用带请求体的 Delete 方法(Delete With Request Body)
- springboot中用RestTemplate调用百度ip定位服务
- spring boot restTemplate protobuf(protocal buffer) demo
- spring 学习--beans.xml配置文件的讲解
- 在spring boot中使用restTemplate上传大文件Java heap space
- Spring boot下配置使用redis--template编码形式
- 学习了一下XML,并结合相应的知识讲解了一下spring的dubbo配置
- spring android resttemplate null pointer异常的解决