在之前的隨筆之中,我們已經了解Java通過上傳組件來實現上傳和下載,這次我們來了解Struts2的上傳和下載。
注意:文件上傳時,我們需要將表單提交方式設置為"POST"方式,並且將enctype屬性設置為"multipart/form-data",該屬性的默認值為"application/x-www-form-urlencoded",就是說,表單要寫成以下這種形式:
<form action="" method="post" enctype="multipart/form-data"></form>
而且Struts2中並沒有提供自己的文件上傳解析器,默認使用的是Jakarta的Common-FileUpload的文件上傳組件,所以我們還需要在添加兩個包:
commons-io
commons-fileupload
至於版本根據自己需要選擇(筆者在第一篇已經搭建好環境了。地址)
注意點如下:
1.1、文件上傳的前提是表單屬性method="post" enctype="multipart/form-data";
1.2、web應用中必須包含common-fileupload.jar和common-io.jar,因為struts2默認上傳解析器使用的是jakarta;
1.3、可以在struts.xml中配置最大允許上傳的文件大小:<constant name="struts.multipart.maxSize" value="....."/>,默認為2M;
2.1、在Action中定義屬性:
private File upload; //包含文件內容
private String uploadFileName; //上傳文件的名稱;
private String uploadContentType; //上傳文件的MIME類型;
這些屬性都會隨著文件的上傳自動賦值;
2.2、上傳圖片的例子
新建視圖界面:Upload.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>Struts2 FileUpload</title>
</head>
<body>
<form action="fileupload" method="post" enctype="multipart/form-data">
文件標題:<input type="text" name="title"/><br/>
選擇文件:<input type="file" name="upload"/><br/>
<input type="submit" value="上傳"/>
</form>
</body>
</html>
新建UploadAction繼承ActionSupport
package com.Struts2.load;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
//上傳單個文件
public class UploadAction extends ActionSupport {
//文件標題請求參數的屬性
private String title;
//上傳文件域的屬性
private File upload;
//上傳文件類型
private String uploadContentType;
//上傳文件名
private String uploadFileName;
//接受依賴注入的屬性
private String savePath;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
//返回上傳文件的保存位置
public String getSavePath() {
return ServletActionContext.getRequest().getRealPath(savePath);
}
//接受依賴注入的方法
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public String execute() throws Exception{
System.out.println(getSavePath());
System.out.println(getUploadFileName());
//以服務器的文件保存地址和原文件名建立上傳文件輸出流
FileOutputStream fos = new FileOutputStream(getSavePath()+"\\"+getUploadFileName());
//以上傳文件建立一個文件上傳流
FileInputStream fis = new FileInputStream(getUpload());
//將上傳文件的內容寫入服務器
byte[] buffer = new byte[1024];
int leng = 0;
while((leng=fis.read(buffer))>0){
fos.write(buffer,0,leng);
buffer = new byte[1024];
}
return SUCCESS;
}
}
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" extends="struts-default">
<action name="fileupload" class="com.Struts2.load.UploadAction">
<!--使用攔截器過濾:1、配置默認攔截器,2、配置input的邏輯視圖-->
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/jpeg,image/jpg,/image/gif,image/png</param>
</interceptor-ref>
<!-- 必須顯示配置defaultStack攔截器的引用 -->
<interceptor-ref name="defaultStack"/>
<param name="savePath">/upload</param>
<result name="success">succ.jsp</result>
<!--必須配置input的邏輯視圖 -->
<result name="input">Error.jsp</result>
</action>
<struts>
注意:web.xml中需要配置struts2的攔截器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>LearStruts2</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!--為Struts2定義一個過濾器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
web.xml
succ.jsp視圖代碼
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!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>
上傳成功<br/>
文件標題:<s:property value="title"/><br/>
<s:property value="uploadFileName"/>
文件為:<img src="<s:property value="'/LearStruts2/upload/'+uploadFileName"/>"/><br/>
</body>
</html>
Error.jsp視圖代碼

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>Error 界面</title>
</head>
<body>
<s:fielderror/>
</body>
</html>
Error.jsp
代碼效果如下:

