东方部落: http://11144439.blog.51cto.com 

struts中上传文件功能小测试。这里jar是 2.5 版本。


  1. 项目结构图

wKiom1klDQiitWNMAABmryggfAs634.png


废话不多说,直接代码。



2. web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>struts2</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <filter>
    <filter-name>action2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>action2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

3.struts.xml配置

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

<struts>
	
	<!-- 启动动态方法匹配功能 -->
	<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
	<!-- 启用开发模式 -->
    <constant name="struts.devMode" value="true"/>
    <!-- 默认上传大小2M,   -->
    <constant name="struts.multipart.maxSize" value="104857600"/>
    
    
    <package name="user" extends="struts-default" namespace="/">
    	<!--动态方法配置 -->
    	<global-allowed-methods>regex:.*</global-allowed-methods>
    	
    	<action name="*_*" class="com.struts2.action.{1}" method="{2}">
    		<result name="success" type="redirect">
    			<param name="location">success.jsp</param>
   				<param name="parse">true</param>	
	   			<param name="uploadFileName">${uploadFileName}</param>
    		</result>
    		<result name="error" type="redirect">
    			<param name="location">error.jsp</param>
	   			<param name="uploadFileName">${uploadFileName}</param>
    		</result>
    		
    	</action>
    </package>
    
</struts>

4 TestUpload 上传功能具体实现

package com.struts2.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import org.apache.struts2.ServletActionContext;
/*
 * @auto :zws
 * @time 2017年5月24日 星期三
 * @method 文件上传功能
 *  注意: 前台上传文件 name 名称应该和后台保持一致 为 upload
 */

public class TestUpload {
	
	// 上传的文件二进制流
	private File upload;
	// 上传文件名称
	private String uploadFileName;
	// 上传文件类型
	private String uploadContentType;

	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}

	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public String fileUpload() throws IOException{
		
		InputStream stream = null;
		OutputStream out = null;
		File file = null;
		
		System.out.println(this.uploadContentType);
		// 判断上传类型 这里只能上传 图片格式
		if(!"p_w_picpath/jpeg".equals(this.uploadContentType)){
			return "error";
		}else{
			try {
				// 上传文件名后缀 . 的下标
				int lf = this.uploadFileName.lastIndexOf(".");
				// 截取上传文件后缀
				String str = this.uploadFileName.substring(lf);
				// 获取时间,毫秒计时
				long time = new Date().getTime();
				// 文件上传真实路径
				String realPath = ServletActionContext.getServletContext().getRealPath("/upload");
				// 创建文件,用来判断是否存在
				file = new File(realPath);
				//判断upload 文件夹是否存在
				if(!file.exists() && !file.isDirectory()){
					// 创建upload 文件夹
					file.mkdir();
				}
				/* 
				 * 写入数据的地址
				 * 	注意    1. 这里应该是文件绝对路径名称,而不是文件夹绝对路径名称
				 * 		2. 为了避免文件命名冲突,应该给上传文件重命名
				 */
				stream = new FileInputStream(upload);
				out = new FileOutputStream(realPath+"\\"+time+str);
				// 每次写512字节
				byte[] by = new byte[512];
				int len = 0;
				while (true) {
					if((len=stream.read(by))==-1){
						break;
					}else{
						out.write(by, 0, len);
					}
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}finally {
				out.close();
				stream.close();
			}
		}
		return "success";
	}
}

5. 前台页面 index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!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>Insert title here</title>
</head>
<body>
	
	<h1 style="text-align: center;">~~~~~~~~~~~~~上传文件测试~~~~~~~~~~~~~~~</h1>
	<!-- 注意 请求方式一定是 post   必须有 enctype="multipart/form-data"  -->
	<s:form action="TestUpload_fileUpload" method="post" enctype="multipart/form-data">
    	<s:file name="upload" label="图片"/>
	    <s:submit label="提交"/>
	</s:form>
</body>
</html>

6.上传成功页面 success.jsp

<%@ 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>Insert title here</title>
</head>
<body>
	<h1 style="text-align: center;">~~~~~~~~~~~~~ ${param.uploadFileName}上传成功!~~~~~~~~~~~~~~~</h1>
</body>
</html>

7.上传失败页面 error.jsp

<%@ 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>Insert title here</title>
</head>
<body>
	<h1 style="text-align: center;">~~~~~~~~~~~~~${param.uploadFileName}上传失败!~~~~~~~~~~~~~~~</h1>
</body>
</html>



