文件上传:
1. Struts2默认采用了apache commons-fileupload。需要引入commons-fileupload相关依赖包:
* commons-io-1.3.2.jar
* commons-fileupload-1.2.1.jar
2. 表单中需要采用POST提交方式,编码类型需要使用:multipart/form-data
3. Struts2中Action相关属性命名规则:
取得文件名称->>规则:输入域的名称+固定字符串"FileName",String类型。
取得文件数据->>规则:File 输入域的名称,File类型。
取得内容类型->>规则:输入域的名称+固定字符串"ContentType"。String类型。
<form action="testUpload.action" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="upload">
</form>
private File file;//文件对应页面name名称
private String fileContentType;//文件类型
private String fileFileName;//文件名称
4. 得到输入流,采用输出流写文件(action中方法):
public String execute() throws Exception { InputStream is = null; OutputStream os = null; try { is = new BufferedInputStream(new FileInputStream(file)); os = new BufferedOutputStream(new FileOutputStream("c:\\" + fileFileName)); byte[] buffer = new byte[1024]; int len = 0; while ((len = is.read(buffer)) > 0) { os.write(buffer, 0, len); } }finally { if (is != null) {is.close();} if (os != null) {os.close();} } return Action.SUCCESS; }
5. 若想对上传文件进行限制,可以配置拦截器:
<!-- 配置上传大小 -->关注 <constant name="struts.multipart.maxSize" ="20971520"></constant> <interceptor-ref name="fileUpload"> <!-- 上传文件最大值 --> <param name="maximumSize">20971520</param> <!-- 允许类型 --> <param name="allowedTypes">image/jpeg,image/gif,image/bmp</param> </interceptor-ref>
6. 不使用fileupload的拦截器拦截不允许的文件类型:
1). 文件上传:设置不允许上传的文件类型 <package name="struts2" extends="struts-default" namespace="/"> <action name="testUpload" class="com.mumu.action.TestAction" method="upload"> <result>/index.jsp</result> <result name="input">/error.jsp</result> <param name="notAllowedTypes">image/jpeg,image/jpg</param> // 关注 </action> </package> 2). 通过方法判断: public String filterDocType(String[] types){ //获取文件类型 String fileType = this.getFileContentType(); //遍历类型 for(String type:types){ if(type.equals(fileType)) return INPUT; } return null; } 3). 文件上传时先判断类型: public String upload() throws IOException{ String filterResult = this.filterDocType(this.getNotAllowedTypes().split(","));关注 if(filterResult!=null){ //关注 ActionContext.getContext().put("typeError","类型上传不允许"); return filterResult; } (看第6个,第6个代码) 上传文件代码..... (上传数据库过程中可以为文件设置新名称等) //使用日期作为新名称 String u = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()); //获取扩展名称 String exename = this.fileFileName.substring(fileFileName.lastIndexOf(".")); t_picture.setOldName(fileFileName); String newname = u+exename; t_picture.setNewName("upload/"+newname); //将数据存入数据库 dao.save(user); //文件数据输入流 InputStream in = new FileInputStream(file); //上传后文件存放的路径 String path = ServletActionContext.getServletContext().getRealPath("/upload"); }
7. 保存文件时应该保存上传的文件名称和真正存放时的文件名称。
8. 可以一次有多个上传框一起上传文件。多文件上传文本框名字必须一样,放在同一个form里面。action中定义一个数组,名字为上传文件文本框的名字。
9. 默认上传大小为2M。
10. struts:将文件保存到saveDir目录下,然后从该目录下以IO的形式读到指定的目录下。所以file指向的是saveDir目录下的文件。文件file.getName()
得到的是文件在缓存中的名字,也就是saveDir下的名字。
文件下载:
1. 配置文件中result的类型必须<result type="stream">
2. 配置属性:
<action name="testDownload" class="com.mumu.action.TestAction" method="download"> <result type="stream"> <!-- 表示强制弹出提示框,下载的文件(包含路径) --> <!-- 通过el表达式,动态的获得下载时下载框显示的名字。--> <!-- attachment表示不管能不能打开,都要打开下载对话框。默认为内联, 就是浏览器能打开就打开。 --!> <param name="contentDisposition">attachment;filename=${filename}</param> <!-- 在类中要有一个get方法来对应inputStream,且返回类型为inputStream action中对应的方法名get+里面的参数名(如:download对应的是getDownload) inputName是固定的 --> <param name="inputName">inputStream</param> <!-- 文件下载的大小 --> <param name="bufferSize">1024</param> </result> <result name="input">/error.jsp</result> </action>
3. 错误:java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [inputStream] in the invocation stack.
Check the <param name="inputName">
第一个原因:<param name="inputName">inputStream</param>在类中没有对应的public InputStream getInputStream()方法
第二种原因:文件不存在
第三种原因:文件的路径不对
4. 文件下载需要写的两个方法(action中):
/** * 文件下载 */ public String download(){ return SUCCESS; } /** * 文件下载流,返回值必须是InputStream。 * filename必须包含完整的文件路径。filename是从web项目开始,向下的路径。如:webroot下有一个upload里,放着下载的文件。 */ public InputStream getInputStream(){ return ServletActionContext.getServletContext().getResourceAsStream(filename); }
5. 中文下载乱码的一种解决方式:
this.fileName="资料大全.txt";
this.fileName=new String(this.fileName.getByte("gbk"),"8859_1");