java架构搭建(六)--struts2上传和下载文件(使用到拦截器)

我把这篇功能放到了java架构搭建这个系列中。
其实struts2的上传和下载和本系列关系不大,但是在架构搭建中,上传和下载是必然会遇到的。
而且能封装的自然封装,这样调用或者给其他程序员提供参考代码,将会大大缩短开发时间。
以前我写过上传和下载的功能,当时使用commons-fileupload-xxx.jar实现的。
struts2的上传和下载其实也是对这个包功能的封装,而且做得很好,使用很方便,包括对文件类型
和文件大小的限制都可以配置实现。所以考虑把它写到架构知识系列中。
在我的实例中,除了上传和下载,我还设计了一张保存文件信息的表(在实际中肯定会有这么一张表的)。
整个例子的代码我都做过实际测试,总体感觉还不错。


后面还设计到图片的上传和下载,把图片单拿出来,是因为图片在上传后和下载前需要有预览功能,
而且我打算在这个功能中实现把图片写入数据库的blob字段中。获取图片也是从数据库先获取,然后
在展示。这个功能设计到读写blob。所以放到下篇再讲。

本篇可能会用到以前写的工具类,在这就不保证全部贴出了,那个不影响整体功能的。

看看效果:







对错误的提示功能:


--------------------------------------------------------------------------------------------------------------------------------------------

大小超过限制:


文件类型不符合要求:



##################################################################

1,数据库设计file_vo表结构脚本.sql

/*
SQLyog 企业版 - MySQL GUI v7.14 
MySQL - 5.1.57-community : Database - myact
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

CREATE DATABASE /*!32312 IF NOT EXISTS*/`myact` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `myact`;

/*Table structure for table `file_vo` */

DROP TABLE IF EXISTS `file_vo`;

