JavaWeb框架_Struts2_(七)----->文件的上传和下载
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个属性来封装文件域信息:
- 类型为java.io.File的xxx属性来封装文件域的信息;
- 类型为String的xxxFileName属性封装了该文件域对应的文本内容;
- 类型为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拦截器时可以指定如下两个参数:
- allowTypes:该参数指定允许上传文件的类型,多个文件类型之间以英文逗号隔开;
- 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_(七)----->文件的上传和下载的更多相关文章
- 在SpringMVC框架下实现文件的 上传和 下载
在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8" ...
- Spring MVC 实现文件的上传和下载
前些天一位江苏经贸的学弟跟我留言问了我这样一个问题:“用什么技术来实现一般网页上文件的上传和下载?是框架还是Java中的IO流”.我回复他说:“使用Spring MVC框架可以做到这一点,因为Spri ...
- JavaWeb中文件的上传和下载
JavaWeb中文件的上传和下载 转自: JavaWeb学习总结(五十)——文件上传和下载 - 孤傲苍狼 - 博客园https://www.cnblogs.com/xdp-gacl/p/4200090 ...
- Javaweb之文件的上传与下载
Javaweb之文件的上传与下载 一.基于表单的文件上传 如果在表单中使用表单元素 <input type=“file” />,浏览器在解析表单时,会自动生成一个输入框和一个按钮,输入框可 ...
- java实现ftp文件的上传与下载
最近在做ftp文件的上传与下载,基于此,整理了一下资料.本来想采用java自带的方法,可是看了一下jdk1.6与1.7的实现方法有点区别,于是采用了Apache下的框架实现的... 1.首先引用3个包 ...
- iOS开发中文件的上传和下载功能的基本实现-备用
感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...
- 文件的上传和下载--SpringMVC
文件的上传和下载是项目开发中最常用的功能,例如图片的上传和下载.邮件附件的上传和下载等. 接下来,将对Spring MVC环境中文件的上传和下载进行详细的讲解. 一.文件上传 多数文件上传都是通过表单 ...
- SpringMVC+Ajax实现文件批量上传和下载功能实例代码
需求: 文件批量上传,支持断点续传. 文件批量下载,支持断点续传. 使用JS能够实现批量下载,能够提供接口从指定url中下载文件并保存在本地指定路径中. 服务器不需要打包. 支持大文件断点下载.比如下 ...
- SecureCRT使用sz和rz命令进行文件的上传和下载
SecureCRT可以使用sz和rz命令进行文件的上传和下载. sz文件下载: 格式:sz 文件名称 即可将服务器的文件下载至本地. rz文件上传: 格式:rz 文件名称 即可将本地文件上传至服务器. ...
随机推荐
- java传值与传引用总结
基本数据类型 我们先来看一个代码 public class ParamTest { public static void main(String[] arge) { double percent = ...
- 【20171027中】alert(1) to win 第13,14,15,16题
第13题 题目: function escape(s) { var tag = document.createElement('iframe'); // For this one, you get t ...
- my dream
我的梦想(践踏一切可以践踏的,放弃一切必须放弃的,然后朝着自己认为的方向努力,只要自己认为对了就可以了(但是最好能考虑方面全一点,这就叫尽力了)我想要的生活怎么那么醉我想要的食物怎么那么碎我最爱的女孩 ...
- 简单的一句sql
表1 Id Name 1 张三 2 李四 3 王五 表二 Id Name1 Name2 1 1 2 2 2 1 3 2 3 4 1 3 我现在要查出结果如下: Id Name1 Name2 1 张三 ...
- 读《你不知道的JavaScript(上卷)》后感-作用域闭包(二)
github原文 一. 序言 最近我在读一本书:<你不知道的JavaScript>,这书分为上中卷,内容非常丰富,认真细读,能学到非常多JavaScript的知识点,希望广大的前端同胞们, ...
- rewrite写法
RewriteRule ^/android-special-(\d+).html$ /special/index.php?c=index&a=specialDetail&speid=$ ...
- 通过对DAO层的封装减少数据库操作的代码量
在学框架之前,写项目时总是要花大量的时间去写数据库操作层代码,这样会大大降低我们的效率,为了解决这个问题,我花了两天时间利用反射机制和泛型将DAO层进行了封装,这样我们只需要写sql语句,不需要再写 ...
- 浅谈MES系统SMT的JIT功能(一):JIT原理
前段时间帮忙客户实现了MES系统的SMT线上的JIT功能(JIT功能只适合电子行业的生产线),今天就来谈谈JIT功能是什么,为什么工厂车间需要用到JIT等等一些经验 首先说说JIT: 准时制生产方式( ...
- ASP.NET Core的身份认证框架IdentityServer4(5)- 包和构建
包和构建 IdentityServer有许多nuget包 IdentityServer4 nuget | github 包含IdentityServer核心对象模型,服务和中间件. 仅支持内存配置和用 ...
- vue初级学习--环境搭建
一.导语 最近总想学点东西,es6啊.typescript啊,都想学,刚好有个机遇,可以学点vue,嗯,那就开始吧. 二.正文 1.node环境: 下载安装nodeJs,最好是1.6以上的版本,下载地 ...