正在学习SpringMVC的路上,今天项目中需要用到文件下载的一个小功能,于是乎开始各种找资料看SpringMVC中是如何通过MessageConverter来实现的,其实做完发现还是比较简洁的,过程遇到几个问题:
-
下载下来的文件内容异常
-
IE下无法下载
-
IE下下载时文件名乱码
上代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/**
* 文件下载
*
* @param fname 文件名称(含后缀)
* @throws IOException
*/
@RequestMapping
(
"/down"
)
public
ResponseEntity<
byte
[]> downFile(
@RequestParam
(required =
true
) String fname) {
HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String path = req.getSession().getServletContext().getRealPath(
"/upload"
);
//默认文件名称
String downFileName =
"开支明细"
+ fname.substring(fname.lastIndexOf(
"."
));
try
{
downFileName = URLEncoder.encode(downFileName,
"UTF-8"
);
//转码解决IE下文件名乱码问题
}
catch
(Exception e) {
e.printStackTrace();
}
//Http响应头
HttpHeaders headers =
new
HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData(
"attachment"
, downFileName);
try
{
return
new
ResponseEntity<
byte
[]>(FileUtils.readFileToByteArray(
new
File(path +
"/"
+ fname)),
headers,
HttpStatus.OK);
}
catch
(Exception e) {
e.printStackTrace();
//日志
//TODO
}
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData(
"attachment"
,
"error.txt"
);
return
new
ResponseEntity<
byte
[]>(
"文件不存在."
.getBytes(), headers, HttpStatus.OK);
}
|
问题拆解:
问题1:文件无法下载问题主要是因为配置servlet配置文件中没能把ByteArrayHttpMessageConverter配上
配置文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<
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
>
|
主要就是加上了一下这一段
1
|
<
bean
class
=
"org.springframework.http.converter.ByteArrayHttpMessageConverter"
/>
|
问题2、IE下无法下载主要是因为IE对http1.1支持不够完善(大家都这么说), 细了说就是对201状态支持不到位,代码如下:
1
2
3
|
return
new
ResponseEntity<
byte
[]>(FileUtils.readFileToByteArray(
new
File(path +
"/"
+ fname)),
headers,
HttpStatus.OK);
|
如果咱们将最后的状态码用HttpStatus.CREATED,那么问题就会出现了!
问题3、IE下这个乱码折腾了一下,也是各种关键字google,最后将filename转个码问题解决,咱这项目是UTF8的,所以我将默认的文件名(中文)Encode一下,代码如下:
1
|
downFileName = URLEncoder.encode(downFileName,
"UTF-8"
);
|