CREATE TABLE `file_vo` (
  `file_id` varchar(32) NOT NULL COMMENT '主键',
  `file_name` varchar(150) DEFAULT NULL COMMENT '名称,例a.txt',
  `file_suffix` varchar(32) DEFAULT NULL COMMENT '后缀,例.txt',
  `file_webpath` varchar(200) DEFAULT NULL COMMENT '在webapp下的路径,例tempfiles/upload',
  `file_phydir` varchar(150) DEFAULT NULL COMMENT '在物理硬盘上的路径,例D:\\app',
  `file_size` varchar(32) DEFAULT NULL COMMENT '文件大小,单位KB',
  `file_contenttype` varchar(150) DEFAULT NULL COMMENT '文件contenttype',
  `foreign_key_id` varchar(32) DEFAULT NULL COMMENT '和其他表关联的id',
  `create_time` varchar(32) DEFAULT NULL COMMENT '创建时间',
  `last_edit_time` varchar(32) DEFAULT NULL COMMENT '最后更改时间',
  `creator` varchar(150) DEFAULT NULL COMMENT '创建人',
  `owner_id` varchar(150) DEFAULT NULL COMMENT '拥有人',
  `isvalid` varchar(10) DEFAULT NULL COMMENT '是否有效(1有效,0无效)',
  `imagedata` longblob COMMENT '图片数据',
  `bigtextdata` longtext COMMENT '大文本数据',
  `bak1` varchar(200) DEFAULT NULL COMMENT '未定用途1',
  `bak2` varchar(200) DEFAULT NULL COMMENT '未定用途2',
  PRIMARY KEY (`file_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;

FileVo:

package org.act.upload.bean;

import java.sql.Blob;
import java.sql.Clob;
//import com.mysql.jdbc.Blob;
//import com.mysql.jdbc.Clob;

public class FileVo {

	private String file_id; 
	private String file_name; 
	private String file_suffix; 
	private String file_webpath; 
	private String file_phydir; 
	private String file_size; 
	private String file_contenttype; 
	private String foreign_key_id; 
	private String create_time; 
	private String last_edit_time; 
	private String creator; 
	private String owner_id; 
	private String isvalid; 
	private Blob imagedata; 
	private Clob bigtextdata;
	
	private String bak1; //备用字段
	private String bak2;
	
	public String getFile_id() {
		return file_id;
	}
	public void setFile_id(String file_id) {
		this.file_id = file_id;
	}
	public String getFile_name() {
		return file_name;
	}
	public void setFile_name(String file_name) {
		this.file_name = file_name;
	}
	public String getFile_suffix() {
		return file_suffix;
	}
	public void setFile_suffix(String file_suffix) {
		this.file_suffix = file_suffix;
	}
	public String getFile_webpath() {
		return file_webpath;
	}
	public void setFile_webpath(String file_webpath) {
		this.file_webpath = file_webpath;
	}
	public String getFile_phydir() {
		return file_phydir;
	}
	public void setFile_phydir(String file_phydir) {
		this.file_phydir = file_phydir;
	}
	public String getFile_size() {
		return file_size;
	}
	public void setFile_size(String file_size) {
		this.file_size = file_size;
	}
	public String getFile_contenttype() {
		return file_contenttype;
	}
	public void setFile_contenttype(String file_contenttype) {
		this.file_contenttype = file_contenttype;
	}
	public String getForeign_key_id() {
		return foreign_key_id;
	}
	public void setForeign_key_id(String foreign_key_id) {
		this.foreign_key_id = foreign_key_id;
	}
	public String getCreate_time() {
		return create_time;
	}
	public void setCreate_time(String create_time) {
		this.create_time = create_time;
	}
	public String getLast_edit_time() {
		return last_edit_time;
	}
	public void setLast_edit_time(String last_edit_time) {
		this.last_edit_time = last_edit_time;
	}
	public String getCreator() {
		return creator;
	}
	public void setCreator(String creator) {
		this.creator = creator;
	}
	public String getOwner_id() {
		return owner_id;
	}
	public void setOwner_id(String owner_id) {
		this.owner_id = owner_id;
	}
	public String getIsvalid() {
		return isvalid;
	}
	public void setIsvalid(String isvalid) {
		this.isvalid = isvalid;
	}
	public Blob getImagedata() {
		return imagedata;
	}
	public void setImagedata(Blob imagedata) {
		this.imagedata = imagedata;
	}
	public Clob getBigtextdata() {
		return bigtextdata;
	}
	public void setBigtextdata(Clob bigtextdata) {
		this.bigtextdata = bigtextdata;
	}
	@Override
	public String toString() {
		return "FileVo [file_id=" + file_id + ", file_name=" + file_name
				+ ", file_suffix=" + file_suffix + ", file_webpath="
				+ file_webpath + ", file_phydir=" + file_phydir
				+ ", file_size=" + file_size + ", file_contenttype="
				+ file_contenttype + ", foreign_key_id=" + foreign_key_id
				+ ", create_time=" + create_time + ", last_edit_time="
				+ last_edit_time + ", creator=" + creator + ", owner_id="
				+ owner_id + ", isvalid=" + isvalid + ", imagedata="
				+ imagedata + ", bigtextdata=" + bigtextdata
				+ ", getFile_id()=" + getFile_id() + ", getFile_name()="
				+ getFile_name() + ", getFile_suffix()=" + getFile_suffix()
				+ ", getFile_webpath()=" + getFile_webpath()
				+ ", getFile_phydir()=" + getFile_phydir()
				+ ", getFile_size()=" + getFile_size()
				+ ", getFile_contenttype()=" + getFile_contenttype()
				+ ", getForeign_key_id()=" + getForeign_key_id()
				+ ", getCreate_time()=" + getCreate_time()
				+ ", getLast_edit_time()=" + getLast_edit_time()
				+ ", getCreator()=" + getCreator() + ", getOwner_id()="
				+ getOwner_id() + ", getIsvalid()=" + getIsvalid()
				+ ", getImagedata()=" + getImagedata() + ", getBigtextdata()="
				+ getBigtextdata() + ", getClass()=" + getClass()
				+ ", hashCode()=" + hashCode() + ", toString()="
				+ super.toString() + "]";
	}
	public String getBak1() {
		return bak1;
	}
	public void setBak1(String bak1) {
		this.bak1 = bak1;
	}
	public String getBak2() {
		return bak2;
	}
	public void setBak2(String bak2) {
		this.bak2 = bak2;
	}
}

FileVo.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
	    <class name="org.act.upload.bean.FileVo" table="file_vo" >
        <id name="file_id" type="java.lang.String">
            <column name="file_id" length="32" />
            <generator class="assigned" />
        </id>
        <property name="file_name" type="java.lang.String">
            <column name="file_name" length="150" />
        </property>
        <property name="file_suffix" type="java.lang.String">
            <column name="file_suffix" length="32" />
        </property>
        <property name="file_webpath" type="java.lang.String">
            <column name="file_webpath" length="200" />
        </property>
        <property name="file_phydir" type="java.lang.String">
            <column name="file_phydir" length="150" />
        </property>
        
        <property name="file_size" type="java.lang.String">
            <column name="file_size" length="32" />
        </property>
        <property name="file_contenttype" type="java.lang.String">
            <column name="file_contenttype" length="150" />
        </property>
        <property name="foreign_key_id" type="java.lang.String">
            <column name="foreign_key_id" length="32" />
        </property>
        <property name="create_time" type="java.lang.String">
            <column name="create_time" length="32" />
        </property>
        <property name="last_edit_time" type="java.lang.String">
            <column name="last_edit_time" length="32" />
        </property>
        
        <property name="creator" type="java.lang.String">
            <column name="creator" length="150" />
        </property>
        <property name="owner_id" type="java.lang.String">
            <column name="owner_id" length="150" />
        </property>
        <property name="isvalid" type="java.lang.String">
            <column name="isvalid" length="10" />
        </property>
        <property name="imagedata" type="java.sql.Blob">
            <column name="imagedata"/>
        </property>
        <property name="bigtextdata" type="java.sql.Clob">
            <column name="bigtextdata"/>
        </property>
        
        <property name="bak1" type="java.lang.String">
            <column name="bak1" length="200" />
        </property>
        <property name="bak2" type="java.lang.String">
            <column name="bak2" length="200" />
        </property>
        
    </class>
</hibernate-mapping>

2,spring配置,以及dao方法。

context_upload.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

	<bean id="fileDao" parent="transactionProxyTemplate">
		<property name="target">
			<bean class="org.act.upload.dao.impl.FileDaoImpl">
				<property name="sessionFactory">
					<ref bean="sessionFactory"/>
				</property>
			</bean>
		</property>
		<property name="proxyInterfaces">
			<value>org.act.upload.dao.FileDao</value>
		</property>
	</bean>
</beans>

FileDao.java

package org.act.upload.dao;

import java.util.List;

import org.act.upload.bean.FileVo;

public interface FileDao {
	public List queryFile(String file_name);
	public FileVo queryFileById(String file_id);
	public void addFileVo(FileVo vo);
}

FileDaoImpl.java

package org.act.upload.dao.impl;

import java.util.List;

import org.act.upload.bean.FileVo;
import org.act.upload.dao.FileDao;
import org.base.MyHibernateDao;

public class FileDaoImpl  extends MyHibernateDao implements FileDao{

	public List queryFile(String file_name) {
		List list=null;
		if(file_name==null||file_name.trim().equals("")){
			System.out.println("参数file_name为空,查询所有值。");
			String hql="from FileVo";
			list=this.queryListHql(hql);
		}else{
			String hql="from FileVo f where f.file_name like '%"+file_name.trim()+"%'";
			list=this.queryListHql(hql);
		}
		return list;
	}
	
	public FileVo queryFileById(String file_id) {
		FileVo vo=new FileVo();
		List list=null;
		if(file_id==null||file_id.trim().equals("")){
			System.out.println("参数file_id为空!");
		}else{
			String hql="from FileVo f where f.file_id='"+file_id.trim()+"'";
			list=this.queryListHql(hql);
			if(list!=null){
				vo=(FileVo)list.get(0);
			}
		}
		return vo;
	}
	public void addFileVo(FileVo vo){
		if(vo!=null){
			this.saveHql(vo);
		}
	}
}

3,struts配置以及action(注意struts是重点!)

struts_upload.xml

<?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.i18n.encoding" value="utf8" />
	<package name="file" namespace="/file" extends="struts-default">
		
		<!-- 使用struts2标签和拦截器实现上传 -->
		<action name="goUploadStruts">
			<result>/jsp/upload/upload_struts.jsp</result>
		</action>
		<action name="uploadStruts" class="org.act.upload.action.UploadAction">
			<result name="input">/jsp/upload/upload_struts.jsp</result>
			<result name="error">/jsp/upload/upload_struts_error.jsp</result>
			<result name="success">/jsp/upload/download_struts.jsp</result>
			<interceptor-ref name="fileUpload">
			    <!--单个文件允许的大小 单位是比特B(1M=1024KB;1KB=1024B),10M=10*1024*1024=10485760 -->
				<param name="maximumSize">10485760</param>
				
				<!-- 允许上传的文件类型,可以到Tomcat_home/conf下的web.xml文件中找到所有文件类型的类型名,逗号隔开 -->
				<param name="allowedTypesSet">
				application/vnd.ms-excel,text/plain,image/png,application/pdf
				,image/x-portable-bitmap,audio/x-mpeg,image/jpeg,text/plain,application/java-archive,text/html,image/gif,application/msword
				</param>
				
				<!-- application/zip,容许文件类型分别为zip,xls,txt,png,pdf,pbm,mp3,jpg,java,jar,html,gif,doc -->
				<!-- application/octet-stream 对应exe-->
			</interceptor-ref>
			<interceptor-ref name="defaultStack" />
		</action>
		
		
		
		
		<action name="downloadFile" class="org.act.upload.action.DownloadAction">
			<result name="success" type="stream">
				<param name="contentDisposition">attachment;filename="${fileName}"</param>
				<!-- 获取InputStream的get方法 -->
				<param name="inputName">inputStreamOfFile</param>
				<!-- 下载文件的缓冲大小 -->
                <param name="bufferSize">4096</param>
				
			</result>
		</action>
		
		
		<!-- 业务上的查询 -->
		<action name="queryById" class="org.act.upload.action.QueryFileAction" method="queryById">
			<result name="success">/jsp/upload/download_struts.jsp</result>
		</action>
		<action name="queryByName" class="org.act.upload.action.QueryFileAction">
			<result name="success">/jsp/upload/download_struts.jsp</result>
		</action>
		
	</package>
</struts>

上传 UploadAction

package org.act.upload.action;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import oracle.sql.BLOB;

import org.act.upload.bean.FileVo;
import org.act.upload.dao.FileDao;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import org.base.MyBaseAction;
import org.base.pk.UUIDHexGenerator;
import org.base.util.DateUtil;
import org.base.util.PropertiesUtil;
import org.hibernate.Hibernate;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 使用struts2实现上传
 * @author lushuaiyin
 *
 */
public class UploadAction extends MyBaseAction {
	
	private static final long serialVersionUID = 1L;
	private File[] upload;// 上传文件
	private String[] uploadContentType; // 文件的内容类型
	private String[] uploadFileName; // 上传文件名
	private FileDao fileDao;
	
	public String execute() throws Exception {
		try {
			String defPath="";
			defPath=(PropertiesUtil.readProperty("uploadFilePath")==null||PropertiesUtil.readProperty("uploadFilePath").trim().equals(""))?"":
				PropertiesUtil.readProperty("uploadFilePath").trim();
			
			String targetDirectory = ServletActionContext.getServletContext().getRealPath(File.separator + defPath);// 获得路径
			for (int i = 0; i < upload.length; i++) {
				FileVo vo=new FileVo();
				String fileName = uploadFileName[i];// 上传的文件名
				String type = uploadContentType[i];// 文件类型//application/x-zip-compressed
				String id = (String) UUIDHexGenerator.generate();//产生主键id
				String fileSuffix=getFileSuffix(fileName);//后缀
				
				String idName = id+getFileSuffix(fileName);// 主键id+文件的后缀
				File target = new File(targetDirectory, idName);
				FileUtils.copyFile(upload[i], target);//上传文件到服务器
				
				//这里一般也需要写库,记录文件的一些信息。如果是图片,根据需要可以写入blob
				//vo写库
				vo.setFile_id(id);
				vo.setFile_name(fileName);
				vo.setFile_suffix(fileSuffix);
				String webpath=defPath+"/"+id+fileSuffix;
				vo.setFile_webpath(webpath);
				vo.setFile_phydir(targetDirectory);
				Long size=upload[i].length();
				Double dsize=new Double(size);
				vo.setFile_size(String.valueOf(dsize/1024));//单位KB
				vo.setFile_contenttype(type);
				String nowTime=DateUtil.getDateStrWithSecond();
				vo.setCreate_time(nowTime);
				vo.setLast_edit_time(nowTime);
				String userId=this.getHttpSession().getAttribute("userId")!=null?(String)this.getHttpSession().getAttribute("userId"):"";
				vo.setCreator(userId);
				vo.setOwner_id(userId);
				vo.setIsvalid("1");
//				vo.setImagedata(BLOB.empty_lob());
				vo.setImagedata(Hibernate.createBlob(new byte[0]));
				vo.setBigtextdata(Hibernate.createClob(""));
				
				System.out.println(vo.toString());
				fileDao.addFileVo(vo);
				

			}

		} catch (Exception e) {
			e.printStackTrace();
			addActionError(e.getMessage());

			return INPUT;
		}

		return SUCCESS;

	}

	public File[] getUpload() {
		return upload;
	}

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

	public String[] getUploadContentType() {
		return uploadContentType;
	}

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

	public String[] getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String[] uploadFileName) {
		this.uploadFileName = uploadFileName;
	}
    
	//获取文件后缀
	public static String getFileSuffix(String fileName) {
		return fileName.substring(fileName.lastIndexOf(".")).trim();
	}

	public FileDao getFileDao() {
		return fileDao;
	}

	public void setFileDao(FileDao fileDao) {
		this.fileDao = fileDao;
	}

}

查询列表QueryFileAction

package org.act.upload.action;

import java.util.List;

import org.act.upload.dao.FileDao;
import org.apache.struts2.ServletActionContext;
import org.base.MyBaseAction;
import org.act.upload.bean.FileVo;

/**
 * 文件的查询
 * @author lushuaiyin
 *
 */
public class QueryFileAction extends MyBaseAction {
	
	private static final long serialVersionUID = 1L;
	private FileDao fileDao;
	
	public String execute() throws Exception {
		String filename = ServletActionContext.getRequest().getParameter("filename");
		List fileList=fileDao.queryFile(filename);
		ServletActionContext.getRequest().setAttribute("fileList", fileList);
		return SUCCESS;
	}
	
	public String queryById() throws Exception {
		String file_id = ServletActionContext.getRequest().getParameter("file_id");
		if(file_id==null||file_id.trim().equals("")){
			System.out.println("未获取到文件参数!");
		}else{
			FileVo fileVO=null;
			if(fileDao.queryFileById(file_id)!=null){
				fileVO=fileDao.queryFileById(file_id);
				ServletActionContext.getRequest().setAttribute("fileVO", fileVO);
			}
		}
		
		return SUCCESS;
	}
	
	public FileDao getFileDao() {
		return fileDao;
	}

	public void setFileDao(FileDao fileDao) {
		this.fileDao = fileDao;
	}
}


下载DownloadAction(注意和struts配置项对应)

package org.act.upload.action;

import java.io.InputStream;

import org.act.upload.bean.FileVo;
import org.act.upload.dao.FileDao;
import org.apache.struts2.ServletActionContext;
import org.base.util.PropertiesUtil;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 下载文件
 * @author lushuaiyin
 *
 */
public class DownloadAction extends ActionSupport {
	private static final long serialVersionUID = 1L;
	private String fileName;//文件的实际名称(上传前的名称),供下载时弹出框使用
	private String fileWebName;//在服务器上存放的实际名称 (我使用的是id+文件实际后缀)
	private FileDao fileDao;
	private FileVo fileVO;

	public void setFileName() {
		this.fileName = getFileVO().getFile_name();
	}

	/**
	 * 获取文件下载时的名称,在弹出框里使用。
	 * 在struts配置文件中指定了<param name="contentDisposition">attachment;filename="${fileName}"</param>
	 * 所以会调用getFileName()方法
	 * @return
	 */
	public String getFileName(){
		return getFileVO().getFile_name();
	}

	/**
	 * 获取下载流。在struts配置文件中指定了<param name="inputName">inputStreamOfFile</param>
	 * 所以会调用getInputStreamOfFile()方法
	 * @return
	 */
	public InputStream getInputStreamOfFile() {
		String defPath=(PropertiesUtil.readProperty("uploadFilePath")==null||PropertiesUtil.readProperty("uploadFilePath").trim().equals(""))?"":
			PropertiesUtil.readProperty("uploadFilePath").trim();
		String filepath="/" + defPath + "/" + getFileWebName();
		return ServletActionContext.getServletContext().getResourceAsStream(filepath);
	}
	
	//在服务器上存放的实际名称
	public String getFileWebName() {
		return getFileVO().getFile_id().trim()+getFileVO().getFile_suffix().trim();
	}

	public void setFileWebName() {
		this.fileWebName = getFileVO().getFile_id().trim()+getFileVO().getFile_suffix().trim();;
	}
	@Override
	public String execute() throws Exception {
		//在请求下载时,程序先走execute方法,这样我们先给FileVO赋值;开始下载后,拦截器需要知道文件名和文件类型(在struts文件中param配置从哪个方法获取)
		//这样拦截器会从指定的方法中获取文件流,文件名,文件类型。
		System.out.println("hereeeeeeeeeeeeeeeeeeeeeeeeeee");
		String file_id = ServletActionContext.getRequest().getParameter("file_id");
		if(file_id==null||file_id.trim().equals("")){
			System.out.println("未获取到文件参数!");
		}else{
			this.setFileVO(fileDao.queryFileById(file_id));
		}
		return SUCCESS;
	}

	public FileDao getFileDao() {
		return fileDao;
	}

	public void setFileDao(FileDao fileDao) {
		this.fileDao = fileDao;
	}

	public FileVo getFileVO() {
		return fileVO;
	}

	public void setFileVO(FileVo fileVO) {
		this.fileVO = fileVO;
	}

	
}


4,配置上传路径

这个写到resource.properties中了,你可以把这个写死

#uploadFilePath is under webapp
uploadFilePath=tempfiles/upload

5,jsp页面

这部分其实有个上传多个文件的逻辑实现。本人用jquery实现的(见上图中可以多文件上传),写的很粗糙,不错效果还是不错。


上传页面upload_struts.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@page import="java.util.*"%>
<% 
String path = request.getContextPath();
%>
<html>
	<head>
	    <meta name="author" content="lushuaiyin">
	    <meta name="description" content="http://blog.csdn.net/lushuaiyin">
	    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>uploadFile</title>
		<link rel="stylesheet" type="text/css" href="<%=path%>/resource/css/table.css" />
		<script src="<%=path%>/script/jquery-1.7.1.min.js" type="text/javascript"></script>	
	</head>
	
<body>

<table align="center" width="80%" height="120px">
    <tr>
		<td>
			采用stuts2标签和拦截器实现
		</td>
	</tr>
	<tr>
		<td>
		    <s:fielderror cssStyle="color:green" />
			<s:actionmessage cssStyle="color:blue" />
			<s:actionerror cssStyle="color:red" />
		</td>
		
	</tr>
</table>
<s:form  id="form1" name="form1" action="/file/uploadStruts.action" theme="simple" method="post"
			enctype="multipart/form-data">

		<table id="mytable1" align="center" width="80%" class="table1" style="border-bottom-style:none">
			<tr>
				<td>
					上传文件
				</td>
				<td>
					<input type="file" name="upload" value="" />
				</td>
				<td>
					<input type="button" value="继续添加文件" οnclick="addFile(this)">
				</td>
			</tr>

		</table>
		<table align="center" width="80%" class="table1" style="border-top-style:none">
			<tr>
				<td>
					<input type="button" value="确认" οnclick="tijiao()">
				</td>
				<td>
					
				</td>
				<td>
					<input type="button" value="重置" οnclick="clearAll()">
				</td>
			</tr>
		</table>
</s:form>

	</body>
</html>
<script type="text/javascript">


function addFile(td){
	var tbody=$(td).parent().parent().parent().parent();
	
	var tdp=$(td).parent().parent();
	var v1=$(tdp).children()[1];
	var inputfile=$(v1).children()[0];
	if(inputfile.value==null||inputfile.value==''){
		alert("请选择文件!");
	}else{
		//alert(vfile2.outerHTML);
		var tdbutton=$(tdp).children().last();//已有的tr这一行需要把button清除
		$(tdbutton).html("");
		//添加新的一行
		var htmlStr="<tr><td>上传文件</td><td><input type=\"file\" name=\"upload\" value=\"\" /></td>"
		+"<td><input type=\"button\" value=\"继续上传\" οnclick=\"addFile(this)\"></td></tr>";
		$(tbody).append(htmlStr);
	}
	
}

function clearAll(){
	var htmlStr="<tr><td>上传文件</td><td><input type=\"file\" name=\"upload\" value=\"\" /></td>"
		+"<td><input type=\"button\" value=\"继续上传\" οnclick=\"addFile(this)\"></td></tr>";
	$("#mytable1").html(htmlStr);
}

function tijiao(){
	var size=$(":file").size();
	var errorNumber=0;
	$(":file").each(function(i){
		//alert(this.value);
		if(this.value==null||this.value==''){
			errorNumber++;
		}
	});
	if(errorNumber>=1){
		alert("请选择一个文件!");
	}else{
		alert("开始上传...");
		var form1=$("#form1");
		form1.action="<%=path%>/file/uploadStruts.action";
		$("#form1").submit();
	}
}
</script>

upload_struts_error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@page import="java.util.*"%>
<% 
String path = request.getContextPath();
%>
<html>
	<head>
	    <meta name="author" content="lushuaiyin">
	    <meta name="description" content="http://blog.csdn.net/lushuaiyin">
	    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>uploadFile</title>
		<link rel="stylesheet" type="text/css" href="<%=path%>/resource/css/table.css" />
		<script src="<%=path%>/script/jquery-1.7.1.min.js" type="text/javascript"></script>	
	</head>
	
<body>

<table align="center" width="80%">
    <tr>
		<td>
			采用stuts2标签和拦截器实现,错误原因:
		</td>
	</tr>
	<tr>
		<td>
			<s:fielderror cssStyle="color:red" />
			<s:actionmessage/>
			<s:actionerror/>
		</td>
	</tr>
</table>


	</body>
</html>

下载页面download_struts.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page import="java.util.*"%>
<%@ page import="org.act.upload.bean.FileVo"%>
<% 
String path = request.getContextPath();
%>
<% 
List list=null;
if(request.getAttribute("fileList")!=null){
	list=(List)request.getAttribute("fileList");
}
%>
<html>
	<head>
	    <meta name="author" content="lushuaiyin">
	    <meta name="description" content="http://blog.csdn.net/lushuaiyin">
	    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>uploadFile</title>
		<link rel="stylesheet" type="text/css" href="<%=path%>/resource/css/table.css" />
		<script src="<%=path%>/script/jquery-1.7.1.min.js" type="text/javascript"></script>	
	</head>
	<body>
	<input type="hidden" value="<%=path%>" id="path">
	<table  align="center" width="80%" class="table2">
			  <tr>
			    <td>文件名:</td>
			    <td><input id="filename" name="filename" type="text" value="" /></td>
			  </tr>
			   <tr>
			    <td><input type="button" value="查询" οnclick="chaxunfile()"/></td>
			    <td><input type="button" value="取消" οnclick="javascript:filename.value=''"/></td>
			  </tr>	
		</table>
		<table id="mytable1" align="center" width="80%" class="table1">
			  <tr>
			    <th></th>
			    <th>文件名</th>
			    <th>文件contenttype</th>
			    <th>大小(单位KB)</th>
			    <th>操作</th>
			  </tr>
			  <% 
			  if(list!=null){
				
			      for(int i=0;i<list.size();i++){
			    	  FileVo vo=(FileVo)list.get(i);
			    	  String file_id="",file_name="",file_contenttype="",file_size="";
			    	  file_id=vo.getFile_id()==null?"":vo.getFile_id().trim();
			    	  file_name=vo.getFile_name()==null?"":vo.getFile_name().trim();
			    	  file_contenttype=vo.getFile_contenttype()==null?"":vo.getFile_contenttype().trim();
			    	  file_size=vo.getFile_size()==null?"0":vo.getFile_size().trim();
			    	 if(i%2==0){
			    		 %>
			  <tr class="interval">
			   <td><input type="hidden" value="<%=file_id%>" id="<%=file_id%>"></td>
			    <td><%=file_name%></td>
			    <td><%=file_contenttype%></td>
			    <td><%=file_size%></td>
			    <td><a href="javascript:void(0)" οnclick="downloadfile('<%=file_id%>')">下载文件</a></td>
			  </tr>
			    		 
			    		 <% 
			    	 }else{
			    		 %>
			   <tr>
			    <td><input type="hidden" value="<%=file_id%>" id="<%=file_id%>"></td>
			    <td><%=file_name%></td>
			    <td><%=file_contenttype%></td>
			    <td><%=file_size%></td>
			    <td><a href="javascript:void(0)" οnclick="downloadfile('<%=file_id%>')">下载文件</a></td>
			  </tr>		 
			    		 <%
			    	 } 
			      }
			  }
			  %>
		</table>
	</body>
</html>

<script type="text/javascript">
var path=document.getElementById("path").value;

//下载文件
function downloadfile(file_id){
	var url=path+"/file/downloadFile.action?file_id="+file_id;
	window.location.href=url;
}


function queryById(file_id){
	var url=path+"/file/queryById.action?file_id="+file_id;
	window.location.href=url;
}

function chaxunfile(){
	var filename=document.getElementById("filename").value;
	var url=path+"/file/queryByName.action?filename="+filename;
	window.location.href=url;
}
</script>


############

注意:



关于上传是struts2拦截器判断是否符合上传条件的返回信息。
(本例在做测试时,把zip类型从拦截器去掉)
如果是文件类型不符合要求,返回的信息需要使用标签
<s:fielderror cssStyle="color:green" />


如果是文件大小不符合要求,返回的信息需要使用标签
<s:actionmessage cssStyle="color:blue" />

<s:actionerror cssStyle="color:red" />



在上传页面,其实用不用struts的form和file标签(或者其他的标签)都无所谓。
使用原生的html也可以的。但是对于拦截器返回的错误信息,就必须使用
struts2的自定义标签。否则你是回去不到错误信息的。


值得注意的是,我在实际中没有配置exe类型,按理说应该被拦截器拦截的,应该有错误信息提示的。

但是实际结果却是能正常上传!这个原因还是没找到,具体在使用的时候,不能盲目相信文档,还是要自己亲自做测试才行。


网上搜了下,见对文件类型限制有使用allowedTypes这个参数的,我改成这个参数后,可以正常限制不符合要求的文件类型。

也有说还可以换成allowedExtensions,我试了下,和allowedTypesSet一样,没起作用。原因只能看源码了。


上面struts配置文件struts_upload.xml改成如下:

<?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.i18n.encoding" value="utf8" />
	<package name="file" namespace="/file" extends="struts-default">
		
		<!-- 使用struts2标签和拦截器实现上传 -->
		<action name="goUploadStruts">
			<result>/jsp/upload/upload_struts.jsp</result>
		</action>
		<action name="uploadStruts" class="org.act.upload.action.UploadAction">
			<result name="input">/jsp/upload/upload_struts.jsp</result>
			<result name="error">/jsp/upload/upload_struts_error.jsp</result>
			<result name="success">/jsp/upload/download_struts.jsp</result>
			<interceptor-ref name="fileUpload">
			    <!--单个文件允许的大小 单位是比特B(1M=1024KB;1KB=1024B),10M=10*1024*1024=10485760 -->
				<param name="maximumSize">10485760</param>
				
				<!-- 允许上传的文件类型,可以到Tomcat_home/conf下的web.xml文件中找到所有文件类型的类型名,逗号隔开 application/vnd.ms-excel, -->
				<!--
				<param name="allowedTypesSet">
				text/plain,image/png,application/pdf
				,image/x-portable-bitmap,audio/x-mpeg,image/jpeg,text/plain,application/java-archive,text/html,image/gif,application/msword
				</param>
				-->
				<!-- application/zip,容许文件类型分别为zip,xls,txt,png,pdf,pbm,mp3,jpg,java,jar,html,gif,doc -->
				<!-- application/octet-stream 对应exe-->
				
				
				<!-- 允许上传的文件类型,可以到Tomcat_home/conf下的web.xml文件中找到所有文件类型的类型名,逗号隔开 application/vnd.ms-excel, -->
				
				<param name="allowedTypes">
				text/plain,image/png,application/pdf
				,image/x-portable-bitmap,audio/x-mpeg,image/jpeg,text/plain,application/java-archive,text/html,image/gif,application/msword
				</param>
				
				<!-- application/zip,容许文件类型分别为zip,xls,txt,png,pdf,pbm,mp3,jpg,java,jar,html,gif,doc -->
				<!-- application/octet-stream 对应exe-->
				
				
				
				<!-- 允许后缀名为png,bmp,jpg,doc,xls的文件上传 --> 
				<!--    
				<param name="allowedExtensions">  
				    png,bmp,jpg,doc,xls  
				</param> 
				-->
				
			</interceptor-ref>
			<interceptor-ref name="defaultStack" />
		</action>
		
		
		
		
		<action name="downloadFile" class="org.act.upload.action.DownloadAction">
			<result name="success" type="stream">
				<param name="contentDisposition">attachment;filename="${fileName}"</param>
				<!-- 获取InputStream的get方法 -->
				<param name="inputName">inputStreamOfFile</param>
				<!-- 下载文件的缓冲大小 -->
                <param name="bufferSize">4096</param>
				
			</result>
		</action>
		
		
		<!-- 业务上的查询 -->
		<action name="queryById" class="org.act.upload.action.QueryFileAction" method="queryById">
			<result name="success">/jsp/upload/download_struts.jsp</result>
		</action>
		<action name="queryByName" class="org.act.upload.action.QueryFileAction">
			<result name="success">/jsp/upload/download_struts.jsp</result>
		</action>
		
	</package>
</struts>









  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值