用Struts2实现文件上传
Struts2自己没有文件上传组件,它的上传功能依赖于第三方组件,默认使用FileUpload 。
1.添加jar包,在WEB-INF/lib下加入commons-fileupload.jar、commons-io.jar
2.设置form表单。”multipart/form-data”会以byte 流的方式提交用户请求
<form enctype="multipart/form-data" action="xxx.action" method="post">
<input type="file" name="image">
</form>
3.在action类中添加对应属性,下例中image对应表单中的name属性,必须一致
public class XAction{
//得到上传的文件
private File image;
//得到文件的名称
private String imageFileName;
public String upload() throws Exception{
String realpath = ServletActionContext.getServletContext().getRealPath("/images");
System.out.println(realpath);
if(image!=null){
File savefile = new File(new File(realpath), imageFileName);
if(!savefile.getParentFile().exists())
savefile.getParentFile().mkdirs();
//将内存中image存入硬盘savefile文件中
FileUtils.copyFile(image, savefile);
ActionContext.getContext().put("message", "上传成功");
}
return "success";
}
}
上传流程:
表单设置之后,在action类中添加与form中的name同名属性,通过application.getRealPath()获取上传文件在服务器的保存路径,再用FileUtils.copyFile()复制文件到new file。
用Struts2实现文件下载
struts.xml
<action name="FileDownload" class="com.action.FileDownload">
指定下载路径
<param name="inputPath">\image\test.jpg</param>
<result name="success" type="stream">
指定下载文件类型
<param name="contentType">image/jpg</param>
attachment:下载时打开下载框 fileName:显示在下载框上的文件名字
<param name="contentDisposition">attachment;fileName="struts.jpg"</param>
指定下载文件名字:这个downloadFile名字要和FileDownload.java类中的getDownloadFile()方法名去掉get一致
<param name="inputName">downloadFile</param>
指定下载文件的缓冲大小
<param name="bufferSize">1024</param>
</result>
</action>
action.java
private String inputPath;
public String getInputPath() {
return inputPath;
}
public void setInputPath(String inputPath) {
this.inputPath = inputPath;
}
//返回一个输入流,对于客户端是输入流,对于服务器端是输出流
public InputStream getDownloadFile() throws Exception{
//获取资源路径
return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
}
public String execute() throws Exception {
return Action.SUCCESS;
}
下载流程
对于客户端来说,下载为向自己的电脑input,result的type也应设置为stream。
下载路径inputPath作为action类的属性,在struts.xml中注入。同时result中还需要指明下载类型,以及获取inputstream的方法名inputName,在这个方法中,返回的是application.getResourceAsStream(inputPath)。
拦截器
拦截器是用来拦截发送到某个action的请求,在action执行之前和之后,可以插入某些通用的代码进行处理,提高了代码的复用率,这是一种AOP的思想。
如何自定义拦截器?
1.implements Interceptor / extends AbstractInterceptor
//在拦截器创建后、对action拦截前调用
public void init() {}
//在拦截器被垃圾回收之前调用,用来回收init()初始化的资源
public void destroy() {}
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("进入拦截器");
if(){
//“放行”,继续下一个拦截器,如果执行完拦截器则直接执行action中的method方法
//在该方法调用的前后可以插入Action调用前后拦截器需要做的方法
String result = invocation.invoke();
}else{
//
return "";
}
}
intercept()是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用invocation.invoke()方法即可,如果不需要,则返回一个字符串即可。
在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。
2.在strutx.xml中注册
3.在action中引用
拦截器栈
如果自定义了inteceptor,系统拦截器将失去作用,那么就需要定义一个由系统拦截器和自定义拦截器组成的拦截器栈。
<package name="" namespace="" extends="struts-default">
<interceptors>
<interceptor name=“permission" class="" />
设置默认拦截器栈
<default-interceptor-stack name=""/>
<interceptor-stack name="permissionStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="permission" />
</interceptor-stack>
</interceptors>
<action name="" class="" method="">
<result name="success"></result>
<interceptor-ref name="permissionStack"/>
</action>
</package>
defaultStack为系统拦截器。执行顺序按栈内定义顺序。
每一个拦截器都有两个参数:excludeMethods 和 includeMethods。
对文件上传使用拦截器
可在struts.xml中设置常量struts.multipart.maxSize=一次上传最大字节数,一般讲此值设置较大,而使用拦截器设定上传文件的大小。
<interceptor-ref name="fileUpload">
配置上传类型
<param name="allowedTypes">image/bmp,image/png</param>
配置上传大小
<param name="maximumSize">200000</param>
</interceptor-ref>
<interceptor-ref name="defaultStack">
</interceptor-ref>
动态设置保存文件的路径 (Action的属性值)
<param name="savePath">/upload</param>
Struts和json以及jQuery结合使用
1.struts2对数据进行json序列化,就必须要用到struts2的json-lib和struts2-json-plugin包。
2.异步提交的数据采用json格式。struts.xml中package的extends必须是json-default。
<package name="" namespace="" extends="json-default">
3.result的类型也必须是json。针对异步提交,action的result节点值应该为空,即不能再转向。
<result name="" type="json"></result>