Struts2的核心是什么?它和Servlet的关系是什么?
Struts2的核心是interceptor(拦截器);Struts2将Servlet注入到Action中,他们不存在依赖关系。
搭建struts2的步骤
1.首先到官网下载struts2的源码,在其lib中找到所需要的jar包
2.struts所需的依赖:
commons-io
commons-fileupload
commons-lang3
javassist
关键包
struts2-core
xwork-core
ognl----依赖于-->commons-lang3-->commons-fileupload-->commons-io
freemaker-->使用的就是ognl
3.在项目的编译根目录创建固定名称:(struts.xml)配置文件
4.在web.xml中配置struts2的启动过滤器
开始搭建struts2框架并实现文件上传和下载
1.创建maven项目
选则webapp那一项,点击next,输入Group Id 和 Artifact Id.点击finish
当我们创建好了之后会发现一个问题那就是Java Resources中只有一个原文件夹,我们只需要选中项目右键build path,将红圈的勾取消掉然后apply在ok就好了。
正确如下图:
2.在pom.xml中添加依赖:
maven中只需要添加三个依赖就可以了:struts2-core;xwork-core;javassist。我们可以在https://mvnrepository.com/中的所有依赖。如下图:
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jsp-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 这是strust基本的依赖 -->
<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-core -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.16.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.javassist/javassist -->
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.20.0-GA</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.struts.xwork/xwork-core -->
<dependency>
<groupId>org.apache.struts.xwork</groupId>
<artifactId>xwork-core</artifactId>
<version>2.3.16.3</version>
</dependency>
<!-- 这是strust基本的依赖end -->
3. 在项目的编译根目录创建固定名称:(struts.xml)配置文件
在src/main/resources中创建struts.xml文件,并且在其中添加检查头dtd,在jar中找到该头部,放进struts.xml中,并且定义根节点
如下图:
4.在web.xml中配置struts2的启动过滤器,配置只有后缀为.do的才处理
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 过滤器,只有后缀为do的才能通过请求 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<!-- /*:过滤所有
*.do:过滤后缀为do的映射
-->
<url-pattern>*.do</url-pattern>
</filter-mapping>
<!-- 配置启动项目时进入的页面,不配置时默认为index.jsp -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
以上struts2就简单的搭建完成了,可以启动一下,如果不报错就没有问题了。接下来就进行开发文件上传和下载。
1.首先创建一个hello.jsp里面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!--使用jstl标签, maven必要添加的东西 --> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@page isELIgnored="false" %> <!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>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/hello/uploadAction.do" method="post" enctype="multipart/form-data"> <input type="file" name="upload"/> <input type="submit" value="上传"/> 上传结果 :${message}<br> <a href="downloadAction.do">下载列表</a> </form> </body> </html>
创建对应的action类,出来请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14package com.action; /** *用于处理用户请求的类 * @author zy * */ public class HelloAction { //定义处理用户请求的方法:public String 方法名(){} public String sayHello(){ //success对应于struts.xml的result节点的name return "success"; } }
在struts.xml中配置action:
<!-- 更改struts2的默认请求后缀:action 或者是 空 -->
<constant name="struts.action.extension" value="do"></constant>
<!-- name:用于继承,唯一标识
namespace:命名空间用于区别同一包下的相同action
-->
<package name="pkg" extends="struts-default" namespace="/hello">
<!-- action->的name:可以理解为servlet中的 映射路径
映射路径:地址栏中项目名之后的则为映射路径
-->
<action name="hello" class="com.action.HelloAction" method="sayHello">
<result name="success">/WEB-INF/hello.jsp</result>
</action>
</package>
<!-- 访问路径:http://localhost:8080/Struts2Demo/hello/hello.do
项目路径:http://127.0.0.1:8080/Struts2Demo
命名空间:/hello
action:/hello
后缀.do
-->
</struts>
xml中的<constant name="struts.action.extension" value="do"></constant>的struts.action.extension是常量,也是在struts2-core的jar包中/org/apache/struts2/default.properties中定义的,还包含了上传文件大小限制等常量。
2.文件上传对应的action
先创建一个常量类
1
2
3
4
5
6
7
8
9
10package com.constant; /** * 常量类 * @author zy * */ public class Constant { public static final String UPLOAD_PATH="/files/upload"; }
再创建处理上传的action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64package com.action; import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.struts2.ServletActionContext; import com.constant.Constant; import com.opensymphony.xwork2.ActionContext; public class UploadAction { /** * 通过struts2的fileupload拦截器获取file和filename * upload是前台页面中的name * uploadFileName中的xxFileName是固定的 * 并且要生成对应的set和get方法组 * @author zy * */ private File upload; private String uploadFileName; public File getUpload() { return upload; } public void setUpload(File upload) { this.upload = upload; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; } //定义处理上传的方法 public String upload(){ //业务处理 //获取服务器端文件上传的路径 String realPath = ServletActionContext.getServletContext().getRealPath(Constant.UPLOAD_PATH); //判断路径是否存在 File fileSave=new File(realPath); if(!fileSave.exists()){ fileSave.mkdirs(); } //判断文件是否存在 if(upload!=null){ //在服务器端创建空白文件 File saveFile=new File(fileSave, uploadFileName); //使用工具类完成文件内容拷贝 try { FileUtils.copyFile(upload, saveFile); ActionContext.getContext().put("message", "文件成功"); } catch (IOException e) { ActionContext.getContext().put("message", "文件失败"); e.printStackTrace(); } }else{ ActionContext.getContext().put("message", "请选择上传文件"); } return "upload"; } }
3.创建下载页面和处理进入该下载页面的action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@page isELIgnored="false" %> <!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>Insert title here</title> </head> <body> <ul> <c:forEach items="${files }" var="file"> <li><a href="${pageContext.request.contextPath }/download/downloadFile.do?fileName=${file.name}">${file.name}</a></li> </c:forEach> </ul> </body> </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39package com.action; import java.io.File; import java.util.Arrays; import java.util.List; import org.apache.struts2.ServletActionContext; import com.constant.Constant; public class DownloadAction { private List<File> files; public List<File> getFiles() { return files; } public void setFiles(List<File> files) { this.files = files; } /** * 定义请求处理 */ public String download(){ //获取服务器端文件上传的路径 String realPath = ServletActionContext.getServletContext().getRealPath(Constant.UPLOAD_PATH); //判断路径是否存在,当没有上传文件时就点击下载列表 File downloadFile=new File(realPath); if(!downloadFile.exists()){ //创建目录 downloadFile.mkdirs(); } File[] files2 = downloadFile.listFiles(); setFiles(Arrays.asList(files2)); return "download"; } }
4.创建实现下载的action
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82package com.action; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.constant.Constant; /** * 文件下载处理类 * @author zy * */ public class DownloadFileAction { /** * 下载请求处理方法 */ public String downloadFile(){ //获取服务器端文件上传的路径 String realPath = ServletActionContext.getServletContext().getRealPath(Constant.UPLOAD_PATH); //获取文件名称 String fileName = ServletActionContext.getRequest().getParameter("fileName"); //将文件装换成流 try { // 读出文件到i/o流 File file = new File(realPath+"/"+fileName); InputStream inputStream=new FileInputStream(file); BufferedInputStream buf=new BufferedInputStream(inputStream); //获取request HttpServletResponse response = ServletActionContext.getResponse(); // 设置response的编码方式 response.setContentType("application/x-msdownload"); response.setCharacterEncoding("utf-8"); // 设置附加文件名 response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "iso-8859-1")); // 从response对象中得到输出流,准备下载 ServletOutputStream outputStream = response.getOutputStream(); byte[] by=new byte[1024];// 相当于我们的缓存 int k=0;// 该值用于计算当前实际下载了多少字节 // 开始循环下载 while(k<file.length()){ int i = buf.read(by, 0, 1024); k+=i; // 将b中的数据写到客户端的内存 outputStream.write(by, 0, i); } // 将写入到客户端的内存的数据,刷新到磁盘 outputStream.flush(); outputStream.close(); buf.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } /** * java.lang.IllegalStateException: getOutputStream() has already been called for this response *是web容器生成的servlet代码中有out.write(""),这个和JSP中调用的 response.getOutputStream()产生冲突.即Servlet规范说明,不能既调用 response.getOutputStream(),又调用response.getWriter(),无论先调用哪一个,在调用第二个时候应会抛出 IllegalStateException,因为在jsp中,out变量实际上是通过response.getWriter得到的,你的程序中既用了 response.getOutputStream,又用了out变量,故出现以上错误。 解决方案:在程序的最后添加: out.clear(); out = pageContext.pushBody(); Struts2中解决办法 直接让action中的处理方法返回null,问题就解决啦!!! */ return null; } }
最后的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>
<!-- 文件上传大小最大为2097152字节即2M-->
<constant name="struts.multipart.maxSize" value="2097152000"></constant>
<!-- 更改struts2的默认请求后缀:action 或者是 空 -->
<constant name="struts.action.extension" value="do"></constant>
<!-- name:用于继承,唯一标识
namespace:命名空间用于区别同一包下的相同action
-->
<package name="pkg" extends="struts-default" namespace="/hello">
<!-- action->的name:可以理解为servlet中的 映射路径
映射路径:地址栏中项目名之后的则为映射路径
-->
<action name="hello" class="com.action.HelloAction" method="sayHello">
<result name="success">/WEB-INF/hello.jsp</result>
</action>
<action name="uploadAction" class="com.action.UploadAction" method="upload">
<result name="upload">/WEB-INF/hello.jsp</result>
</action>
<action name="downloadAction" class="com.action.DownloadAction" method="download">
<result name="download">/WEB-INF/download.jsp</result>
</action>
</package>
<!-- 下载文件配置 -->
<package name="download" extends="struts-default" namespace="/download">
<action name="downloadFile" class="com.action.DownloadFileAction" method="downloadFile">
</action>
</package>
<!-- 访问路径:http://localhost:8080/Struts2Demo/hello/hello.do
项目路径:http://127.0.0.1:8080/Struts2Demo
命名空间:/hello
action:/hello
后缀.do
-->
</struts>
运行截图:虽然界面有点low,但是功能实现了
最后
以上就是害羞猎豹最近收集整理的关于maven搭建struts2框架的全部内容,更多相关maven搭建struts2框架内容请搜索靠谱客的其他文章。
发表评论 取消回复