When using struts2 to do file download, we may use most of the configuration in the struts.xml inside, in fact, we use annotations in the same way
can do file download.
Add the following two methods to the action:
Private String filename;//plus get and set methods
Public String DownloadFile () {
return "Download";
}
Public InputStream getInputStream () {
String dir = "/downloads/" +filename;
Take relative path, this relative path is the relative path below the Webroot
Return Servletactioncontext.getservletcontext (). getResourceAsStream (dir);
}
After writing, add header annotations
@Results ({
@Result (name = "Download", type= "stream", params={
"ContentType", "Application/octet-stream",//Here is Octet-stream, this can represent any file type
"InputName", "InputStream",
"Contentdisposition", "Attachment;filename=${filename}",
"BufferSize", "4096"
}),
})
Carefully observe the wording of the note, and then compare the Struts.xml file inside the wording, in fact, they are similar in writing, the steps are exactly the same. But here's a little bit of attention:
① "Attachment;filename=${filename}" here, ${filename} represents the name of the file to download from the foreground page, which is the filename value in the action.
②${filename} do not add a single/double quotation marks, if you write "Attachment;filename= ' ${filename} '", then the downloaded file name will also have two " quotation marks (but in the Struts.xml configuration file, it can be quoted, and preferably quoted.) This is a different point. Note: There is a small bug here, which is explained later.
After writing, you can write a JSP to test.
Under normal circumstances, the program has been completed, if the foreground page passed over the file to be downloaded in the server does not exist, the program will be error, the user is very bad impression. Therefore, we need to further deal with the situation that the document does not exist.
There are many ways to deal with, you can click on the download file link, first through the Ajax access to the action, if the file does not exist, give a popup prompt user This file does not exist, if the file exists, and then through other channels (such as form form) access to the action, normal download files. Also, it is a workaround to jump to the error page when the error interface appears.
And I am using another method: in the action to define a message variable, if the need to download the file does not exist, the message is assigned a value, such as message= "you want to download the file does not exist" and jump back to the download page, in the Download JSP page with JS judge, If the returned message has a value (the message does not have a value if the file exists), the popup window is given (the other hint method is also OK). The optimized code is as follows:
Private String FileName;
Private String message;
Public String DownloadFile () {
String dir = "/downloads/" +filename;
if (null ==servletactioncontext.getservletcontext (). getResourceAsStream (dir)) {
Message = "Sorry,file is not exist";
return "Filenotexist";
}
return "Download";
}
Public InputStream getInputStream () {
String dir = "/downloads/faq/" +filename;
Return Servletactioncontext.getservletcontext (). getResourceAsStream (dir);
}
Annotations:
@Results ({
@Result (name = "Download", type= "stream", params={
"ContentType", "Application/octet-stream",
"InputName", "InputStream",
"Contentdisposition", "Attachment;filename=${filename}",
"BufferSize", "4096"
}),
@Result (name= "Filenotexist", location= "/web-inf/web/faq.jsp")
})
JSP page Add:
①<input type= "hidden" value= "${message}" id= "message" >
②<script type= "Text/javascript" >
$ (document). Ready (function () {
var message = $ ("#message"). Val ();
if (message! = NULL && Message! = "") {
alert (message);
}
});
</script>
If the file name you want to download contains spaces, for example: Oracle 11g for Windows.pdf
This program will have a small bug, although click to download, will pop up the download box, but, you see the downloaded file name is Oracle, the characters after the space is not. Of course, there are no subsequent file type names. So the file we downloaded is an unknown file. Looking closely at the reason, we can know that the value of filename received in action is Oracle 11g for Windows.pdf, because only here the download file name can be downloaded successfully, otherwise you will be prompted not to find the file. So, the problem is in the annotations there. Note there is this filename=${filename}, we replace the file name with ${filename}, so this becomes
The Filename=oracle 11g for windows.pdf,struts frame will filter out the characters following the space (presumably), so it becomes
Filename=oracle, that's why when we download files, the file name only shows Oracle, for the full reason that's not shown. But we analyzed before, cannot write: Filename= ' ${filename} ', because this is written, we download the file name is ' Oracle 11g for Windows.pdf ', there is a single quote before and after. If you are configuring in Struts.xml instead of annotations, then you'd better write Filename= ' ${filename} ' so there's no problem. In the annotations we can fix this bug by a means of replacing the space with an underscore "_". The modified code is as follows:
Public InputStream getInputStream ()
{
String dir = "/downloads/faq/" +filename;
//Special handling: If the downloaded file name contains spaces, you need to replace the space with an underscore "_"
Otherwise, in the note there filename=${filename} The filename is just the first part of a space
FileName = Filename.replace (', ' _ ');
Return Servletactioncontext.getservletcontext (). getResourceAsStream (dir);
}
Now even if you download the file name has a space, the download will not appear after downloading files of unknown file type, the bug has been resolved.