注意:

    1.strtuts2 默认上传大小为2M,单位是字节,如需修改大小,配置为

这里修改为了 100M

<constant name="struts.multipart.maxSize" value="104857600"/>

     2.前台页面 form中

        请求方式为 :post

          里面属性必须有:enctype="multipart/form-data"

    3.上传过滤,可以根据自己需求来拦截

    4.上传为了出现名称一直,应该重新命名



下载功能测试 用到的jar 为2.3,为什么和上面上传不一样,下面会讲到。

  1. TestDown 下载功能测试功能

package com.struts2.action;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.apache.struts2.ServletActionContext;

public class TestDown {
	
	private InputStream input;
	
	public InputStream getInput() {
		return input;
	}

	public void setInput(InputStream input) {
		this.input = input;
	}

	public String fileDown() throws IOException{
	    try {
	        //下载测试,路径下要有文件。根据自己的选择。
		String realPath = ServletActionContext.getServletContext().getRealPath("/upload/1495607799619.jpg");
		input = new FileInputStream(realPath);
	    } catch (FileNotFoundException e) {
		e.printStackTrace();
	    }
	    return "down";
	}
}

2. struts.xml 配置

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

<struts>
	<!-- 启用开发模式 -->
    <constant name="struts.devMode" value="true"/>

    <package name="down" extends="struts-default" namespace="/file">
	  <result-types>
	  		<!-- 用于处理下载文件点击取消时报出异常问题 -->
			<result-type name="streamx" class="com.sunspoter.lib.web.struts2.dispatcher.StreamResultX">
			</result-type>
		</result-types>
	   <action name="downs" class="com.struts2.action.TestDown" method="fileDown">
    		<result name="down" type="streamx">
    			<!-- 下载文件格式 -->
    			<param name="contentType">p_w_picpath/jpeg</param>
			    <!-- 下载文件流 -->
			    <param name="inputName">input</param>
			    <!-- inline:在线打开
			    	p_w_upload :以附件形式存储
			    	filename : 显示在客户端的名称
			     -->
			    <param name="contentDisposition">p_w_upload;filename="a.jpg"</param>
			    <param name="bufferSize">1024</param>
    		</result>
    	</action>
    </package>
</struts>

3.web.xml 配置  2.3和2.5 用到的filter-class不一样

在这里是2.3

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>struts2</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <filter>
    <filter-name>action2</filter-name>
    <!-- <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> -->
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>action2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

网页直接输入地址    localhost:端口号/项目名/file/downs   既可测试下载结果。



这里说下 下载为什么没有用2.5测试

  1. 首先测试用的是2.5,不过在下载文件点击取消时候,后台会报错,然后在网上搜了结果。说是

    虽然取消了,文件关闭了流,但是Socket没有中断。所以会报错。网上给出了如下解决方案

     <!-- 添加这段代码   开始  -->
    <result-types>
	<!-- 用于处理下载文件点击取消时报出异常问题 -->
		<result-type name="streamx" class="com.sunspoter.lib.web.struts2.dispatcher.StreamResultX">
		</result-type>
	</result-types>
     <!-- 添加这段代码   结束  -->	
	
	
	
	
	   <action name="downs" class="com.struts2.action.TestDown" method="fileDown">
    		
    		<!--  把这里的stream 改成  streamx  -->
    		
    		<result name="down" type="streamx">
    			<!-- 下载文件格式 -->
    			<param name="contentType">p_w_picpath/jpeg</param>
			    <!-- 下载文件流 -->
			    <param name="inputName">input</param>
			    <!-- inline:在线打开
			    	p_w_upload :以附件形式存储
			    	filename : 显示在客户端的名称
			     -->
			    <param name="contentDisposition">p_w_upload;filename="a.jpg"</param>
			    <param name="bufferSize">1024</param>
    		</result>
    	</action>
    </package>

2.并下载  struts2-sunspoter-stream-1.2.jar 包,放在lib中


进过测试,和想象中的一样,仍然报错。于是我用2.3测试,结果没有报错。这就说明了网友他们用的是2.3版本,而对 struts2-sunspoter-stream-1.2.jar 显然不兼容2.5版本的struts2.

既然是版本不兼容,有没有更高版本的struts2-sunspoter-stream-x.x.jar?在网上搜了许久仍没有发现。



struts2-sunspoter-stream-1.2.jar 包在附件中,需要的可以自己下载,注意,我上传jar包时,说是非发数据,后缀我改成jpg了,下载后改回jar。