struts2没有提供自己的请求解析器,也就是说,struts2不会自己去处理multipart/form-data的请求,它需要调用其他请求解析器,将http请求中的表单域解析出来,但struts2在原有的上传解析器上作了进一步封装,更进一步简化了文件上传,struts2的struts.properties配置文件中,配置struts2的上传文件解析器struts.multipart.parser=jakarta(srtuts2默认),也可以设置为常用的cos,pell等。项目结构示意图:web.xml文件内容:
xmlns:xsi="https://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="https://java.sun.com/xml/ns/javaee
https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
struts2
org.apache.struts2.dispatcher.filterdispatcher
struts2
/*
struts-cleanup
org.apache.struts2.dispatcher.actioncontextcleanup
struts-cleanup
/*
index.jsp
这里web.xml多配置了一个actioncontextcleanup的配置,这个类是一个filter,他的作用是方便strut2与sitemesh整合,与文件上传本没有关系,但不加载这个filter,可能在上传中出现莫名的异常,加入后就稳定了,可能是strut2的bug吧。index.jsp文件内容:<%@page language="java" pageencoding="gbk"%><%@taglib prefix="s" uri="/struts-tags"%><%@taglib prefix="c" uri="http://www.51sjk.com/upload/articles/1/0/253/253671_20210627003202584.jpg html public "-//w3c//dtd html 4.01 transitional//en"> ${requestscope.typeerror}
success.jsp文件内容:<%@ page language="java" pageencoding="gbk"%>
<%@taglib prefix="s" uri="/struts-tags"%>
上传成功!
文件标题:
文件为: " />
struts.properties文件内容:struts.locale=zh_cnstruts.i18n.encoding=gbkstruts.multipart.parser=jakartastruts.xml文件内容: image/pjpeg,image/bmp,image/jpg,image/png,image/gif,image/jpeg /upload /success.jsp /index.jsp 参看tomcat的web.xml中的mime: gif image/gifuploadaction.java文件内容:package lee;import java.io.*;import com.opensymphony.xwork2.actioncontext;import org.apache.struts2.servletactioncontext;import com.opensymphony.xwork2.actionsupport;public class uploadaction extends actionsupport { private string title; private file upload; private string uploadcontenttype; private string uploadfilename; private string allowtypes; // 接受依赖注入的属性 private string savepath; // 接受依赖注入的方法 public void setsavepath(string value) { this.savepath = value; } private string getsavepath() throws exception { return servletactioncontext.getservletcontext().getrealpath(savepath); } public void settitle(string title) { this.title = title; } public void setupload(file upload) { this.upload = upload; } public void setuploadcontenttype(string uploadcontenttype) { this.uploadcontenttype = uploadcontenttype; } public void setuploadfilename(string uploadfilename) { this.uploadfilename = uploadfilename; } public string gettitle() { return (this.title); } public file getupload() { return (this.upload); } public string getuploadcontenttype() { return (this.uploadcontenttype); } public string getuploadfilename() { return (this.uploadfilename); } @override public string execute() throws exception { system.out.println("开始上传单个文件---"); system.out.println(getsavepath()); system.out.println("==========" getuploadfilename()); system.out.println("==========" getuploadcontenttype()); system.out.println("==========" getupload()); // 判断是否允许上传 string filterresult = filtertype(this.getallowtypes().split(",")); if (filterresult != null) { actioncontext.getcontext().put("typeerror","您要上传的文件类型不正确"); return filterresult; } // 以服务器的文件保存地址和原文件名建立上传文件输出流 fileoutputstream fos = new fileoutputstream(getsavepath() "\\" getuploadfilename()); fileinputstream fis = new fileinputstream(getupload()); byte[] buffer = new byte[1024]; int len = 0; while ((len = fis.read(buffer)) > 0) { fos.write(buffer, 0, len); } return success; } public string filtertype(string[] types) { string filetype = this.getuploadcontenttype(); for (string type : types) { if (type.equals(filetype)) { return null; } } return input; } public string getallowtypes() { return allowtypes; } public void setallowtypes(string allowtypes) { this.allowtypes = allowtypes; }}struts2针对表单中名为xxx的文件域,在对应的action类中使用3个属性来封装该文件域信息:
1.类型为file的xxx属性:用来封装页面文件域对应的文件内容。
2.类型为string的xxxfilename属性:用来封装该文件域对应的文件的文件名。
3.类型为string的xxxcontenttype属性:用来封装该文件域应用的文件的文件类型。以上程序调试通过!