08 08Struts 2.x file upload

Posted by nonexistence on Sun, 28 Jun 2020 06:52:44 +0200

Article catalog

If your code is developed with standard MVC, it is highly recommended to use SmartUpload. However, if your project code is developed with framework, such as Struts 1.x, Struts 2.x, and Spring MVC, you can only use FileUpload, because these frameworks are convenient for FileUpload processing.

1 Basic upload

If Struts 1.x is used now, a FormFile class is used to receive the uploaded file. However, although this class wraps a lot of content, it is actually redundant, so the upload and receive in Struts 2.x is directly used java.io.File Class, this operation will be more intuitive.
Example: define upload form

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>Upload</title>

  </head>
  
  <body>
  	<form action="UploadAction!insert.action" method="post" enctype="multipart/form-data">
  		Name:&nbsp;<input type="text" name="name"><br>
  		Photo:&nbsp;<input type="file" name="photo"><br>
  		<input type="submit" value="submit">
  	</form>
  </body>
</html>

Then define the UploadAction, but in order to receive the uploaded File, use File to define a photo attribute.
Example: define UploadAction

package org.lks.action;

import java.io.File;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class UploadAction extends ActionSupport {

	private String name;
	private File photo;
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setPhoto(File photo) {
		this.photo = photo;
	}
	
	public void insert(){
		System.out.println("Name:" + this.name + ", Photo:" + this.photo + ", Photo Size:" + this.photo.length());
	}
}

Example: in struts.xml Configure Action

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<package name="UploadAction" namespace="/" extends="struts-default">
		<action name="UploadAction" class="org.lks.action.UploadAction">
		</action>
	</package>
</struts>    

Then run the project code.

June 27, 2020 5:32:35 afternoon com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
//Information: unable to find ' struts.multipart.saveDir ' property setting. Defaulting to  javax.servlet.context .tempdir
Name:lks, 
Photo:D:\Program Files\Tomcat\apache-tomcat-9.0.13\work\Catalina\localhost\StrutsUpload\upload__5785603a_172f51f1af4__8000_00000001.tmp, 
Photo Size:13301
//June 27, 2020 5:32:36 PM com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
//Information: Removing file photo D:\Program Files\Tomcat\apache-tomcat-9.0.13\work\Catalina\localhost\StrutsUpload\upload__5785603a_172f51f1af4__8000_00000001.tmp

At this time, it is found that it can be uploaded successfully, but there is a warning message in it. Because the information upload process implemented in Struts 2.x is as follows: first, the uploaded file will be saved in a temporary folder, and then the file content read in the Action is actually the information content in the temporary folder, but strictly speaking, you should define such temporary folder information yourself.
Example: in struts.properties Temporary save directory defined in file

struts.multipart.saveDir=tempdir

At this time, the file can be uploaded normally.

2 further operation of upload

Although the upload file can be received by Action at this time, and the content of the file can also be obtained, but it can't be saved, because I don't know what the uploaded file is. When using Struts 2.x to upload, the uploaded content is temporarily saved in a storage directory, where the saved file is a randomly generated name.

Name:lks, 
Photo:D:\Program Files\Tomcat\apache-tomcat-9.0.13\work\Catalina\localhost\StrutsUpload\upload__5785603a_172f51f1af4__8000_00000001.tmp, 
Photo Size:13301
//June 27, 2020 5:32:36 afternoon com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
//Information: Removing file photo D:\Program Files\Tomcat\apache-tomcat-9.0.13\work\Catalina\localhost\StrutsUpload\upload__5785603a_172f51f1af4__8000_00000001.tmp

At this time, you cannot know the type of file you uploaded and the original name of the file.

If you want to get the original name and file type of the file, you must define two attributes. If the name of the attribute to receive the uploaded file is photo, you need to define two attributes to receive it:
(1) File name: photoFileName;
(2) File type: photoContentType.
Example: receive file name and file type.

package org.lks.action;

