现在的位置: 首页 > 综合 > 正文

通过Struts实现文件上传详解

2014年02月04日 ⁄ 综合 ⁄ 共 3295字 ⁄ 字号 评论关闭

最近要做一个新项目,里面涉及到图片等文件的上传,具体的流程是通过客户端产生的流把图片传给服务器端,然后服务器端就把此文件存到apache服务器下,接着,把存放的地址再返回给客户端。刚开始的时候直接是把图片存放到Tomcat的webapps下,但是,始终通过URL访问不到,再加上tomcat有的弊端,就是一定得重启才行。所以,讨论之后决定用静态的apache服务器实现算了。下面是具体的编写过程:

1、创建一个web工程fileUpload,然后把相应的jar包引入进去,如下:

2、编写struts的配置文件,struts-config.xml,你可以将其存放到src下,这样的话就不必在web.xml中进行配置啦,我的是直接放到了webcontent下,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>

	<action-mappings>
		<!-- 多文件上传 -->
		<action path="/uploadfiles" type="com.zlb.action.UploadAction" validate="false" />
	</action-mappings>
</struts-config>

3、编辑web.xml配置文件,如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>uploadFile</display-name>
  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

这时,你发现我对struts的配置文件的路径进行了引入。值得注意的还有一点,就是对action的URL进行定义时一定不能用”/*“,你可以用”*.do“或者”*.action“等,要不然的话你在执行上传的时候会报错,网上有好多关于这种情况的解答,想了解的朋友可以自己去看看

3、接下来就是比较重要的action的编写啦~~~~

在这里我就不把详细的代码贴出来了,就一步步的讲解一下吧:

// 创建磁盘工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存缓冲大小
factory.setSizeThreshold(Integer.parseInt(memorySize));

// 创建处理工具
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置最大允许的尺寸
int setFileSize = Integer.parseInt(sizeMax);
upload.setSizeMax(setFileSize);
// 设置临时目录
File file = new File(tempDir);

//因怕此目录可能不存在,所以先进行下判断
if(!file.exists()){
file.mkdir();
}

//先对request做下判断,如果无效,则直接返回
String contentType = request.getContentType();
if(contentType == null && "".equals(contentType)){
	out.print("File Upload Error");
	return;
}
// 解析

List<FileItem> fileItems = upload.parseRequest(request);Iterator<FileItem> iter = fileItems.iterator();for (; iter.hasNext();) {FileItem fileItem = (FileItem) iter.next();// 判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通表单字段则返回true,否则返回falseif
(fileItem.isFormField()) {// 当前是一个表单项out.print("form field : "+ fileItem.getFieldName() + ", "+ fileItem.getString());} else {// 当前是一个上传的文件String fileName = fileItem.getName();File fileDir = new File(photoDir + fileName);fileItem.write(fileDir);out.print(photoUrl
+ fileName);}




} 里面的各种参数都要自己进行设置,他们所代表的含义为:

private String tempDir="";//存储图片的临时目录
private String photoDir="";//照片目录
private String photoUrl="";//照片的URL
private String memorySize="";//内存缓冲大小
private String sizeMax="";//文件允许的最大值

至此,所有的代码都已完成。但是,如果出现并发情况下我们该怎么办呢?很多人都会想到使用多线程处理,我们这里就也加个线程池对其进行处理,代码编写如下:

ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool();

然后直接通过threadPool .execute()执行即可。此线程池表示有多少个任务就创建多少个线程,若是存在未使用的,则会重用之前的线程,若是线程的空闲时间到了60S,则它会自动对其进行回收,应该说这是创建线程池的首选吧!

好了,介绍就到这里,接下来问题就随之而来了。当把文件上传的代码放到此线程池中对其执行时,就会出现问题:

List<FileItem> fileItems = upload.parseRequest(request);“这一句怎么也通不过,要么就是报异常,具体问题请点击查看。

若有知道答案的还望告诉我一声,谢谢啦!

 

更多有关文件上传与下载的文章请点击

抱歉!评论已关闭.