轉自:http://mayday85.iteye.com/blog/1622445
首先感謝這位作者的博客,使得我解決問題,只是感覺這個博客有點散,所以特此筆記總結一下:
在使用一個框架時,程序員分為三種級別:
1.看demo開發
2.看文檔開發
3.看源碼開發
注意:考慮時間上的問題,有好的demo不看文檔,有好的文檔不看源碼。
關於spring mvc文件下載,博客中提到了兩種解決方案:
方案1:
@RequestMapping("download") public void download(HttpServletResponse res) throws IOException { OutputStream os = res.getOutputStream(); try { res.reset(); res.setHeader("Content-Disposition", "attachment; filename=dict.txt"); res.setContentType("application/octet-stream; charset=utf-8"); os.write(FileUtils.readFileToByteArray(getDictionaryFile())); os.flush(); } finally { if (os != null) { os.close(); } } }
因為既然使用了mvc,怎么還能暴露HttpServletResponse這樣的j2ee接口出來,為作者不推薦。
方案2:
相信spring提供了更好的方式,於是通過翻閱文檔,作者得出如下代碼:
@RequestMapping("download") public ResponseEntity<byte[]> download() throws IOException { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); headers.setContentDispositionFormData("attachment", "dict.txt"); return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(getDictionaryFile()), headers, HttpStatus.CREATED); }
文件內容為:
aa 1 vv 2 hh 3
但是結果錯誤的輸出為:
"YWEJMQ0KdnYJMg0KaGgJMw=="
解決:
1.查看ByteArrayHttpMessageConverter的源碼:
public ByteArrayHttpMessageConverter() { super(new MediaType("application", "octet-stream"), MediaType.ALL); } ... protected void writeInternal(byte[] bytes, HttpOutputMessage outputMessage) throws IOException { FileCopyUtils.copy(bytes, outputMessage.getBody()); }
2.查看AnnotationMethodHandlerAdapter源碼:
public AnnotationMethodHandlerAdapter() { // no restriction of HTTP methods by default super(false); // See SPR-7316 StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); stringHttpMessageConverter.setWriteAcceptCharset(false); this.messageConverters = new HttpMessageConverter[]{new ByteArrayHttpMessageConverter(), stringHttpMessageConverter, new SourceHttpMessageConverter(), new XmlAwareFormHttpMessageConverter()}; } public void setMessageConverters(HttpMessageConverter<?>[] messageConverters) { this.messageConverters = messageConverters; }
3.查看MappingJacksonHttpMessageConverter源碼:
extends AbstractHttpMessageConverter<Object>
4.結論修改XML文件:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> <bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" > <property name = "supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> </list> </property> </bean> </list> </property> </bean>
注意:導入json相關jar包。解決。
題記
每個例子和demo最好都以最佳實踐去寫!(很欣賞作者這句話,生活工作,態度很重要)