在 Struts 应用程序里,FileUpload 拦截器和 Jakarta Commons FileUpload 组件可以完成文件的上传.
步骤:
1. 在 Jsp 页面的文件上传表单里使用 file 标签. 如果需要一次上传多个文件, 就必须使用多个 file 标签, 但它们的名字必须是相同的
2. 在 Action 中新添加 3 个和文件上传相关的属性. 这 3 个属性的名字必须是以下格式
private File uploadImage; //上传的文件
private String uploadImageContentType; //上传的文件的类型
private String uploadImageFileName; //上传文件的名称
uploadImage是 jsp 页面上的 file 标签的名字:
上传文件:<input type="file" name="uploadImage">
如果是上传单个文件:
(1)第一个(uploadImage)属性的类型就是 java.io.File, 它代表被上传的文件;
(2)第二个(uploadImageContentType)属性类型是String,它代表上传文件的文件类型, 定义方式是jsp页面file组件的名称+ContentType,;
(3) 第三个(uploadImageFileName)属性类型是 String, 它代表上传文件的文件名,定义方式是jsp页面file组件的名称+FileName;
如果上上传多个文件, 可以使用数组或 List;
实例步骤:
在WEB-INF/lib下加入commons-fileupload-1.2.1.jar、commons-io-1.3.2.jar。这两个文件可以从http://commons.apache.org/下载。
1.编写一个页面(单文件上传):
文件上传要素:
(1)表单的提交的方式需要是POST
(2)表单中需要有<input type=”file”>
必须有name属性
(3)表单的enctype属性必须是multipart/form-data
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form enctype="multipart/form-data" method="post" action="<%=basePath %>/upload/upload.action">
<input type="file" name="upload" value="" />
资源描述:<input type="text" name="desc" value="" />
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>
2.编写Action:
package com.ming.upload;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
/*
* 提供文件上传的三个属性:
* 文件类型(File) 属性名与<input type=”file”>中name属性一致.
* 字符串类型(String) 属性名前端与<input type=”file”>中name属性一致.后端+FileName;
* 字符串类型(String) 属性名前端与<input type=”file”>中name属性一致.后端+ContentType;
*/
public class UploadAction extends ActionSupport {
// 接收普通项的值:
private String desc;
public void setDesc(String desc) {
this.desc = desc;
}
/*
* 原理就是将前端文件流存储在临时文件中,并定义File对象为upload
*/
private File upload; //对应前端的文件input框的name属性值
private String uploadFileName; // 上传文件的文件名. 由File的属性名称和FileName拼接而成
private String uploadContentType; // 上传文件的MIME的类型. 由File的属性名称和ContentType拼接而成
public void setUpload(File upload) {
this.upload = upload;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
@Override
public String execute() throws Exception {
System.out.println("desc="+desc);
// 获得文件上传的磁盘绝对路径.(当前服务器存放的磁盘位置)
String path = ServletActionContext.getServletContext().getRealPath(
"/upload");
// 创建一个文件对象:
File diskFile = new File(path+"\\"+uploadFileName);
System.out.println(uploadFileName);
System.out.println(uploadContentType);
//将上传文件的流临时存放到服务器上的临时文件
System.out.println("文件路径:" + upload.getPath());
//将上传的文件复制到服务器指定的目录中
FileUtils.copyFile(upload, diskFile);
/*
* 用输入流读取文件
*/
Reader reader = new FileReader(upload);
char[] cbuf = new char[1024];
while(reader.read(cbuf) != -1) {
for (int i = 0; i < cbuf.length; i++) {
System.out.print(cbuf[i]);
}
}
reader.close();
return NONE;
}
}
struts2提供了stream结果类型,该结果类型就是专门用于支持文件下载功能的
指定stream结果类型 需要指定一个 inputName参数,该参数指定一个输入流,提供被下载文件的入口
<action name="download1" class="cn.itcast.struts2.demo2.DownloadAction1">
<result name="success" type="stream">
<!-- 允许下载的文件的类型:通过ognl表达式获取,Action中提供getContentType方法 -->
<param name="contentType">${contentType}</param>
<!-- 下载头,包括:浏览器显示的文件名,通过ognl表达式获取,Action中提供getFileName方法 -->
<param name="contentDisposition">attachment;filename=${fileName}</param>
<!-- 对应的就是Action种的属性,返回流的属性,需要在Action中提供getInputStream方法,该方法返回值类型为java.io.InputStream类型,这是约定的。 -->
<param name="inputName">inputStream</param>
<!-- 缓冲区大小设置 -->
<param name="bufferSize">1024</param>
</result>
</action>
package cn.itcast.struts2.demo2;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.struts2.ServletActionContext;
import sun.misc.BASE64Encoder;
import com.opensymphony.xwork2.ActionSupport;
/**
* 文件下载的Action:
*
* @author jiangtao
*
*/
public class DownloadAction1 extends ActionSupport {
// 接收文件名:
private String filename;
public void setFilename(String filename)
throws UnsupportedEncodingException {
this.filename = new String(filename.getBytes("ISO-8859-1"), "UTF-8");
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
/**
* 提供获得文件MIME类型的方法:
*/
public String getContentType() {
String mimeType = ServletActionContext.getServletContext().getMimeType(
filename);
return mimeType;
}
/**
* 提供获得文件名的方法:
* @throws IOException
*/
public String getFileName() throws IOException{
// 获得User-Agent的请求头:
String agent = ServletActionContext.getRequest().getHeader("User-Agent");
String fileName = encodeDownloadFilename(filename,agent);
return fileName;
}
/**
* 提供一个文件下载的输入流:
* @throws FileNotFoundException
*/
public InputStream getInputStream() throws FileNotFoundException{
// 获得文件下载的路径:
String path = ServletActionContext.getServletContext().getRealPath("/download");
InputStream is = new FileInputStream(path+"\\"+filename);
return is;
}
/**
* 下载文件时,针对不同浏览器,进行附件名的编码
* @param filename 下载文件名
* @param agent 客户端浏览器
* @return 编码后的下载附件名
* @throws IOException
*/
public String encodeDownloadFilename(String filename, String agent) throws IOException{
if(agent.contains("Firefox")){ // 火狐浏览器
filename = "=?UTF-8?B?"+new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?=";
}else{ // IE及其他浏览器
filename = URLEncoder.encode(filename,"utf-8");
}
return filename;
}
}