超级简单易用的 Spring RestTemplate, 还可以多线程共享一个实例, 有一个小缺憾, 就是需要记得设置默认超时时间, 否则默认不超时. 而设置超时时间以后, 又会引入新的 Connection Pool 大小的问题
不设置经常出
现
ResourceAccessException与Socket异常
设置超时
方式1
@Configuration
public class AppConfig{
@Bean
public RestTemplate customRestTemplate()
{
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(...);
httpRequestFactory.setConnectTimeout(...);
httpRequestFactory.setReadTimeout(...);
return new RestTemplate(httpRequestFactory);
}
}
方式2
@Configuration
public class AppConfig{
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder)
{
return restTemplateBuilder
.setConnectTimeout(...)
.setReadTimeout(...)
.build();
}
}
这个链接讲了两种方式:spring-resttemplate-timeout,
@Autowired
private RestTemplate restTemplate;
/**json字符串post请求*/
String requestJson = JSONObject.toJSONString(requestParam);//对象转json字符串【json字符串,map转json也OK】
logger.info("小金体育发送请求参数:{} ", requestJson);
try {
String returnValue = gamePlatformRestTemplate.postForObject(Constant.XJTY_URL, requestJson, String.class);
logger.info("小金体育接收返回内容:{} ",returnValue);
}catch (Exception e){
logger.error("小金体育发送请求异常:{}", e);
throw new ServiceException(ReturnCode.CODE_30001, "网络请求异常" );
}
/**map格式post请求*/
Map<String, String> param = new LinkedHashMap<>();
param.put("Currency", "CNY");
param.put("Password", userPasswordEnocder.getRawPassword(user.getGamePassword()));
logger.info("IMOne创建用户发送请求参数:{} ,请求地址:{}", JSON.toJSONString(param),url);
//参数必须json格式,json格式就必须要用map,否则收到乱码,第三方接口问题?【有时候写这个也不管用,接收到的中文还是乱码,就需要用到👇下面另外一种方法了:】
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);//application/json;charset=UTF-8 MediaType 为导入org.springframework.http包
HttpEntity<Map<String,String>> requestEntity = new HttpEntity<>(param, requestHeaders); //HttpEntity-这样写参数就json格式了
String result = "";
try{
result = restTemplate.postForObject(url, requestEntity, String.class);
}catch (Exception e){
logger.error("IMOne创建用户请求异常:{}", e);
throw new ServiceException(ReturnCode.CODE_30001, "网络请求异常" );
}
logger.info("IMOne返回内容:{}",result);
//RequestEntity [MgService]
RequestEntity<Map<String, String>> req = new RequestEntity<>(map, headers, HttpMethod.POST, new URI(url));
logger.info("mg createUser req: {}", req);
MgBaseResponse result = restTemplate.postForObject(url, req, MgBaseResponse.class); //对象接收,也可字符串接收:String.class
还有个这样的头:
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/json");
RequestEntity<Map<String, Object>> req = new RequestEntity<>(map, headers, HttpMethod.POST, new URI(url));
或者头↓:
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity<Map<String,Object>> httpEntity = new HttpEntity<>(map,httpHeaders);
result = restTemplate.postForObject(urlBuffer.toString(), httpEntity, String.class);
接👆上面收到乱码问题不管用后解决方案二:
restTemplate = getInstance("utf-8");
String result = restTemplate.postForObject(urlBuffer.toString(), paramJson, String.class);
public static RestTemplate getInstance(String charset) {
RestTemplate restTemplate = new RestTemplate();
List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
for (HttpMessageConverter<?> httpMessageConverter : list) {
if(httpMessageConverter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName(charset));
break;
}
}
return restTemplate;
}
参考:https://blog.csdn.net/mryang125/article/details/80963280
【发现HttpMethod.POST/GET/PUT/DELETE……】
RestTemplate.exchange
/**map格式post请求*/
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);//该行未试过,自己改写的[SunbetService Line446]
HttpEntity<Map<String,String>> requestEntity = new HttpEntity<>(param, requestHeaders);
try{
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); //字符串格式接收;ResponseEntity:包org.springframework.http
responseText = responseEntity.getBody();
} catch (Exception e) {
logger.error("调用sunbet接口异常", e);
throw new ServiceException(ReturnCode.CODE_39001); //"Sunbet平台异常,请稍后再试。"
}
if (StringUtils.isEmpty(responseText)) {
throw new ServiceException(ReturnCode.CODE_39001);
}
/**map格式PUT请求*/
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
Map<String, String> body = new HashMap<>();
body.put("password", "abc");
body.put("ext_ref", user.getUsername());
try {
RequestEntity<Map<String, String>> req = new RequestEntity<>(body, headers, HttpMethod.PUT, new URI(url));
ResponseEntity<MgBaseResponse> response = restTemplate.exchange(req, MgBaseResponse.class);
logger.info("response: {}", JSON.toJSONString(response));
} catch (HttpClientErrorException e) {
String erroStr = e.getResponseBodyAsString();
logger.info("MG 密码修改异常异常:{}", erroStr);
throw new ServiceException(ReturnCode.CODE_31006, "Mg");
} catch (Exception e) {
throw new ServiceException(ReturnCode.CODE_31006, "Mg");
}
/**Get 请求restTemplate.exchange */
StringBuilder sb = new StringBuilder(Constant.SUNBET_API_URL).append("?startdate=").append(startDate).append("&enddate=").append(endDate);
String url = sb.toString().replace(" ", "%20");
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Content-Type", MediaType.TEXT_HTML_VALUE);//text/html 该行未试过,自己改写的
//headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(null, httpHeaders);
String responseText = null;
try {
ResponseEntity<String> responseEntity = gamePlatformRestTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
responseText = responseEntity.getBody();
logger.debug("获取注单,请求返回的内容: {}", responseText);
} catch (Exception e) {
logger.error("Sunbet获取注单数据,出现异常", e);
throw new ServiceException(ReturnCode.CODE_37007, "Sunbet");
}
if (StringUtils.isEmpty(responseText)) {
logger.error("Sunbet获取注单数据为空");
return;
}
Get 请求
restTemplate.getForObject
//组装接口请求参数
StringBuffer sb = new StringBuffer();
sb.append("s=0");//操作子类型
sb.append("&account=" + account);//会员帐号
sb.append("&money=" + money);//金额(上分的金额, 如果不 携带分数传 0)
sb.append("&orderid=" + orderid);//流水号(格式:代理编 号 +yyyyMMddHHmmssSSS + account)
sb.append("&ip=" + ip);//客户端请求IP(玩家IP)
sb.append("&lineCode=" + Constant.LEG_LINECODE);//代理下面的站点标识, 用防止站点之间导分
sb.append("&KindID=" + kindId);//游戏ID
logger.info("LEG loginGame param:{}", sb.toString());
//发起第三方请求
LegResponseVo legResponseVo = null;
try {
String url = createRequestUrl(sb.toString());
logger.info("LEG loginGame url:{}", url);
String result = restTemplate.getForObject(url, String.class);
logger.info("LEG loginGame body:{}", result);
legResponseVo = JSON.parseObject(result, LegResponseVo.class);//json字符串转对象
} catch (Exception e) {
logger.error("LEG loginGame error:{}", e);
throw new ServiceException(ReturnCode.CODE_30001, "LEG登录游戏");
}
return legResponseVo;