【Struts2】文件的上传与上传权限的控制

来源:互联网 发布:西安高新区软件新城 编辑:程序博客网 时间:2024/05/21 06:18

很多关于Struts2的文章,对此都有详细的介绍,但是里面的示例的程序写得很糟糕。各种无意义的拦截器技术、国际化技术、初始化参数,把原本简单的程序弄得很繁琐。同时,部分关键的代码没有写。导致每次上传Tomcat都报Unable to find 'struts.multipart.saveDir' property setting.的警告。然后上传大点的文件,整个Web工程就崩溃,然后后台抛出大段的File Upload BaseSize Limit Exceeded Exception异常,刷爆Tomcat。其实这些警告与异常都是可以避免的。我觉得程序就应该更加简短与丰满,而不是雍容华贵。下面举个例子来说明。


一、基本目标

利用Struts2制作一个文件上传系统,限制只能上传少于2M的图片,上传成功后就把图片的中文名、大小,与原本的图片显示。这图片保存到服务器的Upload文件夹。同时,扔一个再大的文件给这个系统,已不会找不到服务器。



二、基本准备

与《【Struts2】Struts2纯手工安装、配置以及Helloworld,以最新版struts 2.3.20 GA做例子》(点击打开链接)一样准备好Struts2必须的jar,同时写好web.xml。这个不解释了。每次说Struts2都要引用一次这个文章。这次不用引入额外的包。


配置好Struts2之后,目录结构如下,在里面新建两个文件夹,一个是未来存放上传文件的Upload,一个是Struts2要求的上传临时文件夹tmp,这个tmp没有也可以,只是会不停报Unable to find 'struts.multipart.saveDir' property setting.的警告。写程序的时候,里面不用写任何东西。


三、制作过程

1、首先是upload.jsp,没什么好说的,就是一个文件表单。只是希望大家注意要对文件域设置好name,一会儿Struts2要根据这个名称接受文件,这里是file。

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>选择文件</title></head><body><form method="post" action="upload" enctype="multipart/form-data">选择文件:<input type="file" name="file" /><br /><input type="submit" value="上传" /></form></body></html>

2、uploaderr.jsp上传失败页面,这个主要是输出后台穿过来的错误信息。errMsg直接利用Jsp2.4的el表达式取就可以了,在《【Filter】利用过滤器Filter解决post传递的编码问题与利用EL表达式简化参数传递》(点击打开链接)已经提到过。不用像《【Servlet】利用Servlet3.0标准与JSTL表达式实现文件上传系统,支持图片上传后显示》(点击打开链接)利用到c标签,也就是JSTL表达式,更不用使用struts的s标签,就取个小小的值,不用这么复杂。

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>上传失败</title></head><body>上传失败!${errMsg}<br /><a href="upload.jsp">返回</a></body></html>

3、上传成功页面uploadsuc.jsp,同理可得,取出服务器的上的保存名字构造出图片地址,后台传过来的文件名、文件大小,服务器上的保存文件名基本是一个时间戳,不可能给你存中文名的,但就算你要存中文名读取这张图片也没有问题,但是要用到《【Struts2】中文文件的下载与下载权限的控制》(点击打开链接)的技术

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>上传成功</title></head><body>上传成功!<br />文件:${fileFileName},大小:${fileLength}<br /><img src="./Upload/${saveFileName }" /><br /><a href="upload.jsp">返回</a></body></html>

4、struts.xml,这里虽然涉及到文件,但是按照往常一样指定处理的Action也就是java文件,设置根据返回结果跳转到什么链接就可以了。因为无须把文件抛回前台。主要是要在开头要设置两个属性,防止Tomcat抛出异常。也不要像某些书籍、文章那样设置什么拦截器、初始化参数什么的,半点意义没有。只会增加你的记忆负担而已。

<?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><!-- 只是为了禁止上传时候弹出没有临时上传文件夹的警告! 实际上,这个临时上传文件夹没有也可以上传的。 不知道有什么用。 --><constant name="struts.multipart.saveDir" value="/tmp" /><!-- 只是设置struts抛出文件过大异常的大小,这里设置成4G,因为FAT32最大的单文件就是4Gstruts2默认抛出文件过大异常的大小为2097152B也就是恰好2M,超过这个数会在Tomcat吐出一堆异常, 然后前台显示找不到页面,非常不友好。文件大小的控制不应该利用抛出异常控制,我们自己在java文件中控制就可以--><constant name="struts.multipart.maxSize" value="4294967296" /><!-- 在test包里面 --><package name="test" extends="struts-default"><!-- action为upload的执行方法就是test包中的upload.java中的run方法 --><action name="upload" class="test.upload" method="run"><result name="success">/uploadsuc.jsp</result><result name="error">/uploaderr.jsp</result></action></package></struts> 