import java.io.File;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class UploadAction extends ActionSupport {

	private String name;
	private File photo;
	private String photoFileName;
	private String photoContentType;
	
	public void setPhotoFileName(String photoFileName) {
		this.photoFileName = photoFileName;
	}
	
	public void setPhotoContentType(String photoContentType) {
		this.photoContentType = photoContentType;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setPhoto(File photo) {
		this.photo = photo;
	}
	
	public void insert(){
		System.out.println("Name:" + this.name + ", Photo:" + this.photo + ", Photo Size:" + this.photo.length());
		System.out.println("Photo Name: " + this.photoFileName);
		System.out.println("File type: " + this.photoContentType);
	}
}

Since the original information of the file can be found, the file can be stored for the user. However, if you want to save the file, you must set a saved directory and generate the file name. Considering all the problems, you can define a class separately, which is specially responsible for saving the file.
Example: tool class for file saving

package org.lks.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

public class UploadFileUtil{
	
	private File uploadFile; //Save the contents of the uploaded file
	private String contentType; //Save the type of uploaded file
	private String fileName; //Build file name
	
	/**
	 * Construct file content and file type for operation
	 * @param uploadFile Contains information about the uploaded file
	 * @param contentType Type of uploaded file
	 */
	public UploadFileUtil(File uploadFile, String contentType) {
		this.uploadFile = uploadFile;
		this.contentType = contentType;
	}
	
	/**
	 * Get the file name, and generate according to uuid
	 * @return Returns a file name that does not repeat
	 */
	public String getFileName(){ //Get the name of the file
		if(this.fileName ==null || "".equals(this.fileName)){
			String fileExt = null; //Extension type of saved file
			if("image/bmp".equalsIgnoreCase(this.contentType)){
				fileExt = "bmp";
			}else if("image/gif".equalsIgnoreCase(this.contentType)){
				fileExt = "gif";
			}else if("image/jpeg".equalsIgnoreCase(this.contentType)){
				fileExt = "jpg";
			}else if("image/png".equalsIgnoreCase(this.contentType)){
				fileExt = "png";
			}
			
			this.fileName = UUID.randomUUID() + "." + fileExt;
		}
		return this.fileName;
	}
	
	public boolean saveFile(String outFilePath) throws IOException{  //Save operation of file
		File file = new File(outFilePath);
		OutputStream output = null;
		InputStream input = null;
		try{
			if(!file.getParentFile().exists()){
				file.getParentFile().mkdirs();
			}
			output = new FileOutputStream(file);
			input = new FileInputStream(this.uploadFile);
			byte data[] = new byte[2048];
			int len = 0;
			while((len = input.read(data, 0, len)) != -1){
				output.write(data,0, len);
			}
			return true;
		}catch(Exception e){
			throw e;
		}finally{
			if(output != null){
				output.close();
			}
			
			if(input != null){
				input.close();
			}
		}
	}
	
	public boolean deleteFile(String filePath){
		return new File(filePath).delete();
	}
}

Then call the method of this class in Action to save the file.
Example: saving information in Action

public void insert(){
		UploadFileUtil ufu = new UploadFileUtil(this.photo, this.photoContentType);
		String fileName = ufu.getFileName();
		System.out.println(fileName);
		String outFilePath = ServletActionContext.getServletContext().getRealPath("/upload/") + fileName;
		try {
			System.out.println(ufu.saveFile(outFilePath));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

For any development code, if it is found that it has been written repeatedly, a good class function design must be carried out.

3 upload restrictions

Now, although the file can be uploaded, there are some restrictions on the upload, that is to say, it has some file size restrictions.

1. Change the size limit of the uploaded file - modify struts.properties file
(1) The following is the default maximum limit for uploading files

struts.multipart.maxSize=2097152

But don't make pictures too big unless you are a professional photo website. But if the file is large, it must display the error, that is to say, you should continue to configure an input path and modify it struts.xml Documents.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<package name="UploadAction" namespace="/" extends="struts-default">
		<action name="UploadAction" class="org.lks.action.UploadAction">
			<result name="input">upload.jsp</result>
		</action>
	</package>
</struts>    

2. At this time, if the file is too large, struts 2.x will default to error operations. However, although error handling is not possible in the large direction, it can be misconfigured in each Action;
Example: modification struts.xml file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<package name="UploadAction" namespace="/" extends="struts-default">
		<action name="UploadAction" class="org.lks.action.UploadAction">
			<interceptor-ref name="fileUpload">
				<param name="maximumSize">10000</param>
				<param name="allowedTypes">
					image/gif,image/jpg,image/jpeg,image/png,image/bmp
				</param>
			</interceptor-ref>
			<interceptor-ref name="defaultStack"></interceptor-ref>
			<result name="input">upload.jsp</result>
		</action>
	</package>
</struts>    

All errors are still stored in the fieldErrors collection.

<h1>${fieldErros['photo'][0] }</h1>

However, the default message of the error output at this time is English, not Chinese. You can define the displayed text in a global resource file.
Example: in Messages.properties Text message defined inside

The file upload of Struts 2.x does consider many situations.

Topics: Struts Java Apache Tomcat