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. ubuntu中python3.4安装pip

    这两天碰到在ubuntu中安装pip的问题. 第一种方法 用百度搜索了一下,基本上都是这个命令: sudo apt-get install python3-pip 但是,用这条命令下载速度特别慢. 第 ...

  2. gops - Go语言程序查看和诊断工具

    想必 Java 的开发者没有不知道或者没用过 jps 这个命令的,这个命令是用来在主机上查看有哪些 Java 程序在运行的. 我刚用 Go 语言程序的时候也很苦恼,我部署在公司服务器上的 Go 程序, ...

  3. 在ASP.NET Core中使用AOP来简化缓存操作

    前言 关于缓存的使用,相信大家都是熟悉的不能再熟悉了,简单来说就是下面一句话. 优先从缓存中取数据,缓存中取不到再去数据库中取,取到了在扔进缓存中去. 然后我们就会看到项目中有类似这样的代码了. pu ...

  4. 跨域 Ajax 其他可选技术 异步

    使用image pings 最早的跨域方法之一就是使用这个,任何域的<img>和<script>元素都可以随便加载. var img = new Image(); img.on ...

  5. Unity 游戏框架搭建 (十九) 简易对象池

    在Unity中我们经常会用到对象池,使用对象池无非就是解决两个问题: 一是减少new时候寻址造成的消耗,该消耗的原因是内存碎片. 二是减少Object.Instantiate时内部进行序列化和反序列化 ...

  6. ASP.NET Core 2.0 集成测试无法执行的问题

    问题表现: Microsoft.AspNetCore.Mvc.Razor.Compilation.CompilationFailedException : One or more compilatio ...

  7. javaScript额外笔记

    --------------------------------------------------------Part 1javascript:脚本语言辅助开发:网页的前台开发三大块:1.HTML ...

  8. java 虚拟机的类加载机制

    Java 虚拟机的类加载机制 关于类加载机制: ​ 虚拟机把描述类的数据从Class 文件加载到内存,并对数据进行效验.转换解析和初始化,最终 形成可以被虚拟机直接使用的Java 类型,就是虚拟机的类 ...

  9. javascript第四章--面向对象的程序设计

    ① 理解对象 ② 创建对象 ③ 继承

  10. Redis Save 与 BGSAVE 的区别

    一,save保存数据到磁盘的方式: Redis Save 命令执行一个同步保存操作,将当前 Redis 实例的所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘. 语法redis Sav ...