1.  前言

  

  这个章节是Struts2框架应用最广泛的三个版块(上传下载、国际化、校验输入)之一,所以这一版块的学习还蛮重要的。

2.  具体内容

2.1Struts2文件上传

2.1.1单文件上传

  本小节通过一个示例讲解Struts2如何实现单文件的上传。

(1) 先写一个选择上传单文件页面(select.jsp)

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
Created by IntelliJ IDEA.
User: mairr
Date: 17-12-7
Time: 下午9:04
To change this template use File | Settings | File Templates.
--%> <%@ page contentType="text/html;charset=UTF-8" import="java.util.*" language="java" pageEncoding="UTF-8" %> <html>
<head>
<title>upload_test</title>
</head> <body>
<s:form action="upload" method="post" theme="simple" enctype="multipart/form-data">
输入帐号:<s:textfield name="uid"/><br>
选择头像:<s:file name="headImage"/><br>
<s:submit value="提交"/>
    
     <s:fielderror/>
    
</s:form>
</body>
</html>

  如下所示的一个上传选择界面框:

(2) 当文件上传页面提交请求时,请求发送到upload.action,这是一个Struts2的Action,该Action处理上传请求,具体的UploadAction类代码如下:

package action;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import java.io.File;
import java.io.IOException; public class UploadAction extends ActionSupport {
private String uid;          // 封装帐号(uid)请求参数属性
private File headImage;         // 封装上传文件域属性
private String headImageContentType; // 封装上传文件类型的属性
private String headImageFileName;     // 封装上传文件属性 public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
} public File getHeadImage() {
return headImage;
}
public void setHeadImage(File headImage) {
this.headImage = headImage;
} public String getHeadImageContentType() {
return headImageContentType;
}
public void setHeadImageContentType(String headImageContentType) {
this.headImageContentType = headImageContentType;
} public String getHeadImageFileName() {
return headImageFileName;
}
public void setHeadImageFileName(String headImageFileName) {
this.headImageFileName = headImageFileName;
} public String execute() throws IOException {
// 上传文件的保存位置在“/image”,该位置在tomcat服务器的“webapps”之中
String realpath= ServletActionContext.getServletContext().getRealPath("/image"); // 声明文件目录image,如果文件名不存在就建一个呗~
File file = new File(realpath);
if(!file.exists()){
file.mkdirs();
} // 实现文件上传,也就是做了一个方法调用~
FileUtils.copyFile(headImage,new File(file,headImageFileName));
return SUCCESS;
}
}

  需要注意的是,上面的Action除了包含两个表单域的name属性外,还包含headImageContentType和headImageFileName两个属性,这两个属性分别能用于封装上传文件的文件类型、上传文件的文件名。可以这样认为:如果表单中包含一个name属性为xxx的文件域,则对应的Action需要使用3个属性来封装文件域信息:

  1. 类型为java.io.File的xxx属性来封装文件域的信息;
  2. 类型为String的xxxFileName属性封装了该文件域对应的文本内容;
  3. 类型为String的xxxContentType属性封装了该文件域对应的文件类型

   所以,在Action的execute方法中,可以直接通过这3个属性获取上传文件的文件名、文件类型和文件内容。

