Spring Boot 中 RestTemplate 返回 LinkedHashMap 转实体的方法

在最近项目中,使用Springboot给外部提供接口,同时提供调用接口的SDK。
为了方便,直接使用SpringBoot中的RestTemplate来调用接口。
对接的时候翻车了,rest默认返回的是LinkedHashMap,我直接返回实体给他们,结果可想而知。
0、配置消息转换

RestTemplate中属性

private final List> messageConverters = new ArrayList<>();

包含了默认的消息转换,我们可以添加json、stream、html等消息转换。

@Configuration
public class RestTemplateConfig {
	@Resource
	private RightsProperties rightsProperties;

	@Bean
	public RestTemplate restTemplate(@Qualifier("simpleClientHttpRequestFactory") ClientHttpRequestFactory factory){
		RestTemplate restTemplate = new RestTemplate(factory);
		MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
		mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(
				MediaType.APPLICATION_JSON,
				MediaType.APPLICATION_OCTET_STREAM,
				MediaType.TEXT_HTML));
		restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);
		return restTemplate;
	}

	@Bean
	public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
		SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
		//单位为ms
		factory.setReadTimeout(rightsProperties.getReadTimeout());
		//单位为ms
		factory.setConnectTimeout(rightsProperties.getConnectTimeout());
		return factory;
	}

}
1、调用接口需要设置请求头
public static HttpEntity> generatePostJson(Map jsonMap, String token) {
		//如果需要其它的请求头信息、都可以在这里追加
		HttpHeaders httpHeaders = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("application/json;charset=UTF-8");
		httpHeaders.setContentType(type);
		httpHeaders.set("terminal_client", RequestConstant.TERMINAL_CLIENT);
		httpHeaders.set("token", token);
		return new HttpEntity<>(jsonMap, httpHeaders);
	}
2、GET方法调用
/**
 * get 请求并返回实体
 * @param uri uri
 * @param map 参数
 * @param token token
 * @param typeRef 返回实体类型
 * @param  实体
 * @return T 实体信息
 */
public  Result sendGetEntity(String uri, Map map, String token,
							  ParameterizedTypeReference> typeRef) {
	ResponseEntity> responseEntity = restTemplate.exchange(
		rightsProperties.getPreUri() + uri,
			HttpMethod.GET,
			generatePostJson(null, token),
			typeRef,
			// 参数组装成map
			map);
	return responseEntity.getBody();
}
3、POST方法调用
post方法要将参数设置在请求的body中
/**
 * POST方法调用
 * @param uri uri
 * @param map 参数
 * @param token token
 * @param typeRef 返回类型
 * @param  实体
 * @return 返回实体
 */
public   Result sendPostEntity(String uri, Map map, String token,
							   ParameterizedTypeReference> typeRef) {
	ResponseEntity> responseEntity = restTemplate.exchange(
			rightsProperties.getPreUri() + uri,
			HttpMethod.POST,
			// 参数需要设置在body中
			generatePostJson(map, token),
			typeRef);
	return responseEntity.getBody();
}
4、实战
// GET调用
@Override
public Result> getCanUseList(Integer type, String token) {
	Map map = Collections.singletonMap("type", type);
	ParameterizedTypeReference>> typeRef =
			new ParameterizedTypeReference>>() {};
	return restSendService.sendGetEntity(RequestConstant.GET_CAN_USE_LIST_URI, map, token, typeRef);
}
// POST调用
@Override
public Result issuedToCustomer(IssuedDTO param, String token) {
	Map map = JsonUtils.objectToMap(param);
	ParameterizedTypeReference> typeRef =
			new ParameterizedTypeReference>() {};
	return restSendService.sendPostEntity(RequestConstant.ISSUED_TO_CUSTOMER_URI, map, token, typeRef);
}
5、原理
跟踪源码看到无论调用get 还是 post 最终都会执行doExecute方法,而根据typeRef会用构造一个ResponseExtractor
public ResponseEntityResponseExtractor(@Nullable Type responseType) {
			if (responseType != null && Void.class != responseType) {
				this.delegate = new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
			}
			else {
				this.delegate = null;
			}
		}
		
@Nullable
	protected  T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback,
			@Nullable ResponseExtractor responseExtractor) throws RestClientException {

		Assert.notNull(url, "URI is required");
		Assert.notNull(method, "HttpMethod is required");
		ClientHttpResponse response = null;
		try {
			ClientHttpRequest request = createRequest(url, method);
			if (requestCallback != null) {
				requestCallback.doWithRequest(request);
			}
			response = request.execute();
			handleResponse(url, method, response);
			// 
			return (responseExtractor != null ? responseExtractor.extractData(response) : null);
		}
		catch (IOException ex) {
			String resource = url.toString();
			String query = url.getRawQuery();
			resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
			throw new ResourceAccessException("I/O error on " + method.name() +
					" request for \"" + resource + "\": " + ex.getMessage(), ex);
		}
		finally {
			if (response != null) {
				response.close();
			}
		}
	}

你可能感兴趣的:(JAVA猿-常用代码,spring,boot,resttemplate)