引言:
一系列的知识研究,可以有助于构建你强大的知识网。概述:
struts2也能实现简单的文件上传与下载,为什么说它能简单实现哪?因为项目中文件的上传和下载基本都与项目的业务逻辑所绑定,从功能和性能上,或许struts2不是很适用,但是作为一种实现方式,我们确可以了解一下。内容:
一 单个文件的上传:
1 实现原理:(1):第一步,将上传流写入本地临时文件夹里,生成一个临时文件。
(2):第二步,临时文件对象封装到file对象里。
(3):第三步,通过fileupload拦截器将封装好的file对象注入到action中。
注意:在这里我们并不关心前俩不,这个都是struts2框架为我们准备好的,关键是第三步需要我们自己配置的。
2 实现示例:
实现方法有三种:
(1)基础实现方式,新建文件流;
(2)通过FileUtils包里面的一个copy()方法;
(3)通过java中文件读写的封装类,BufferedReader和BufferedWriter。
3 代码示例:
(1)业务逻辑层代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport{
private File upload; //要与jsp页面的控件命名一样。<input type="file" name="upload">
private String uploadFileName; //获取文件名称,通过File可以获得临时文件的名称
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;
}
@Override
public String execute() throws Exception {
File uploadFile =new File(ServletActionContext.getServletContext().getRealPath("upload"));
if(!uploadFile.exists())
{
uploadFile.mkdir(); //创建一个文件
}
//第一种基础写法
//新建文件流
/*InputStream input = new FileInputStream(upload); //输入流
FileOutputStream out = new FileOutputStream(uploadFile + "\\" +uploadFileName); //输出流
try{
byte[] b = new byte[1024]; //字节数组,读多大的文件,1024为读1KB的数据
int i = 0; //定义记录位置
while((i = input.read(b))>0){
out.write(b, 0, i);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//关闭输入输出流,不然占资源
input.close();
out.close();
}*/
//第二种:实现读写功能,利用FileUtils包下面的一个方法
//FileUtils.copyFile(upload, new File(uploadFile + "\\" +uploadFileName));
//第三种方法:struts上次文件默认大小为2M,可以在struts2种配置
BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream(upload)));
BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(uploadFile + "\\" +uploadFileName)));
try {
char[] c = new char[1024];
int i = 0;
while((i = bReader.read(c)) >0){
bWriter.write(c, 0, i);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
bReader.close();
bWriter.close();
upload.delete();
}
return "success";
}
}
2)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>单个文件上传</title>
</head>
<body>
<!-- form的action为struts.xml中package的命名空间/action的名字。 -->
<form action="file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="upload">
<input type="submit" name="btnUpload" value="上传">
</form>
</body>
</html>
3)sturts2配置文件:<package name="upload" namespace="/file" extends="struts-default">
<!-- 单文件上传,配置action -->
<action name="upload" class="com.action.UploadAction">
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
<result name="input">/index.jsp</result>
<!-- 拦截器设置 -->
<!-- <interceptor-ref name="fileUpload">
<param name="maximumSize">1000000</param>
<param name="allowedTypes"></param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref> -->
<!-- 直接action设置 ,在相应的Action设置接收参数的变量-->
<param name="maximumSize">1000000</param>
<param name="allowedTypes"></param>
</action>
</package><span style="font-size:18px;"><strong></strong></span><span style="font-size:18px;"><strong> </strong></span><span style="font-size:18px;"> </span>
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport{
private File upload; //要与jsp页面的控件命名一样。<input type="file" name="upload">
private String uploadFileName; //获取文件名称,通过File可以获得临时文件的名称
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;
}
@Override
public String execute() throws Exception {
File uploadFile =new File(ServletActionContext.getServletContext().getRealPath("upload"));
if(!uploadFile.exists())
{
uploadFile.mkdir(); //创建一个文件
}
//第一种基础写法
//新建文件流
/*InputStream input = new FileInputStream(upload); //输入流
FileOutputStream out = new FileOutputStream(uploadFile + "\\" +uploadFileName); //输出流
try{
byte[] b = new byte[1024]; //字节数组,读多大的文件,1024为读1KB的数据
int i = 0; //定义记录位置
while((i = input.read(b))>0){
out.write(b, 0, i);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//关闭输入输出流,不然占资源
input.close();
out.close();
}*/
//第二种:实现读写功能,利用FileUtils包下面的一个方法
//FileUtils.copyFile(upload, new File(uploadFile + "\\" +uploadFileName));
//第三种方法:struts上次文件默认大小为2M,可以在struts2种配置
BufferedReader bReader = new BufferedReader(new InputStreamReader(new FileInputStream(upload)));
BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(uploadFile + "\\" +uploadFileName)));
try {
char[] c = new char[1024];
int i = 0;
while((i = bReader.read(c)) >0){
bWriter.write(c, 0, i);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
bReader.close();
bWriter.close();
upload.delete();
}
return "success";
}
}
<%@ 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>单个文件上传</title>
</head>
<body>
<!-- form的action为struts.xml中package的命名空间/action的名字。 -->
<form action="file/upload" method="post" enctype="multipart/form-data">
<input type="file" name="upload">
<input type="submit" name="btnUpload" value="上传">
</form>
</body>
</html>
<package name="upload" namespace="/file" extends="struts-default">
<!-- 单文件上传,配置action -->
<action name="upload" class="com.action.UploadAction">
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
<result name="input">/index.jsp</result>
<!-- 拦截器设置 -->
<!-- <interceptor-ref name="fileUpload">
<param name="maximumSize">1000000</param>
<param name="allowedTypes"></param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref> -->
<!-- 直接action设置 ,在相应的Action设置接收参数的变量-->
<param name="maximumSize">1000000</param>
<param name="allowedTypes"></param>
</action>
</package><span style="font-size:18px;"><strong></strong></span><span style="font-size:18px;"><strong> </strong></span><span style="font-size:18px;"> </span>
3 实现方法的联系与区别:
(1)字符与字节:FileInputStream类操作的是二进制字节流,I/O速度快且效率高,但是它的read()方法读取到的是字节,不利于人们阅读,而且无法对文件中的字符进行操作,例如查找和替换;BufferedReader类弥补了这个缺陷,操作文本格式进行输入输出 ,可以对文本内容进行操作,例如:可以使用BufferedReader的readLine()方法一行一行读取文本。
(2)编码:BufferedReader进行文件的上传可能出现乱码,但是FileInputStream以二进制方式处理不会出现乱码。
(3)缓冲区:BufferedReader类用来包装所有其read()操作可能开销很高的Reader(如FileReader和InputStreamReader)
(4)第二种文件上传的方法,引用了文件工具FileUtils包下面的copyFile方法,相当于将已存在的文件copy了一份。
二 批量文件上传:
1 实现原理:与单个上传文件一致。
2 代码实现:
(1)业务逻辑层代码:
package com.action;
import java.io.File;
import java.util.List;
public class UploadsAction {
//多个单文件上传
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;
}
/*//文件集合上传
private List<File> upload;
private List<String> uploadFileName;
private List<String> uploadContentType;
public List<File> getUpload() {
return upload;
}
public void setUpload(List<File> upload) {
this.upload = upload;
}
public List<String> getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(List<String> uploadFileName) {
this.uploadFileName = uploadFileName;
}
public List<String> getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(List<String> uploadContentType) {
this.uploadContentType = uploadContentType;
}
*/
public String execute() throws Exception{
return "success";
}
}
(2) 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>多文件上传</title>
</head>
<body>
<!-- form的action为struts.xml中package的命名空间/action的名字。 -->
<form action="file/uploads" method="post" enctype="multipart/form-data">
<input type="file" name="upload"><br>
<input type="file" name="upload"><br>
<input type="file" name="upload"><br>
<input type="file" name="upload"><br>
<input type="submit" name="btnUpload" value="上传">
</form>
</body>
</html>
(3)sturts2配置代码:在package name="upload"里面。 <!-- 多文件上传配置action -->
<action name="uploads" class="com.action.UploadsAction">
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
</action>
三 文件下载:
1 实现原理:sturts2配置文件进行参数化传递,在result标签中进行(type=“stream”) 的设置即可。
2 代码示例 :
(1)业务逻辑层代码:
package com.action;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
public class DownLoadAction {
private InputStream fileInput;
private String fileName; //页面的文件名称,以参数形式传递
public InputStream getFileInput() {
//第一种写法
return ServletActionContext.getServletContext().getResourceAsStream("upload\\" + fileName);//文件名不一定是fileName,是服务器端的实际文件名称。
//return fileInput;
}
public void setFileInput(InputStream fileInput) {
this.fileInput = fileInput;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String execute() throws Exception{
/*//第二种写法:
fileInput =ServletActionContext.getServletContext().getResourceAsStream("upload\\" + fileName);//文件名不一定是fileName,是服务器端的实际文件名称。
*/ return "success";
}
}
(2)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>文件下载</title>
</head>
<body>
<a href="file/download?fileName=123.txt">123.txt</a>
</body>
</html>
(3)struts2文件配置代码: <!-- 下载文件配置action -->
<action name="download" class="com.action.DownLoadAction">
<result name="success" type="stream">
<param name="inputName">fileInput</param>
<param name="contentDisposition">attachment;filename="${fileName}"</param>
</result>
<result name="error">/error.jsp</result>
</action>
总结:
sturts的核心知识点一个是拦截器,一个就是文件的上传与下载。但是文件的上传与下载还应该结合项目的业务逻辑要求,我们也可以不用sturts2封装的这些类,通过其他的方法实现文件的上传和下载。小编总结就到这里,请读者多多点评。