Detailed explanation of struts2 file upload and download

File upload
form
File upload form requirements

  1. The form submission method must be POST
  2. There must be a form element in the form: or struts2 label <s:file label=“xxx” name=“xxx”/>
  3. The enctype attribute of the form must be multipart/form-data
    . The three value representations and meanings of the enctype attribute of the form are provided here
    (1) application/x-www-form-urlencoded, the default value, it can only process the form field The value attribute, the form using this encoding method will process the value of the form field into a URL encoding method.
    (2) Multipart/form-data, using this encoding method will process form data in a binary stream. This encoding method will also encapsulate the content of the file specified by the file domain into the request parameters.
    (3) Text/plain. This encoding method is more convenient when the action attribute of the form is mailto: URL. This method is mainly suitable for sending mail directly through the form.

1. Form example,
rendering
Insert picture description here
JSP code:

<font color="red"><s:actionerror/></font>
<form action="${pageContext.request.contextPath}/UserAction_login"  "return check(this);" method="post" enctype="multipart/form-data">
	<table align="center" border="1">
		<tr>
			<td bgcolor="#bbbbbb">用户名:</td>
			<td><input type="text" name="id"/></td>
		</tr>
		<tr>
			<td bgcolor="#bbbbbb">密&nbsp;&nbsp;&nbsp;&nbsp;码:</td>
			<td><input type="password" name="pwd"/></td>
		</tr>
		<tr>
			<td bgcolor="#bbbbbb">照&nbsp;&nbsp;&nbsp;&nbsp;片:</td>
			<td><input type="file" name="photo"/></td>
		</tr>
		<tr>
			<td colspan="2" align="center"><input type="submit"  value="登录">&nbsp;&nbsp;<input type="reset" value="重置"></td>
		</tr>
		</table>
	</form>

If you use struts2 tags, you need to introduce the struts2 tag library

<%@ taglib prefix="s" uri="/struts-tags"%>

2.action code

package com.action;


import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.valueBean.User;

public class UserAction extends ActionSupport{
	//封装除了文件的其他信息
	private String id;
	private String pwd;
	
	//封装上传的文件对象
	private File photo;
	//上传的文件类型   固定格式xxxContentType
	private String photoContentType;
	//上传的文件名   固定格式xxxFileName
	private String photoFileName;

	//生成唯一的文件名(该方法在上传的文件名不重复时可以不需要)
	private String uniqueFileName(String FileName) {
	
		//通过时间获得唯一的字符串(不修改日期时间情况下唯一)
		DateFormat format = new SimpleDateFormat("yyMMddHHmmss");
		String formatDate = format.format(new Date());
		
		//获得.最后出现的位置,分割文件名和后缀名
		int position = photoFileName.lastIndexOf(".");
		String extension = photoFileName.substring(position);
		
		return formatDate + extension;
	}
	
	//处理请求的方法
	public String login() throws Exception {
		//判断登录信息(为了方便理解,这里使用固定的用户名密码判断)
		if(id.equals("admin") && pwd.equals("123456")) {	
			ActionContext.getContext().getSession().put("id","admin");
			/*
			 *获得存放的绝对路径(注意,如果存放在项目的文件夹下服务器重启会消失,
			 * 若要永久保存,可放至固定目录如:String realPath = "c:/images";)
			*/
			String realPath = ServletActionContext.getServletContext().getRealPath("/photo");
			//自动生成唯一的文件名(若文件名不重复时可使用一下注释的代码并不需要编写 uniqueFileName方法)
			String realFileName = uniqueFileName(photoFileName);
			File real = new File(realPath,realFileName);
			//不重复时代码
			/*
			File real = new File(realPath,photoFileName);
			*/
			
			//判断路径是否存在,不存在的话自动创建
			if(photo != null)
				if(!real.getParentFile().exists())
					real.getParentFile().mkdirs();
					
			//拷贝photo文件内容到real
			FileUtils.copyFile(photo, real);
			
			return "loginSuccess";
			}
		else {
			ActionContext.getContext().put("error", "用户名或密码错误!");
			return "loginLose";
		}	
	}
	
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public File getPhoto() {
		return photo;
	}
	public void setPhoto(File photo) {
		this.photo = photo;
	}
	public String getPhotoContentType() {
		return photoContentType;
	}
	public void setPhotoContentType(String photoContentType) {
		this.photoContentType = photoContentType;
	}
	public String getPhotoFileName() {
		return photoFileName;
	}
	public void setPhotoFileName(String photoFileName) {
		this.photoFileName = photoFileName;
	}
}

3. Configuration file struts.xml information

<struts>
	<package name="login" namespace="/" extends="struts-default">
			<action name="UserAction_*" class="com.action.UserAction" method="{1}">
				<result name="loginSuccess">/welcome.jsp</result>
				<result name="loginLose" >/login.jsp</result>
				<!-- 错误信息返回页面  -->
				<result name="input">/{1}.jsp</result>
			</action>
		</package>
	</struts>

4. Set the allowed file type (suffix name) and the maximum file size