(3) 接下来进行UploadAction的配置(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.custom.i18n.resources" value="messageResource"/> <!--设置Struts应用的解码集-->
<constant name="struts.i18n.encoding" value="utf-8"/>
  
  <!-- --- 包配置 ---- -->
<package name="default" namespace="/" extends="struts-default">
<action name="upload" class="action.UploadAction">
<result>/uploadSuccess.jsp</result>
</action>
</package>
</struts>

(4) 最后写一个上传成功页面(uploadSuccess.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>
<head>
<title>上传初始页</title>
</head>
<body>
上传成功!<br> <!--输入表单里的用户帐号属性-->
用户帐号:<s:property value="uid"/><br> <!--根据上传文件名字,显示上传头像-->
您的头像:<img src="<s:property value="'image/' + headImageFileName"/> " alt="图像无法显示"/>
</body>
</html>

  上传过程图:

  (a)选择图片

  (b)确认选择

  (c)提交之后,显示上传成功

2.1.2 拦截器实现文件的过滤

  Struts2提供了一个名为fileUpload拦截器,通过配置该拦截器可以轻松地实现文件过滤。为了让fileUpload拦截器起作用,只需要在处理文件上传的Action中配置该拦截器引用即可。
  配置fileUpload拦截器时可以指定如下两个参数:

  1. allowTypes:该参数指定允许上传文件的类型,多个文件类型之间以英文逗号隔开;
  2. maximumSize:该参数指定允许上传文件的大小,单位是字节。

  当文件过滤失败后,系统自动转入input逻辑视图,因此必须为Action配置名为input的逻辑视图。

(1) 通过拦截器来实现文件过滤的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.custom.i18n.resources" value="messageResource"/> <!--设置Struts应用的解码集-->
<constant name="struts.i18n.encoding" value="utf-8"/> <!--package中加入拦截器-->
<package name="default" namespace="/" extends="struts-default">
<interceptors>
<!--配置拦截器栈(在拦截器章节有讲述)-->
<interceptor-stack name="myStack">
<!--配置fileUpload拦截器-->
<interceptor-ref name="fileUpload">
<!--配置允许上传文件的类型(此处要注意的是png图片在ie浏览器中是image/x-png类型)-->
<param name="allowedTypes">image/x-png,image/bmp,image/gif,image/jpeg,image/jpg</param>
<!--配置允许上传文件大小拦截器,单位是字节(2的16次幂=65536(64k))-->
<param name="maximumSize">65536</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors> <action name="upload" class="action.UploadAction">
<!--使用拦截器栈-->
<interceptor-ref name="myStack"/>
<result>/uploadSuccess.jsp</result> <!--过滤失败,系统会转入input逻辑视图,这里配置其返回选择界面-->
<result name="input">/select.jsp</result>
</action>
</package>
</struts>

  格式不对和容量大于64kb会上传失败,直接返回重新选择的界面。如果上传失败,系统需要回应上传失败信息。因此,需要在文件上传页selectFile.jsp页面中加上“<s:filederror/>”------->(我直接加到了selectFile.jsp代码中,你可以回看上面)

(a) 文件格式不对

------(提交之后)------->

(b) 文件大小超过了限额

-------(提交之后)----->

2.1.3  文件上传的常量配置

   上传文件时,系统默认使用web服务器的工作路径作为临时路径。为了避免文件上传时候使用Web服务器的工作路径作为临时路径,则应该设置struts.multipart.saveDir常量。该常量指定上传文件的临时保存路径。该常量配置示例如下:

 <constant name="struts.multipart.saveDir" value="HOME/....(写上路径)..."/>

  此外,还有一个文件上传的常量struts.multipart.maxSize。该常量指定struts.mutipart.maxSize。该常量指定在struts2文件上传中整个请求内容所允许的最大字节数,默认为2097152(即2MB)。该常量配置示例如下:

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

2.1.4  Struts2多文件上传

  在Struts2应用中,如果一个页面有多个文件域需要实现上传,则可以为每个文件域提供三个属性,分别封装该文件域对应的文件名、文件类型和文件内容。多文件上传与单文件上传没有什么区别,仅仅是利用数组同时上传多个文件的方式。

  在处理多文件上传时,要注意改变的是,在Action类中,需要使用三个数组分别封装文件名、文件类型和文件内容

 // 实现单文件上传代码如下:
FileUtils.copyFile(headImage,new File(file,headImageFileName)); // 实现多文件下载代码如下:
for(int i = 0; i < headImage.length(); i++){
File uploadImage = headImage[i];
FileUtils.copyFile(uploadImage,new File(file,headImageFileName[i]));
}

2.2  Struts2文件下载

  利用Struts2来处理文件的下载的问题时,能够解决下载文件的文件名为中英文等等都不出现乱码。此外,还能够在用户下载之前进行检查,判断用户是否有足够的权限来下载该文件等。下面用一个示例来讲解文件的下载:

(1) 先写一个下载页面:(index.jsp)

<%--
Created by IntelliJ IDEA.
User: mairr
Date: 17-12-9
Time: 下午2:20
To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <html>
<head>
<title>test_download</title>
</head>
<body>
  请下载中文课件:<a href="downLoad.action?downPath=第一章节.doc">中</a><br>
  请下载英文课件:<a href="downLoad.action?downPath=chapter01.doc">英</a><br>
</body>
</html>

(2) 在Struts2框架文件下载Action类中,需要提供一个返回InputStream流方法,该输入流代表了被下载文件的入口。该Action类代码如下所示:(DownLoadAction.java)

package action;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import util.MyUtil;
import java.io.InputStream;
import java.io.UnsupportedEncodingException; public class DownLoadAction extends ActionSupport{ private String downPath; // 下载时的文件名
private String contentType; // 保存文件类型
private String filename; // 保存时的文件名 public String getContentType() {
return contentType;
} public void setContentType(String contentType) {
this.contentType = contentType;
} public String getFilename() {
return filename;
} public void setFilename(String filename) {
this.filename = filename;
} public String getDownPath() {
return downPath;
}
public void setDownPath(String downPath) {
try {
// 解决下载时候的中文文件乱码问题
downPath = new String(downPath.getBytes("ISO-8859-1"),"UTF-8");
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
this.downPath = downPath;
} /*
*下载用的Action返回一个InputString实例,该方法对应Action配置
*里面的result的inputName参数,值为inputString
*
*/ public InputStream getInputString(){
return ServletActionContext.getServletContext().getResourceAsStream(downPath);
} public String execute(){
// 下载保存时的文件名和被下载的文件名一样
filename = downPath;
// 下载的文件路径,请在webapps目录下创建images
downPath = "images/" + downPath;
// 保存文件的类型 contentType = "application/x-msdownload"; /*
*对下载的文件名按照UTF-8进行编码,解决下载窗口中的中文乱码问题
* 其中,MyUtil是自己定义的一个类
*/ filename = MyUtil.toUTF8String(filename);
return SUCCESS;
}
}

(3) 在上述的Action类中定义了一个工具类MyUtil,该类中有一个静态方法toUTF8String实现对下载的文件名按照UTF-8进行编码,解决下载窗口中中文乱码的问题:(MyUtil.java)

package util;

import java.io.UnsupportedEncodingException;

public class MyUtil {
// 对下载文件按照 UTF-8 进行编码 public static String toUTF8String(String str){
StringBuffer sb = new StringBuffer();
int len = str.length();
for (int i = 0; i < len; i++)
{
// 取出字符中的每个字符
char c = str.charAt(i);
// Unicode码值在0~255之间,不做处理
if(c>=0 && c <= 255){
sb.append(c);
}else {
// 转换 UTF-8 编码
byte b[];
try{
b = Character.toString(c).getBytes("UTF-8");
}catch(UnsupportedEncodingException e){
e.printStackTrace();
b = null;
}
// 转换为%HH的字符串形式
for(int j = 0;j < b.length ; j++){
int k = b[j];
if(k < 0){
k &= 255;
}
sb.append("%" + Integer.toHexString(k).toUpperCase());
}
}
}
return sb.toString();
}
}

(4) 最后,完成Action的配置,关键是要配置一个类型为stream的结果,配置时需要指定如下四个属性:

  • contentType:  指定被下载文件的文件类型;
  • inputName:  指定被下载文件的入口输入流;
  • contentDisposition:  指定下载的文件名;
  • bufferSize:  指定下载文件时的缓冲大小。

  具体代码如下:(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>
<package name="default" namespace="/" extends="struts-default">
<action name="downLoad" class="action.DownLoadAction">
<!--结果类型为String-->
<result type="stream"> <param name="contentType">${contentType}</param>
<!--默认就是inputStream,它将会指示StreamResult通过
inputName属性值的getter和setter方法,如这里就是
getInputStream()来获取下载文件的内容,意味着Action
要有这个方法
-->
<param name="inputName">inputStream</param>
<!--默认为inline(在线打开),设置为attachment将会告诉浏览器下载
该文件,filename指定下载文件时的文件名,若未指定将会以浏览器
页面名作为文件名,如:以download.action作为文件名
-->
<param name="contentDisposition">attachment;filename=${filename}</param>
<!--指定下载文件的缓冲大小-->
<param name="bufferSize">4096</param> </result>
</action>
</package>

(5)  最后的下载窗口:

JavaWeb框架_Struts2_(七)----->文件的上传和下载的更多相关文章

  1. 在SpringMVC框架下实现文件的 上传和 下载

    在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8" ...

  2. Spring MVC 实现文件的上传和下载

    前些天一位江苏经贸的学弟跟我留言问了我这样一个问题:“用什么技术来实现一般网页上文件的上传和下载?是框架还是Java中的IO流”.我回复他说:“使用Spring MVC框架可以做到这一点,因为Spri ...

  3. JavaWeb中文件的上传和下载

    JavaWeb中文件的上传和下载 转自: JavaWeb学习总结(五十)——文件上传和下载 - 孤傲苍狼 - 博客园https://www.cnblogs.com/xdp-gacl/p/4200090 ...

  4. Javaweb之文件的上传与下载

    Javaweb之文件的上传与下载 一.基于表单的文件上传 如果在表单中使用表单元素 <input type=“file” />,浏览器在解析表单时,会自动生成一个输入框和一个按钮,输入框可 ...

  5. java实现ftp文件的上传与下载

    最近在做ftp文件的上传与下载,基于此,整理了一下资料.本来想采用java自带的方法,可是看了一下jdk1.6与1.7的实现方法有点区别,于是采用了Apache下的框架实现的... 1.首先引用3个包 ...

  6. iOS开发中文件的上传和下载功能的基本实现-备用

    感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...

  7. 文件的上传和下载--SpringMVC

    文件的上传和下载是项目开发中最常用的功能,例如图片的上传和下载.邮件附件的上传和下载等. 接下来,将对Spring MVC环境中文件的上传和下载进行详细的讲解. 一.文件上传 多数文件上传都是通过表单 ...

  8. SpringMVC+Ajax实现文件批量上传和下载功能实例代码

    需求: 文件批量上传,支持断点续传. 文件批量下载,支持断点续传. 使用JS能够实现批量下载,能够提供接口从指定url中下载文件并保存在本地指定路径中. 服务器不需要打包. 支持大文件断点下载.比如下 ...

  9. SecureCRT使用sz和rz命令进行文件的上传和下载

    SecureCRT可以使用sz和rz命令进行文件的上传和下载. sz文件下载: 格式:sz 文件名称 即可将服务器的文件下载至本地. rz文件上传: 格式:rz 文件名称 即可将本地文件上传至服务器. ...

随机推荐

  1. 顺序线性表 ---- ArrayList 源码解析及实现原理分析

    原创播客,如需转载请注明出处.原文地址:http://www.cnblogs.com/crawl/p/7738888.html ------------------------------------ ...

  2. 走进 Xamarin Test Recorder for Xamarin.Forms

    此篇是承接之前 走进 UITest for Xamarin.Forms 的,所以如果没有看过之前的可以先看下之前的 UITest 比起上一篇纯敲代码只适合程序员的 UITest ,这一篇不管是程序员还 ...

  3. Android 6.0运行时权限

    一.Runtime Permissions Android 6.0在手机安全方面做的一个处理就是增加了运行时权限(Runtime Permissions). 新的权限机制更好的保护了用户的隐私,Goo ...

  4. iOS之 Auto Layout

    1. 动画 // 修改从 StoryBoard 绑定到类的约束的值 self.boxView.constant += 80 // 在动画闭包里对其父级进行 layoutIfNeeded() UIVie ...

  5. iOS 之 runtime --- 集百家之言

    runtime runtime用在什么地方? 说法 在程序运行过程中,动态的创建一个类(比如KVO的底层实现) 在程序运行过程中,动态地为某个类添加属性.方法,修改属性值\方法(method swiz ...

  6. 版本控制之二:SVN的初步使用(转)

    转自http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407979.html 上一篇介绍了VisualSVN Server和Tortoise ...

  7. Paint the Grid Reloaded(缩点,DFS+BFS)

    Leo has a grid with N rows and M columns. All cells are painted with either black or white initially ...

  8. c++学习笔记---05--- C++输出输入小结

    C++输出输入小结 题目: 这个程序将向用户提出一个"Y/N"问题,然后把用户输入的值赋值给answer变量. 要求: 针对用户输入'Y'或'y'和'N'或'n'进行过滤: 发掘程 ...

  9. Oracle 数据库常用操作语句大全

    一.Oracle数据库操作 1.创建数据库      create database databasename 2.删除数据库      drop database dbname 3.备份数据库 完全 ...

  10. [Intel Edison开发板] 06、Edison开发在linux中烧写、配置、搭建开发环境

    1.前言 linux上烧写.配置.搭建Edison环境,千万不要用默认的setup tool for ubuntu!!! (即使,你用的就是ubuntu) 因为,其默认的工具会从一个坏链接下载配置文件 ...