这一篇主要讲文件上传需要注意的地方。
原理:
通过对Action的请求,在Action中书写相应代码,同时配置struts.xml。
涉及到的页面有:
list.jsp、Action、struts.xml
ListAction用于显示webroot\file\文件下的文件名(webroot和webContent同种意思)
upload此Action用于下载
结构图先上来:
src
|-cn.download
|-Download.java
|-ListAction.java
webContent
|-file
|-download
|-list.jsp
测试
贴上源码:
list.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<table>
<tr>
<td>序号</td>
<td>文件名</td>
<td>操作</td>
</tr>
<%
String[] str= (String[])request.getAttribute("fileNameList");
int i=1;
for(String s:str){
%>
<tr>
<td>i</td>
<td><%=s%></td>
<td><a href="download_s?fileName=<%=s%>">下载</a></td>
</tr>
<%i++;} %>
</table><br>
</body>
</html>
ListAction:
package cn.download;
import java.io.File;
import java.util.Map;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class ListAction extends ActionSupport {
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
String path = ServletActionContext.getServletContext().getRealPath("/file");
File files = new File(path);
Map<String, Object> request = (Map<String, Object>) ActionContext.getContext().get("request");
request.put("fileNameList", files.list());
return super.execute();
}
}
Struts.xml:
<package name="download" extends="struts-default" namespace="/">
<action name="download_s" class="cn.download.Download" >
<result type="stream">
<!-- 输入到浏览器的格式...此处为二进制 -->
<param name="contentType">application/octet-stream</param>
<!-- 在Struts中有个自动匹配的Convension插件,所以对于Action中的属性会被get属性名()注入值。例:age会被getAge()方法注入-->
<!-- skInputStream属性,与Action中的getSkInputStream()方法对应,即属性名为:skInputStream -->
<param name="inputName">skInputStream</param>
<!-- downName与Action中getDownName()方法对应,即属性downName -->
<param name="contentDisposition">attachment;filename=${downName}</param>
<!-- 缓冲区大小。一般是1024 -->
<param name="bufferSize">1024</param>
</result>
<result name="input">/error.jsp</result>
</action>
<action name="list" class="cn.download.ListAction">
<result >/download/list.jsp</result>
</action>
</package>
Download.java (Action):
package cn.download;
import java.io.InputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class Download extends ActionSupport {
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
//因为我的项目和服务器都是编码成UTF-8所以不会乱码。如果有乱码请加下面一段代码。
/* try{
fileName=new String(fileName.getBytes("ISO8859-1"),"UTF-8");
}catch(Exception e){
//throw new RuntimeException(e);
}
*/
System.out.println("setFileName:"+fileName);
this.fileName = fileName;
}
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return super.execute();
}
public InputStream getSkInputStream(){
return ServletActionContext.getServletContext().getResourceAsStream("/file/"+fileName);
}
public String getDownName(){
try{
//我是直接将filename以gb2312输出。因为关系到浏览器那边能接收哪种编码
//我测试过用"UTF-8",记过是中文有问题。所以,为了filename完整性,我直接转成gb2312。
//这个地方的问题,我查询过。请看我的另一篇关于“URL编码 为什么 中文 加% 原因 ”。
//所以我在此处认为,是第二条结论。是和操作系统有关。
fileName=URLEncoder.encode(fileName, "gb2312");
}catch(Exception e){
}
return fileName;
}
}
直接运行list这个Action,会转到list.jsp,并且将file文件夹下的文件名都输出到list.jsp页面
页面视图:
jsp:测试文档.txt。
弹出的下载框:%……txt
控制台结果是:
setFileName:测试文档.txt
所以,下载成功。
总结:
- struts下载需要注意的是struts.xml中的配置。以及Download.java(Action)中的配置。
- result type =”stream”
- 记得要有Action中要有inputStream类的返回值。
- struts.xml中的${downName} 此种方式不是EL表达式,是struts的一种取值方式。