异常
使用new RestTemplate()报错,错误如下
java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/util/DefaultIndenter
原因
RestTemplate默认使用jackson序列化,spring 4+需要配备jackson 2+的版本,由于jackson版本过低导致找不到类
解决
一:升级jackson
升级jackson版本,这也是网上绝大多数的解决方式,把jackson升级到最新版本
二:使用gson
由于很多公共包依赖jackson,贸然升级怕引发风险,所以改成使用gson这种序列化方式
- 添加gson依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.1</version>
</dependency>
- 配置restTemplate
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.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
import java.util.List;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
List<HttpMessageConverter<?>> messageConverters = Collections.singletonList(new GsonHttpMessageConverter());
RestTemplate restTemplate = new RestTemplate(messageConverters);
restTemplate.setRequestFactory(factory);
return restTemplate;
}
@Bean
public ClientHttpRequestFactory requestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(15000);
factory.setReadTimeout(15000);
return factory;
}
}
- 请求
@Service
public class EmployeesServiceImpl {
@Autowired
private RestTemplate restTemplate;
public Employee employees(String id){
String url = "http://xxxxx";
ResponseEntity<Employee> responseEntity = restTemplate.exchange(url, HttpMethod.GET,entity,Employee.class, Collections.emptyMap());
return responseEntity.getBody();
}
}
三:自定义序列化
参照GsonHttpMessageConverter源代码,只要继承AbstractGenericHttpMessageConverter,并实现相应的方法就可以。例如:变成fastjson实现序列化
public class FastjonsHttpMessageCoverter extends AbstractGenericHttpMessageConverter {
@Override
protected void writeInternal(Object o, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
}
@Override
protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
@Override
public Object read(Type type, Class contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
}