struts.xml配置内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd">
<struts><!-- 是否启用开发模式 --><constant name="struts.devMode" value="true"/><!--<constant name="struts.i18n.encoding" value="utf-8"/>--><package name="interceptor" extends="struts-default" namespace=""><!-- http://localhost:8080/sf/uploadform.action --><action name="uploadform"><result name="success">/WEB-INF/jsp/uploadform.jsp</result></action><action name="upload" class="priv.lwx.struts2.fileupload.web.UploadAction"><!--这个拦截器负责将客户端上传的文件存储到临时的缓存目录下,并且获取临时文件的路径、名称以及文件类型。--><interceptor-ref name="fileUpload"><!--设定上传的文件最大字节数为1M--><param name="maximumSize">1048576</param></interceptor-ref><interceptor-ref name="basicStack"/><!--basicStack这个拦截器栈含有将参数值注入到Action中相应的属性中的拦截器--><result name="success">/WEB-INF/jsp/uploadimage.jsp</result></action></package>
</struts>
BaseAction的代码如下:
package priv.lwx.struts2.fileupload.web;import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.apache.struts2.util.ServletContextAware;import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;/*** description** @author liaowenxiong* @date 2022/5/9 09:36*/public class BaseAction implements SessionAware, ServletRequestAware, ServletResponseAware, ServletContextAware {protected Map<String, Object> session;protected HttpServletRequest request;protected HttpServletResponse response;protected ServletContext application;@Overridepublic void setServletRequest(HttpServletRequest httpServletRequest) {this.request = httpServletRequest;}@Overridepublic void setServletResponse(HttpServletResponse httpServletResponse) {this.response = httpServletResponse;}@Overridepublic void setSession(Map<String, Object> map) {this.session = map;}@Overridepublic void setServletContext(ServletContext context) {this.application = context;}
}
UploadAction的代码如下:
package priv.lwx.struts2.fileupload.web;import org.apache.commons.io.IOUtils;import java.io.*;/*** 实现文件上传功能** @author liaowenxiong* @date 2022/5/13 15:02*/public class UploadAction extends BaseAction {/* 注意:属性 xxxFileName、xxxContentType 是固定的写法,如在 jsp 页面<s:file label="File" name="some" />中的 name=“some”,那么在 UploadAction 中对应的 File 属性名为 some。但是,如果想取到文件名,那么需要写 someFileName,如果想取到文件类型,那么需要写 someContentType。*/private File some;private String someFileName;private String someContentType;private String imagePath;public String execute() throws IOException {System.out.println(application);System.out.println("缓存文件路径:" + this.some);System.out.println("源文件名:" + someFileName);System.out.println("文件类型:" + someContentType);// 生成随机的文件名String imageName = "file_" + System.currentTimeMillis() + someFileName.substring(someFileName.lastIndexOf("."));System.out.println("随机文件名:" + imageName);// 这个值在JSP页面中链接到图片时会使用到imagePath = "upload-image/" + imageName;System.out.println("imagePath:" + imagePath);// 获取目录upload-image的绝对路径String uploadPath = application.getRealPath("upload-image");// 判断目录upload-image是否存在,否则创建该目录File file = new File(uploadPath);if (!file.exists()) {file.mkdirs();}// 将imagePath存储到request对象中// request.setAttribute("imagePath", imagePath);// 将imagePath存储到application对象中application.setAttribute("imagePath", imagePath);// 获取目标文件在服务器主机中的绝对路径String realPath = application.getRealPath(imagePath);System.out.println("文件的绝对路径:" + realPath);// 从缓存中读取图片BufferedInputStream bis = new BufferedInputStream(new FileInputStream(this.some));// 构造指向目标文件的字节输出流对象,用来向目标文件写入数据BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(realPath));// 写入数据到目标文件中IOUtils.copy(bis, bos);bis.close();bos.close();return "success";}public String test() {String imageName = "file_1652507858364.JPG";imagePath = "upload-image/" + imageName;System.out.println("imagePath:" + imagePath);return "success";}public String test1() throws IOException {return execute();}public File getSome() {return some;}public void setSome(File some) {this.some = some;}public String getSomeFileName() {return someFileName;}public void setSomeFileName(String someFileName) {this.someFileName = someFileName;}public String getSomeContentType() {return someContentType;}public void setSomeContentType(String someContentType) {this.someContentType = someContentType;}public String getImagePath() {return imagePath;}public void setImagePath(String imagePath) {this.imagePath = imagePath;}
}
uploadform.jsp 的代码如下:
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件上传</title>
</head>
<body>
<h1>文件上传
</h1>
<s:form action="upload" method="post" theme="xhtml" enctype="multipart/form-data"><s:file label="File" name="some"/><s:submit value="提交"/>
</s:form>
<br/>
<br/>
<br/>
</body>
</html>
uploadimage.jsp 的代码如下:
<%@ page import="java.util.Enumeration" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title>
</head>
<body>
<h1>文件上传成功
</h1>
<%Enumeration<String> attributeNames = request.getAttributeNames();while (attributeNames.hasMoreElements()) {String attributeName = attributeNames.nextElement();System.out.println(attributeName);}
%>
<%--这个EL表达式是去ValueStack中的root对象中获取属性imagePath的值--%>
<img src="${imagePath}"/>
<br/>
<img src="${applicationScope.imagePath}"/>
<br/>
<%--这个OGNL表达式是去ValueStack中的context对象中获取到ServletContext对象,然后再获取该对象中的属性imagePath的值--%>
<img src="<s:property value="#application.imagePath"/>"/>
<br/>
<%--这个OGNL表达式是去ValueStack中的root对象中获取属性imagePath的值--%>
<img src="<s:property value = 'imagePath'/>"/>
<br/>
<%--<s:debug/>--%>
<br/>
<br/>
</body>
</html>