注意:在struts.xml配置文件中,已經限制只能上傳圖片格式,如果上傳別的文件的話,則會報錯。
2.3、多個文件上傳
新建Upliads.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="filesupload" method="post" enctype="multipart/form-data">
文件標題:<input type="text" name="title"><br/>
選擇第一個文件:<input type="file" name="uploads"><br/>
選擇第二個文件:<input type="file" name="uploads"><br/>
選擇第三個文件:<input type="file" name="uploads"><br/>
<input type="submit" value="上傳"/>
</form>
</body>
</html>
Upliads.jsp
新建UploadsAction類繼承ActionSupport
package com.Struts2.load;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
//上傳多個文件
public class UploadsAction extends ActionSupport {
private String title; //對應jsp的title
private File[] uploads; //對應jsp的uploads
private String[] uploadsContentType;
private String[] uploadsFileName;
//savePath:通過配置文件進行賦值"'\'upload",
//其中的'\'表示項目的根目錄D:\\tomcat-8.0\\wtpwebapps\\LearStruts2\\upload
private String savePath;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public File[] getUploads() {
return uploads;
}
public void setUploads(File[] upload) {
this.uploads = upload;
}
public String[] getUploadsContentType() {
return uploadsContentType;
}
public void setUploadsContentType(String[] uploadsContentType) {
this.uploadsContentType = uploadsContentType;
}
public String[] getUploadsFileName() {
return uploadsFileName;
}
public void setUploadsFileName(String[] uploadsFileName) {
this.uploadsFileName = uploadsFileName;
}
public String getSavePath() {
return ServletActionContext.getRequest().getRealPath(savePath);
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public String execute() throws Exception{
File[] files = getUploads();
for(int i = 0;i<files.length;i++){
System.out.println(getSavePath());
System.out.println(getUploadsFileName()[i]);
//getSavePath : 獲得根目錄
//getUploadsFileName() : 獲得文件名
FileOutputStream fos = new FileOutputStream(getSavePath()+"\\"+getUploadsFileName()[i]);
FileInputStream fis = new FileInputStream(files[i]);
byte[] buffer = new byte[1024];
int len = 0;
while((len=fis.read(buffer))>0){
fos.write(buffer,0,len);
buffer = new byte[1024];
}
}
return SUCCESS;
}
}
struts.xml中配置信息
<!--多個文件上傳 -->
<action name="filesupload" class="com.Struts2.load.UploadsAction">
<!--該屬性是依賴注入:通過配置文件給savePath賦值 ,是必須的 -->
<param name="savePath">/upload</param>
<result name="success">succ1.jsp</result>
</action>
succ1.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>
上傳成功
</body>
</html>
succ1.jsp
代碼效果如下:

2.3、Struts2的文件下載
視圖下載界面

<%@ 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>Struts 2實現的文件下載</title>
</head>
<body>
<a href="down.action">圖片下載</a>
</body>
</html>
fuledown.jsp
Action類
package com.Struts2.load;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DownAction extends ActionSupport {
private String inputPath;
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 getInputPath() {
return inputPath;
}
public void setInputPath(String inputPath) {
this.inputPath = inputPath;
}
//下載用的Action應該返回一個InputStream實例
//該方法對應在result裡的inputName屬性值為targetFile
//第二步
public InputStream getTargetFile() throws Exception{
System.out.println("1");
InputStream in=ServletActionContext.getServletContext().getResourceAsStream(inputPath);
return in;
}
//第一步
public String execute(){
System.out.println("???");
inputPath="/upload/1.jpg";//要下載的文件名稱
filename="1.jpg"; //保存文件時的名稱
contentType="image/jpg";//保存文件的類型
return SUCCESS;
}
}
Struts.xml配置文件
<!-- 下載文件的Action -->
<action name="down" class="com.Struts2.load.DownAction">
<!-- 指定被下載資源的位置 -->
<param name="inputPath">${inputPath}</param>
<!-- 配置結果類型為stream的結果 -->
<result name="success" type="stream">
<!--
contentType:指定下載文件的類型 ,和互聯網MIME標准中的規定類型一致,
例如text/plain代表純文本,text/xml表示XML,image/gif代表GIF圖片,image/jpeg代表JPG圖片
-->
<param name="contentType">${contentType}</param>
<!-- 指定下載文件的位置 -->
<!--
inputName:下載文件的來源流,對應著action類中某個類型為Inputstream的屬性名,
例如取值為inputStream的屬性需要編寫getInputStream()方法
-->
<param name="inputName">targetFile</param>
<!--
contentDisposition
文件下載的處理方式,包括內聯(inline)和附件(attachment)兩種方式,
而附件方式會彈出文件保存對話框,否則浏覽器會嘗試直接顯示文件。
默認情況是代表inline,浏覽器會嘗試自動打開它
-->
<param name="contentDisposition">attachement;filename="${filename}"</param>
<!-- 指定下載文件的緩沖大小 -->
<param name="bufferSize">50000000</param>
</result>
</action>
代碼都有筆者測試過,至於解析,筆者會在後期理解好之後再重新寫。