有時(shí)候在文件管理模塊中有用到自定義content-type,以及自動(dòng)匹配HttpMessageConverter,但是在解決這些問(wèn)題的時(shí)候有朋友經(jīng)常遇到問(wèn)題。
這兩天研究了一下這個(gè)問(wèn)題的解決問(wèn)題 springmvc通過(guò)自定義http accept或者content-type自動(dòng)選擇HttpMessageConverter
RestTmplate設(shè)置headers:
restTemplate設(shè)置headers有三種方式
1、通過(guò)設(shè)置MessageConverters
2、通過(guò)設(shè)置攔截器(ClientHttpRequestInterceptor)
3、通過(guò)配置HttpHeaders
一般的restTemplate請(qǐng)求都可以設(shè)置HttpHeaders,因此HttpHeaders是比較容易想到的。
但使用http get方式的時(shí)候restTemplate沒(méi)有設(shè)置HttpHeaders的地方
文件管理器模塊有個(gè)功能是直接獲取文件的字節(jié)數(shù)組返回給客戶端,以提高javascript客戶端的解析速度
返回byte[] 需要有相應(yīng)解析器:ByteArrayHttpMessageConverter。它對(duì)應(yīng)的Content-Type是application/octet-stream
而我們用的是自定義的:application/bytes ,
在服務(wù)端配置文件加入下面配置
Java代碼
<bean id="byteConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/bytes</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter ">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
//信息轉(zhuǎn)換器放入適配器中
<ref bean="byteConverter" />
</list>
</property>
</bean>
然后在方法上設(shè)置headers
@RequestMapping(value = "/public/{appId}/{fileName}", method = RequestMethod.GET, headers = { "content-type=application/bytes" })
服務(wù)端的配置完成
客戶端restTemplate不能使用HttpHeaders,只能用后兩種
RestTemplate初始化的時(shí)候會(huì)加入5個(gè)信息轉(zhuǎn)換器,其中就有ByteArrayHttpMessageConverter,
這樣到服務(wù)端加上自己設(shè)置的就有6種類型,在自動(dòng)匹配HttpMessageConverter會(huì)匹配到不是自己想要的轉(zhuǎn)換器,比如這6個(gè)在getBytes這個(gè)功能的測(cè)試中,會(huì)匹配成json的轉(zhuǎn)換器。
為避免這樣就在RestTemplate請(qǐng)求前,用自定義Content-Type的ByteArrayHttpMessageConverter覆蓋默認(rèn)的配置
通過(guò)設(shè)置HttpMessageConverters
Java代碼
ByteArrayHttpMessageConverter converter = new ByteArrayHttpMessageConverter();
converter.setSupportedMediaTypes(Collections.singletonList(MediaType.valueOf("application/bytes")));
restTemplate.setMessageConverters((List)Collections.singletonList(converter));
通過(guò)設(shè)置ClientHttpRequestInterceptor
Java代碼
ClientHttpRequestInterceptor interceptor= new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
HttpRequestWrapper wrapper = new HttpRequestWrapper(request);
MediaType mt=MediaType.valueOf("application/bytes");
wrapper.getHeaders().setContentType(mt);
wrapper.getHeaders().setAccept((List)Collections.singletonList(mt));
return execution.execute(wrapper, body);
}
};
restTemplate.setInterceptors(Collections.singletonList(interceptor));