文件下传和上载解析
表单元素的enctype属性:
application/x-www-form-urlencoded(默认)
1)默认编码方式,只处理表单域里的value属性值。
2)可通过request.getParameter()方法取得请求的参数。
multipart/form-data
1)以二进制流的方式处理表单数据,且会将文件域指定的文件内容也封装到请求参数里。
2)无法通过request.getParameter()方法取得请求的参数。
struts2的文件上传(action属性):
private File xxx;封装该文件对应的文件内容。
private String xxxFileName;该文件的文件名称。
private String xxxContentType;该文件的文件类型。
fileUpload拦截器:
allowedTypes属性:指定允许上传的文件类型。多文件用","
maximumSize属性:指定允许上传文件的大小。单位是字节。
过滤失败,返回input 逻辑视图。
需要显示的配置defaultStack 拦截器栈
文件上传的常量配置:
struts.multipart.saveDir:上传文件的临时文件夹。
默认使用javax.servlet.context.tempdir.
此临时文件夹在Tomcat的work\Catalina\localhost\下
应避免使用Tomcat的工作路径作为临时路径
struts.multipart.maxSize:上传文件的最大字节数。
可控制整个struts2应用里的上传文件的大小。
输出错误提示:
-<s:fileError/>
国际化错误提示的key
struts.message.error.file.too.large:上传文件过大。
struts.message.error.content.type.not.allowed:上传类型错误。
struts.message.error.uploading:文件上传出现未知错误。
文件下载
stream结果类型
contentType属性:指定被下载文件的文件类型。
inputName属性:指定被下载文件的入口输入流。
contentDisposition:
指定下载文件的处理方式(内联(inline)和附件(attachment))。
通过filename指定下载文件的文件名。
bufferSize属性:指定下载文件时的缓冲大小。
<form action="load_doPictureUpload.action" enctype="multipart/form-data" method="post"> <table> <tr> <td>上传图片:</td> <td><input type="file" name="picture"/></td> </tr> <tr> <td><input type="submit" value="上传"/></td> </tr> </table> </form>
文件名称:<a href="load_doDownPicture.action">下载</a>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd" > <struts> <!-- 程序国际化 指定国际化资源文件--> <constant name="struts.custom.i18n.resources" value="ApplicationResources"/> <!-- 指定request 和 response中的编码方式,相当于request.setCharacterEncoding("utf-8") 和response.setCharacterEncoding("utf-8") --> <constant name="struts.i18n.encoding" value="utf-8"/> <!-- 是否国际化信息自动加载 默认为false --> <constant name="struts.i18n.reload" value="false"/> <!-- 设置上传文件时不要Tomcat的临时路径,使用设置的值 --> <constant name="struts.multipart.saveDir" value="/"/> <!-- 设置上传文件大小,此处设置会对起最后的限制作用! --> <constant name="struts.multipart.maxSize" value="10485760"/> <!-- 该属性指定需要struts2 处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由struts处理 如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开--> <constant name="struts.action.extension" value="action"/> <!-- 设置浏览器是否缓存静态内容,默认值为true(生成环境下使用),开发阶段最好关闭 --> <constant name="struts.serve.static.browserCache" value="false"/> <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生成环境下使用),开发阶段最好打开 --> <constant name="struts.configuration.xml.reload" value="true"/> <!-- 开发模式下使用,这样可以 打印出更详细的错误信息 --> <constant name="struts.devMode" value="true"/> <!-- 默认的试图主题 --> <constant name="struts.ui.theme" value="simple"/> <package name="package-default" extends="json-default" abstract="true"> <!-- 配置公共results --> <global-results> <!-- json 回调 --> <result name="jsonback" type="json"> <param name="includeProperties">status</param> </result> <result name="error">/</result> </global-results> <!-- 异常处理 --> <global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"/> </global-exception-mappings> </package> <!-- 通过include元素导入其他配置文件 --> <include file="strutsxml/struts_*.xml"/> </struts>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd" > <struts> <package name="picture" extends="package-default"> <action name="load_*" class="org.cric.action.LoadAction" method="{1}"> <!-- 配置fileUpload的拦截器 --> <interceptor-ref name="fileUpload"> <!-- 配置允许上传的文件的大小(字节) --> <param name="maximumSize">389377</param> <!-- 配置允许上传出的文件类型 --> <param name="allowedTypes">image/png,image/gif,image/jpeg</param> </interceptor-ref> <interceptor-ref name="defaultStack"/> <result name="input">/error.jsp</result> <result>/ok.jsp</result> <result name="down" type="stream"> <!-- 指定下载文件的文件类型 --> <param name="contentType">image/gif</param> <!-- 指定由getTageFile()方法返回被下载文件的InputStream --> <param name="inputName">inputStream</param> <param name="contentDisposition">attachment;filename="${fileName}"</param> <!-- 指定下载文件时的缓冲 --> <param name="bufferSize">2048</param> </result> </action> </package> </struts>
package org.cric.action; import java.io.File; import java.io.InputStream; import org.apache.struts2.ServletActionContext; import org.cric.util.ImgWriteUtil; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionSupport; public class LoadAction extends ActionSupport { private File picture;//封装文件域对应的文件内容 private String pictureFileName;//该文件的文件名称 private String pictureContentType;//该文件的文件类型 private String image; private String fileName; private InputStream inputStream; public InputStream getInputStream() { return inputStream; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public File getPicture() { return picture; } public void setPicture(File picture) { this.picture = picture; } public String getPictureFileName() { return pictureFileName; } public void setPictureFileName(String pictureFileName) { this.pictureFileName = pictureFileName; } public String getPictureContentType() { return pictureContentType; } public void setPictureContentType(String pictureContentType) { this.pictureContentType = pictureContentType; } ////////////////////////////////////////////////// ////////////////////////////////////////////////// public String doPictureUpload() throws Exception{ String pathStr=ServletActionContext.getRequest().getRealPath("/image");//获取项目实际运行的路径 String endStr=this.getPictureFileName().substring(this.getPictureFileName().lastIndexOf("."));//获取图片的后缀名 String nameStr=String.valueOf(System.currentTimeMillis());//获取名称 String picturePath=pathStr+"/"+nameStr+endStr; File toFile=new File(picturePath); ImgWriteUtil imgWriteUtil = new ImgWriteUtil(); imgWriteUtil.writeImg(picture, toFile); this.image="image/"+nameStr+endStr; return Action.SUCCESS; } public String doDownPicture() throws Exception{ fileName="中文.gif"; fileName=new String(fileName.getBytes("GB2312"),"ISO8859-1"); this.setInputStream(ServletActionContext.getServletContext().getResourceAsStream("/image/1287400068000.gif")); return "down"; } }
/** * 写入图片 */ package org.cric.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class ImgWriteUtil { private BufferedInputStream bis; private BufferedOutputStream bos; public void writeImg(File fromfile, File tofile) {// 写入图片 int len = 0; int size = 0; try { bis = new BufferedInputStream(new FileInputStream(fromfile)); bos = new BufferedOutputStream(new FileOutputStream(tofile)); size = (int) fromfile.length(); byte[] buffer = new byte[size]; while ((len = bis.read(buffer)) > 0) { bos.write(buffer, 0, len); } } catch (FileNotFoundException e) { e.printStackTrace(); throw new RuntimeException("创建文件时出错!"); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("读写文件时出错!"); } finally { try { if (bos != null) { bos.close(); } if (bis != null) { bis.close(); } } catch (IOException e) { e.printStackTrace(); } } } }