文件的上传
上传表单:
表单属性:enctype="multipart/form-data"
提交类型:method = "post"
输入属性: type="file"
文件上传在struts中使用文件上传拦截器上传文件
<interceptorname="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
Struts的默认提交大小为2M
下面我们就来实现一个文件上传的小案例
文件结构图如下:
首先在upload.jsp中写一个上传表单
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>文件上传页面</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">
</head>
<body>
<form action="${pageContext.request.contextPath }/uploadAction" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="userName"><br/><br/>
文件:<input type="file" name="file1"><br/><br/>
<input type="submit" value="上传">
</form>
</body>
</html>
配置对应的upload.xml文件,拦截请求,同时配置错误视图input,转发到/uploadPage/error.jsp中
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="uploads" extends="struts-default">
<!-- 注意: action 的名称不能用关键字"fileUpload" -->
<action name="uploadAction" class="cn.qblank.upload.UploadAction">
<!-- 限制运行上传的文件类型 -->
<interceptor-ref name="defaultStack">
<!-- 限制运行文件的扩展名 -->
<param name="fileUpload.allowedExtensions">txt,jpg,jar,rar,exe</param>
<!-- 限制运行的类型 【与上面同时使用,取交集】-->
<!-- <param name="fileUpload.allowedTypes">text/plain</param> -->
</interceptor-ref>
<result name="success" type="redirect">/down_list</result>
<!-- 配置错误视图 -->
<result name="input">/uploadPage/error.jsp</result>
</action>
<action name="down_*" class="cn.qblank.upload.DownloadAction" method="{1}">
<result name="list">/uploadPage/list.jsp</result>
<!-- 下载 -->
<result name="download" type="stream">
<!-- 运行下载的文件的类型:指定为所有的二进制文件类型 -->
<param name="contentType">application/octet-stream</param>
<!-- 对应的是Action中属性: 返回流的属性【其实就是getAttrInputStream()】 -->
<param name="inputName">attrInputStream</param>
<!-- 下载头,包括:浏览器显示的文件名 -->
<param name="contentDisposition">attachment;filename=${downFileName}</param>
<!-- 缓冲区大小设置 -->
<param name="bufferSize">1024</param>
</result>
</action>
</package>
</struts>
配置struts常量constant.xml,在这里我们可以对编码、访问后缀、上传文件大小等动作进行限制
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 一、全局配置 -->
<!-- 0. 请求数据编码 -->
<constant name="struts.i18n.encoding" value="UTF-8"/>
<!-- 1. 修改Struts默认的访问后缀 -->
<constant name="struts.action.extension" value="action,do,"></constant>
<!-- 2. 修改xml自动重新加载 -->
<constant name="struts.configuration.xml.reload" value="true"/>
<!-- 3. 开启动态方法调用 (默认不开启)-->
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<!-- 4. 修改上传文件的最大大小为300M -->
<constant name="struts.multipart.maxSize" value="314572800"/>
</struts>
写一个UploadAction对上传的文件进行处理
package cn.qblank.upload;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport{
//文件
private File file1;
//文件名
private String file1FileName;
//文件类型
private String file1ContentType;
//配置setter
public void setFile1(File file1) {
this.file1 = file1;
}
public void setFile1FileName(String file1FileName) {
this.file1FileName = file1FileName;
}
public void setFile1ContentType(String file1ContentType) {
this.file1ContentType = file1ContentType;
}
@Override
public String execute() throws Exception {
//获取上传路径upload
String path = ServletActionContext.getServletContext().getRealPath("/upload");
//创建目标文件对象
File destFile = new File(path, file1FileName);
//把上传的文件拷贝到目标文件中
FileUtils.copyFile(file1, destFile);
System.out.println("文件类型:" + file1ContentType);
return SUCCESS;
}
}
根据上面的upload.xml的配置,提交成功后会进入/down_list这个路径,于是我们在类DownloadAction中写一个list方法用于将提交的文件存储到域中
/**
* 列出所有上传的文件
* @return
* @throws Exception
*/
public String list() throws Exception {
//获取路径
String path = ServletActionContext.getServletContext().getRealPath("/upload");
//新建一个目录对象
File file = new File(path);
String[] fileNames = file.list();
//保存到域中
ActionContext context = ActionContext.getContext();
//得到代表request的Map
Map<String,Object> request = (Map<String, Object>) context.get("request");
request.put("fileNames", fileNames);
return "list";
}
最后返回一个list标志,然后根据upload.xml中的配置,转发到/uploadPage/list.jsp,于是我们就可以写一个list.jsp界面用于显示上传的文件
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>列表</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">
<style>
fieldset{
width:400px
}
table{
}
</style>
</head>
<body>
<!-- 从request域中取出数据 -->
<fieldset>
<legend>文件列表</legend>
<table border="1">
<tr>
<th>序号</th>
<th>文件名</th>
<th>操作</th>
</tr>
<c:forEach varStatus="sc" var="fileName" items="${requestScope.fileNames }">
<tr>
<td>${sc.count}</td>
<td>${fileName}</td>
<td>
<!-- 构建一个url -->
<c:url value="down_down" var="url">
<c:param name="fileName" value="${fileName }"></c:param>
</c:url>
<a href="${url}">下载</a>
</td>
</tr>
</c:forEach>
</table>
</fieldset>
</body>
</html>
不要忘记在struts.xml中添加这些upload.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- 总配置文件 负责引入各个子配置文件 -->
<!-- 常量 -->
<include file="constant.xml"></include>
<include file="cn/qblank/excute/config.xml"></include>
<!-- 类型转换 -->
<include file="cn/qblank/type/type.xml"></include>
<!-- 文件上传 -->
<include file="cn/qblank/upload/upload.xml"></include>
</struts>
文件下载:
前面的list.jsp中已经将文件下载的地址获取到了,接下来就可以在DownloadAction中进行下载的操作
/**
* 下载
*/
//1.获取将要下载的文件的文件名
private String fileName;
public void setFileName(String fileName) {
try {
//get方式提交 处理中文乱码
fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
this.fileName = fileName;
}
//2.在struts.xml中配置返回stream
public String down() throws Exception {
return "download";
}
//3.返回文件流
public InputStream getAttrInputStream(){
return ServletActionContext.getServletContext().getResourceAsStream("/upload/" + fileName);
}
//4.使下载文件的名字为显示的中文名 与upload.xml中的downFileName相对应
public String getDownFileName(){
try {
//进行中文编码
fileName = URLEncoder.encode(fileName,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return fileName;
}
值得注意的是这个和upload.xml中的配置是对应的,这些配置可以在api中找到
<action name="down_*" class="cn.qblank.upload.DownloadAction" method="{1}">
<result name="list">/uploadPage/list.jsp</result>
<!-- 下载 -->
<result name="download" type="stream">
<!-- 运行下载的文件的类型:指定为所有的二进制文件类型 -->
<param name="contentType">application/octet-stream</param>
<!-- 对应的是Action中属性: 返回流的属性【其实就是getAttrInputStream()】 -->
<param name="inputName">attrInputStream</param>
<!-- 下载头,包括:浏览器显示的文件名 -->
<param name="contentDisposition">attachment;filename=${downFileName}</param>
<!-- 缓冲区大小设置 -->
<param name="bufferSize">1024</param>
</result>
</action>
这样,文件下载的也完成了