<struts>
	<!-- 设置最大允许上传的文件大小(字节),默认2M
	<constant name="struts.multipart.maxSize" value="20480000"></constant>
	  -->
	<package name="login" namespace="/" extends="struts-default">
			<action name="UserAction_*" class="com.action.UserAction" method="{1}">
			<interceptor-ref name="defaultStack">
				<!-- 设置允许上传的文件类型(允许使用通配符) -->
				<param name="fileUpload.allowedTypes">image/*</param>
				
				<!-- 设置允许上传的文件后缀名
				<param name="fileUpload.allowedExtensions">.jpg,.png</param>
				 -->
			</interceptor-ref>
				<result name="loginSuccess">/welcome.jsp</result>
				<result name="loginLose" >/login.jsp</result>
				<!-- 错误信息返回页面  -->
				<result name="input">/{1}.jsp</result>
			</action>
		</package>
	</struts>

Errors need to be displayed after configuration. You need to use <s:actionerror></s:actionerror> to display on the page you jump to

5. Setting error Chinese display
Familiar, split error prompt
Insert picture description here
as shown, error number
0: field name
1. file name
2. temporary file name
3. file type

The default error message prompt location is struts2-core.jar\org.apache.struts2\struts-message.properties The
Insert picture description here
drawing is the default error message for several countries (no Chinese)

Take struts-messages_en.properties as an example to expand. It
can be seen that the error message is composed of value keys
Insert picture description here
. The three lines of code in the picture are more commonly used error displays.
31. The file exceeds the maximum value of
32. The file type is not allowed to submit.
33. The file extension is not Suffixes allowed to be submitted
where {0}, {1}, {2}, {3} correspond to the error sequence number of the previous error message diagram

After understanding, we create a UserUpload.properties (xxx.properties) file in src (or under the src package), and then we can imitate the default information to write a custom error message (the system will convert the input Chinese into hexadecimal)
example content

struts.messages.error.content.type.not.allowed="{1}"\u4E0D\u662F\u56FE\u7247\u7C7B\u578B
struts.messages.error.file.extension.not.allowed="{1}"\u540E\u7F00\u540D\u4E0D\u6EE1\u8DB3\u683C\u5F0F

Internationalization must be configured in struts.xml to take effect.
After adding, the code of struts.xml is

<struts>
	<!-- 配置国际化 -->
	<constant name="struts.custom.i18n.resources" value="UserUpload"></constant>
	<!-- 设置最大允许上传的文件大小(字节),默认2M
	<constant name="struts.multipart.maxSize" value="20480000"></constant>
	  -->
	<package name="login" namespace="/" extends="struts-default">
			<action name="UserAction_*" class="com.action.UserAction" method="{1}">
			<interceptor-ref name="defaultStack">
				<!-- 设置允许上传的文件类型(允许使用通配符) -->
				<param name="fileUpload.allowedTypes">image/*</param>
				
				<!-- 设置允许上传的文件后缀名
				<param name="fileUpload.allowedExtensions">.jpg,.png</param>
				 -->
			</interceptor-ref>
				<result name="loginSuccess">/welcome.jsp</result>
				<result name="loginLose" >/login.jsp</result>
				<!-- 错误信息返回页面  -->
				<result name="input">/{1}.jsp</result>
			</action>
		</package>
	</struts>

Demo picture
Insert picture description here

6. Multi-file upload (steps are given here, no detailed introduction)
1. Multi-file upload only needs to set multiple file upload elements or struts2 tags in JSP <s:file label="xxx" name="xxx"/ >
2. The three fields of the received file in the action code are all changed to an array type (re-injection of get and set methods)
3. Part of the logic is processed

File download (dynamic download is used here, if you use static, just replace fileName with a fixed value)
Compared with file upload, file download is much simpler (personally think)
file download is actually a result type (Stream)
JSP code

	<s:form action="UserAction_download">
	<s:textfield label="输入下载的文件名(含后缀名)" name="fileName"/>
	<s:submit value="下载"></s:submit>
	</s:form>

action code

package com.action;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
	//提供输入流,需要get方法,set文件下载时方法可有可无
	private InputStream inputStream;
	private String fileName;
	public String download() throws FileNotFoundException, UnsupportedEncodingException {
		//将文件转为输入流
		String path = "H:/JAVAEE/images/" + fileName;
		inputStream = new FileInputStream(path);
		
		//由于重新转到网页,所以文件名含中文时需要行url转码
		fileName = URLEncoder.encode(fileName,"UTF-8");
		return "download";
	}
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public InputStream getInputStream() {
		return inputStream;
	}
}

struts.xml code

<struts>
	<package name="login" namespace="/" extends="struts-default">
		<action name="UserAction_*" class="com.action.UserAction" method="{1}">
					<result name="download" type="stream">
						<!-- 配置输出流 -->
						<param name="inputName">inputStream</param>
						<!-- 设置响应头消息,使浏览器以下载方式打开 固定格式:attachment;filename=xxx  -->
						<param name="contentDisposition">attachment;filename=${fileName}</param>
						<!-- 设置响应头消息,告诉浏览器响应正文的MIME类型  固定格式:application/octet-stream -->
						<param name="contentType">application/octet-stream</param>
					</result>
		</action>
	</package>
</struts>

Demo picture
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_42301302/article/details/88915822