文章目录
- restTemplate为空的问题
- 方案一
- 方案二(这种方案编译时不报错,但是运行时会报错)
- exchange和postForEntity的区别
- exchange例子
- postForEntity的例子
- 报错: : Request processing failed; nested exception is
- rest逻辑处理
- httpStatus 200的判断
- 几个方法的区别
- 多个restTemplate
- 有时框架自带的restTemplate带有负载均衡,但是不知道在哪里配置的怎么办?
- 其他
- restTempalte请求报错 No instances available for
接口只能接收json请求。 如果其他格式会报错。
日志报错:Content type 'text/plain;charset=ISO-8859-1
restTemplate代码很简单,但是要注意下文中的2个要点:
String url="/api/getUser";
User user= new User();
user.setName("zhangsan");
String s = JSON.toJSONString(user);
// 要点1: 这三句设置header非常重要
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<String>(s, headers);
try {
// 要点2:这里要发送包含header的request,不要直接发对象的json报文
restTemplate.postForEntity(url, request, User.class);
}catch (Exception e){
logger.error("异常了",e);
}
restTemplate为空的问题
方案一
在启动类,或配置类里面添加如下代码:
@Autowired
private RestTemplateBuilder builder;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
问题解决。
方案二(这种方案编译时不报错,但是运行时会报错)
@Resource
private RestTemplate restTemplate;
这个方案实际不可行。只是作为反面教材来对照下。
exchange和postForEntity的区别
exchange是原始的方法,灵活度最高。
postForEntity比exchange少了一个参数,相当于把post封装了。
其实本质都一样。
exchange例子
postForEntity的例子
报错: : Request processing failed; nested exception is
如果报这个错,很可能是restTemplate不存在。 配置下build即可。
rest逻辑处理
除了状态码200等之外,还要考虑到超时等,例如主机不存在等。
@RequestMapping("/restUrl")
public String restUrl(@RequestParam(name="url") String url){
try {
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, "1234", String.class);
if(HttpStatus.OK==responseEntity.getStatusCode()){
logger.info("rest请求成功,返回报文:{}",responseEntity);
}else{
logger.info("rest请求失败,返回报文:{}",responseEntity);
}
}catch (Exception e){
logger.error("rest请求异常,error:",e);
;
return e.getMessage()+e.getSuppressed();
}
return "query success";
}
httpStatus 200的判断
一般来说有2种写法,都是可以的:
// 最优雅
if(HttpStatus.OK==responseEntity.getStatusCode()){
}
// 不够优雅
if(HttpStatus.OK.value()=responseEntity.getStatusCode().value()){
}
// 我就拿数字直接比较... 其实这样也可以
if(200==responseEntity.getStatusCode().value()){
}
另:getStatusCode().value()可以写为getStatusCodeValue(),是一样的。
几个方法的区别
发送请求有好几种方法,会用就好。getForObject()
返回值直接是响应体内容转为指定的对象getForEntity()
返回值的封装包含有响应头, 响应状态码的 ResponseEntity 对象exchange()
可以指定为get请求或者post请求,并且返回ResponseEntity 对象
多个restTemplate
注入带有负载均衡的restTemplate。
@Bean
@LoadBalanced
public RestTemplate ispRestTemplate() {
return new RestTemplate();
}
注入常规的restTemplate。
@Bean
public RestTemplate notBalanceRestTemplate() {
return new RestTemplate();
}
@Resource(name = "ispRestTemplate")
private RestTemplate ispRestTemplate;
@Resource(name = "notBalanceRestTemplate")
private RestTemplate notBalanceRestTemplate;
有时框架自带的restTemplate带有负载均衡,但是不知道在哪里配置的怎么办?
就是再配置一个restTemplate,但是注入的时候使用@Autowired但是不加@Qualifier,这样根据类型注入会报错,就可以找到默认的restTemplate在哪里配置的了。
报错:
Field restTemplate in required a single bean, but 2 were found:
- notBalanceRestTemplate: defined by method ‘notBalanceRestTemplate’ in class path resource [com/test/]
- ispRestTemplate: defined by method ‘ispRestTemplate’ in class path resource [com/test/]
其他
restTempalte请求报错 No instances available for
怪了,restTemplate请求就报错,但是httpUtils请求就没问题。
百度说是@LoadBalance的问题,但是在StartupApplication类配置了还是不行。
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
感觉不是这的问题,怪怪的。