5、upload.java这是我们核心处理Java,对比与《【Servlet】利用Servlet3.0标准与JSTL表达式实现文件上传系统,支持图片上传后显示》(点击打开链接)的利用一个Part对象处理完所有东西的Servlet3.0的文件上传,Struts2的文件上传,必须设置一个名称与前台页面传过来页面相同的File对象。在upload.jsp传来File对象的name="file"。因此就有一个File file的静态类成员。之后,Struts2会自动生成一个fileFileName,也就是文件域name属性+FileName的东西,给你包装好用户传递过来的文件名,注意那个N必须大写。当然还有一个name属性+ContentType的String对象给你封装文件类型,但是根本不用利用到这个对象,完全可以根据FileName中.的后缀名去确定文件类型。之后file.length()可以取出文件大小。

好了,这就可以对文件的上传权限进行控制。Struts2还要我们自己写文件存入服务器的方法。这段东西,没有什么解释。Java存文件就是这样存的。

package test;//用到了输入流,必须的支持import java.io.*;//这个是为了取出Upload这个文件夹的绝对路径import org.apache.struts2.ServletActionContext;//这是Struts2必要的支持import com.opensymphony.xwork2.ActionSupport;//防止报序列号警告@SuppressWarnings("serial")//Struts2必须继承这个类public class upload extends ActionSupport {//上传文件Action固有的两个属性fileContentType不是必须的//但一定要设置好getter与setter,这是Struts2固有的特点。//设置完getter与setter一定不可以在执行方法中再次初始化,如String xx=//这样前台会取不值的!private File file;private String fileFileName;//saveFileName是保存到服务器的名字//利用传来过的文件的后缀名+时间戳构造,//必要时还可以补上用户名private String saveFileName;//这是文件的大小,主要是为了传到前台private String fileLength;private String errMsg;//防止输入输出流报警告@SuppressWarnings("resource")public String run() throws Exception {//对错误信息字符串赋予""值,否则会返回前台一个nullerrMsg = "";//判断是否符合上传的条件boolean canUpload = true;//取出Upload的绝对路径String saveFilePath = ServletActionContext.getServletContext().getRealPath("/Upload");//取出上传文件的后缀名String fileExtensions = getFileFileName().substring(getFileFileName().lastIndexOf("."));//根据后缀名判断是否能上传if (!(fileExtensions.equals(".gif") || fileExtensions.equals(".png")|| fileExtensions.equals(".jpeg")|| fileExtensions.equals(".jpg") || fileExtensions.equals(".bmp"))) {errMsg += "上传文件只能是图片,后缀名必须是bmp,gif,jpg,jpeg!";canUpload = false;}//根据文件大小判断是否能上传if (file.length() > (2 * 1024 * 1024)) {errMsg += "上传文件太大,请少于2M!";canUpload = false;}//把文件大小转化成字符串,推回给前台fileLength = (file.length() / 1024) + "KB";//如果可以上传if (canUpload) {//就营造一个服务器上的文件名saveFileName = System.currentTimeMillis() + fileExtensions;//输出流是保存到服务器的输出流FileOutputStream fos = new FileOutputStream(saveFilePath + "/"+ saveFileName);//输入流就是传过来的文件FileInputStream fis = new FileInputStream(getFile());//缓冲数组byte[] buffer = new byte[1024];int len = 0;//输入流不停读东西到缓冲数组,直到读完while ((len = fis.read(buffer)) > 0) {//输出流不停把缓冲数组的东西的东西写到服务器上Upload的绝对目录上面fos.write(buffer, 0, len);}//返回struts.xml一个成功结果return "success";} else {return "error";}}//所有静态成员必须有getter与setter,否则不能与前台交互public File getFile() {return file;}public void setFile(File file) {this.file = file;}public String getFileFileName() {return fileFileName;}public void setFileFileName(String fileFileName) {this.fileFileName = fileFileName;}public String getSaveFileName() {return saveFileName;}public void setSaveFileName(String saveFileName) {this.saveFileName = saveFileName;}public String getErrMsg() {return errMsg;}public void setErrMsg(String errMsg) {this.errMsg = errMsg;}public String getFileLength() {return fileLength;}public void setFileLength(String fileLength) {this.fileLength = fileLength;}}


1 0
原创粉丝点击