目录标题
Struts2的核心配置
Struts2常量配置
常量配置
1.在default.properties 中配置
默认值,不会在该配置文件中配置
2.在struts.properties中配置
基本不会在该配置文件中配置
###设置默认编码集为UTF-8,作用于HttpServletRequest的setCharacterEncoding方法
struts.i18n.encoding=UTF-8
###设置action请求的扩展名为action或者没有扩展名,该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开
struts.action.extension=action,,
###设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭
struts.serve.static.browserCache=true
### 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用)
struts.configuration.xml.reload=false
###设置不使用开发者模式,开发模式下使用,这样可以打印出更详细的错误信息
struts.devMode = false
###设置不开启动态方法调用
struts.enable.DynamicMethodInvocation=false
3.在struts.xml中配置
开发中基本上都在该配置文件中配置常量
通过<constant>
元素来配置常量,该标签写<struts>
下面,和<package>
标签同级
<!-- 声明常量 -->
<constant name="" value=""></constant>
示例:
<struts>
<!-- 声明常量 -->
<!--设置默认编码集UTF-8,解决post请求乱码-->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!--设置使用开发者模式-->
<constant name="struts.devModel" value="true"></constant>
<!-- 设置后缀 -->
<constant name="struts.action.extension" value="action,,"> </constant>
<struts>
4.在web.xml中配置
配置核心过滤器StrutsPrepareAndExecuteFilter时,通过初始化参数来配置常量,通过<filter>
元素的<init-param>
子元素指定常量
<filter>
<!--指定struts2的核心过滤器-->
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!--通过init-param元素配置struts2常量,设置开发者模式-->
<init-param>
<param-name>struts.devModel</param-name>
<param-value>true</param-value>
</init-param>
</filter>
基本不会在该配置文件中配置
`
配置文件加载顺序
1、default.properties:在该文件保存在struts2-core-2.3.37.jar中org/apache/struts2包下。
2、struts-default.xml:在核心的jar包struts2-core-2.3.37.jar的最下方,struts2框架的核心功能都是在该配置文件中配置的。
3、struts-plugin.xml配置文件。
4、struts.xml:在src的目录下,该文件是Web应用自己的配置的配置文件
5、struts.properties:该文件是Web应用默认的Struts2的配置文件
6、web.xml:该文件是Web应用的的配置文件
后加载的配置文件会覆盖掉之前加载的配置文件
核心配置文件
在struts2中struts.xml是核心配置文件,struts.xml文件中包含三个标签
package标签
与java中的包不同,类似一个代码包,区别不同的action。
package标签属性:
- name:包的名称,区分不同的package,管理action配置
- namespace:名称空间,一般与标签中的name属性共同决定访问路径
namespace=”/” – 根名称空间,不写默认也是“/”。
namespace=”/aaa” – 带有名称的名称空间,访问时必须带上才能访问action
- extends:继承,可以继承其他的包,只要继承了,那么该包就包含了其他包的功能,一般都是继承struts-default
action标签
action标签主要配置action的访问路径
action的标签属性:
- name:action的名称,区分不同的action,和package标签中的namespace属性构成了访问路径
- class:配置Action类的全路径全路径=包名+类名,通过反射的原理去执行该类的,默认值是ActionSupport类
- method : Action类中执行的方法,如果不指定,默认值是execute
result标签
根据action中的方法返回值,将页面定位到指定的页面或action上
result标签的属性:
- name属性:和你方法的返回值要一样
- type – 结果类型,有4个值:dispatcher(默认)、redirect、chain、redirectAction
dispatcher(默认)和redirect:result标签中“/”代表的是项目根路径,不写就代表当前路径下
chain和redirectAction:result标签中“/”没有任何意义,不需要写,写了就是多余,也就是只能从当前路径去指定页面!!!
chain:只能转发到同一命名空间下的Action
redirect:可以重定向到action中去,也可以重定向到显示页面中去
struts配置文件分离
用于按模块开发,在struts.xml配置文件中使用<include file=" "/>
包含指定的文件夹
案例1:有两个配置文件struts-part1.xml和struts-part2.xml,可以在struts.xml中配置:
<struts>
<include file="struts-part1.xml"/>
<include file="struts-part2.xml"/>
</struts>
案例2:在cn.itcast.action.demo包下有一个配置文件struts_demo.xml,引入该配置文件到struts.xml中
<struts>
<include file="cn/itcast/action/demo/struts_demo.xml"/>
</struts>
Action的配置
实现Action控制类
Action类的书写格式有三种方法
方法一: Action类可以不继承特殊的类或不实现任何特殊的接口或者父类,仅仅是一个POJO,即简单的Java对象(Plain Ordinary Java Object) ,要有一个公共的无参的构造方法和一个execute方法
代码如下:
package cn.itcast.action;
public class HelloWorldAction {
public String execute (){
return "success";
}
}
方法二: 创建一个类去实现指定的一个接口:com.opensymphony.xwork2.Action
这个接口中只有一个抽象方法
public abstract String execute()throws Exception;
同时还有5个String类型的静态属性:ERROR、SUCCESS、INPUT、NONE、LOGIN
常量:
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = “login”;
代码如下:
package cn.itcast.action;
import com.opensymphony.xwork2.Action;
public class HelloWorldAction implements Action{
public String execute ()throws Exception{
return SUCCESS;
}
}
方法三: 继承一个指定的父类:com.opensymphony.xwork2.ActionSupport
ActionSupport类本身实现了Action接口,是Struts2中默认的Action接口的实现类,所以继承ActionSupport就相当于实现了Acton接口,并提供了数据的校验。
代码如下:
package cn.itcast.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorldAction extends ActionSupport{
public String execute ()throws Exception{
return SUCCESS;
}
}
struts.xml配置
<package name="struts2_1" namespace="/" extends="struts-default">
<!-- 使用pjo完成action操作 -->
<action name="action1" class="cn.itcast.action.Demo1Action">
<result >/success.jsp</result>
</action>
<!-- 实现Action类来完成action操作 -->
<action name="action2" class="cn.itcast.action.Demo2Action">
<result >/success.jsp</result>
</action>
<!-- 通过继承ActionSupport来完成action操作 -->
<action name="action3" class="cn.itcast.action.Demo3Action">
<result >/success.jsp</result>
</action>
</package>
在开发中,第三种方法经常用到
通配符配置Action类
先写一下常规写法
新建一个BookAction类
package cn.itcast.action;
import com.opensymphony.xwork2.ActionSupport;
public class BookAction extends ActionSupport{
public String add(){
System.out.println("Book add");
return SUCCESS;
}
public String delete(){
System.out.println("Book delete");
return SUCCESS;
}
public String update(){
System.out.println("Book update");
return SUCCESS;
}
public String find(){
System.out.println("Book find");
return SUCCESS;
}
}
book.jsp
<body>
<a href="/FirstStruts3/book/add">book add</a></br>
<a href="/FirstStruts3/book/delete">book delete</a></br>
<a href="/FirstStruts3/book/update">book update</a></br>
<a href="/FirstStruts3/book/find">book find</a></br>
</body>
在struts.xml配置
<package name="struts2_2" namespace="/book" extends="struts-default">
<!--常规Action配置-->
<action name="add" class="cn.itcast.action.BookAction" method="add">
<result >/success.jsp</result>
</action>
<action name="delete" class="cn.itcast.action.BookAction" method="delete">
<result >/success.jsp</result>
</action>
<action name="update" class="cn.itcast.action.BookAction" method="update">
<result >/success.jsp</result>
</action>
<action name="find" class="cn.itcast.action.BookAction" method="find">
<result >/success.jsp</result>
</action>
</package>
跑一下项目,都打印出来了
在使用struts2时,每一个action都需要配置,每一个action里面的方法以及其返回到的界面都需要配置,如果一个一个配置,就太麻烦了,这里我们可以约定一些命名规范,然后再struts.xml里面使用通配符配置。
<package name="struts2_2" namespace="/book" extends="struts-default">
<!--使用通配符的Action配置-->
<action name="*" class="cn.itcast.action.BookAction" method="{1}">
<!--{1}代表匹配一个*-->
<result >/success.jsp</result>
</action>
</package>
也可以成功
Action的动态方法调用
https://blog.csdn.net/weixin_40544356/article/details/81631336
在实际生活中,Action太多不便管理,为了减少Action,通常在一个Action中编写不同的方法处理不同的请求,如编写LoginAction,其中login()方法处理登陆请求,register()方法处理注册请求,此时可以采用动态方法调用来处理。
在使用动态方法调用时,在Action的名字中使用!
符号来标识要调用方法的名称,语法格式如下:
<form action="Action名称!方法名称">
使用动态方法调用将请求提交给Action时,表单中的每个按钮提交事件都交给同一个Action,只是对应Action中的不同方法。只需要在struts.xml中只要配置该Action
<action name="Action名字" class="包名.Action类名">
<result">/test.jsp</result>
</action>
当开启动态方法调用功能时,应当将下面的常量置为true
<!-- 动态方法调用是否开启,默认是关闭的 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false"></constant>
不推荐使用动态方法调用,因为会存在安全隐患。
访问Servlet API的方法
https://blog.csdn.net/iii_am_haomiaozi/article/details/83757534
通过ActionContext类访问
truts2提供了ActionContext类,struts2可以通过该类来实现与Servlet API的访问。
ActionContext类提供了如下几种方法:
方法说明 | 功能描述 |
---|---|
Object get(Object key) | 类似于调用HttpServletRequest的getAttribute(String name)方法 |
Map getApplication() | 返回一个Map对象,该对象模拟了该应用的ServletContext实例 |
static ActionContext getContext() | 这是个静态方法 获取系统的ActionContext实例 |
Map getParameters() | 获取所有的请求参数,类似于调用HttpServletRequest对象的getParameterMap()方法 |
Map getSession() | 返回一个Map对象,该对象模拟了HttpSession 实例 |
void setApplication(Map application) | 传入一个Map实例,将Map实例的key-value转换成application的属性名-值。 |
void setSession(Map session) | 传入一个Map实例,将Map实例的key-value转换成application的属性名-值。 |
实例1:通过ActionContext类实现登陆
LoginAction.java
package cn.itcast.action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String execute() throws Exception {
ActionContext context=ActionContext.getContext();
if("admin".equals(username)&&"123456".equals(password)){
context.put("username", username);
context.put("password", password);
context.put("success", "用户登录成功!");
return SUCCESS;
}else{
context.put("error", "用户登录失败!");
return ERROR;
}
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>FirstStruts2</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.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 指定Struts2配置文件的D2T信息 -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="LoginDemo" extends="struts-default" namespace="/">
<action name="login" class="cn.itcast.action.LoginAction">
<result name="success">/success.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
</struts>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登陆页面</title>
</head>
<body>
<div align="center">
<form action="login" method="post">
账号:<input type="text" name="username"/></br>
密码:<input type="password" name="password"/></br>
<input type="submit" value="登陆"/></br>
</form>
</div>
</body>
</html>
success.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>
<title>登陆成功页面</title>
</head>
<body>
<div algin=center>通过ActionContext类访问Servelt API</div>
<p>${success }<br></p>
<h2>用户登录信息</h2>
用户名:${username }<br>
密 码:${password }<br>
</body>
</html>
error.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>
<title>登陆失败页面</title>
</head>
<body>
<p>${error }<br></p>
</body>
</html>
发布项目访问login.jsp
输入错误的账号密码,提示登陆失败
输入正确的用户名admin和密码123456,提示登陆成功
从返回用户信息,可以看出来,在Action中放入ActionContext的key-value键值对被提取出来了,说明struts2可以通过ActionContext类访问Servlet API。
通过特定接口访问
Struts2框架提供了ActionContext来访问Servlet API,但无法直接获得Servlet API实例,Struts2提供如下几个接口使Action可以直接访问到Servlet API:
接口 | 功能描述 |
---|---|
ServletContextAware | 实现该接口的Action可以直接访问Web应用的ServletContext实例 |
ServletRequestAware | 实现该接口的Action可以直接访问Web应用的ServletRequest实例 |
ServletResponseAware: | 实现该接口的Action可以直接访问Web应用的ServletRsponse实例 |
实例2:
AwareAction.java
package cn.itcast.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class AwareAction extends ActionSupport implements ServletRequestAware{
HttpServletRequest request;
public void setServletRequest(HttpServletRequest request) {
this.request=request;
}
public String execute() throws Exception {
request.setAttribute("message", "通过ServletRequestAware接口实现了访问Servlet API的访问");
return SUCCESS;
}
}
struts.xml配置
<struts>
<package name="AwareDemo" extends="struts-default">
<action name="aware" class="cn.itcast.action.AwareAction">
<result name="success">/message.jsp</result>
</action>
</package>
</struts>
message.jsp
<body>
<div algin="center">${requestScope.message}</div>
</body>
发布项目,访问aware
可以看出,使用ServletRequestAware接口顺利访问Servlet API了的
通过ServletActionContext访问
Struts2还提供了一个ServletActionContext工具类用来访问Servlet API。该类包含了一下几个静态方法:
方法 | 描述 |
---|---|
static PageContext getPageContext() | 取得Web应用的PageContext对象 |
static HttpServletRequest getRequest() | 取得Web应用的?HttpServletRequest对象 |
static HttpServletResponse getResponse() | 取得Web应用的HttpServletResponse对象 |
static ServletContext getServletContext() | 取得Web应用的ServletContext对象 |
实例3:
ContextAction.java
package cn.itcast.action;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class ContextAction extends ActionSupport {
public String execute() throws Exception {
ServletActionContext.getRequest().setAttribute("message",
"通过ServletActionContext类直接访问Servlet API");
return SUCCESS;
}
}
struts.xml配置
<struts>
<package name="ContextDemo" extends="struts-default">
<action name="context" class="cn.itcast.action.ContextAction">
<result name="success">/context.jsp</result>
</action>
</package>
</struts>
context.jsp
<body>
<div algin=center>${requestScope.message}</div>
</body>
发布项目,访问context
借助ServletActionContext类的帮助,也可以在Action中直接访问Servlet API,避免了Action实现AxxAction等接口。
在开发中应优先使用ActionContext来避免和Servlet API耦合
Aciton处理请求参数
在Struts2中,页面的请求数据和Action有两种基本的对应方式,分别是字段驱动(FileldDriven)方式和模型驱动(ModelDriven)方式。其中,字段驱动也叫做为属性驱动。
属性驱动
1.基本数据类型字段驱动方式的数据传递:
package cn.hjc.Action;
import com.opensymphony.xwork2.ActionSupport;
public class ActionOne extends ActionSupport {
private String UserName;
private String PassWord;
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public String getPassWord() {
return PassWord;
}
public void setPassWord(String passWord) {
PassWord = passWord;
}
public String execute() throws Exception {
return SUCCESS;
}
2.直接使用域对象字段驱动方式的数据传递
模型驱动
模型驱动,通过实现ModelDriven接口来接受请求参数,Action类必须实现接口,并且要重写getModel()方法,这个方法返回的就是Action所使用的数据模型对象。
Result结果类型
配置 Result
result标签的属性:
- name属性:指定逻辑视图的名称,默认为success。
- type 属性:指定返回的视图资源的类型,不同的类型代表不同的结果输出,默认值是dispatcher。
struts.xml文件中<result>
元素配置代码如下所示:
<action name="loginAction" class="cn.itcast.action.LoginAction">
<result name="success" type="redirect">
<param name="loaction">/success.jsp</param>
</result>
</action>
上述配置,使用了<result>
元素的name、type属性和param子元素。
<param>
子元素的name属性有两个值,分别如下:
属性 | 描述 |
---|---|
location | 指定该逻辑视图所对应的实际视图资源。 |
parse | 指定在逻辑视图资源名称中是否可以使用OGNL表达式。默认值为true,表示可以使用,如果设为false,则表示不支持。 |
上面的配置可以简化为:
<action name="loginAction" class="cn.itcast.action.LoginAction">
<result>/success.jsp</result>
</action>
预定义的结果类型
属性 | 说明 | 对应类 |
---|---|---|
chain | 用来处理Action 链 | com.opensymphony.xwork2.ActionChainResult |
dispatcher | 用来转向页面,通常处理 JSP | org.apache.struts2.dispatcher.ServletDispatcherResult |
redirect | 重定向到一个URL | org.apache.struts2.dispatcher.ServletRedirectResult |
redirectAction | 重定向到一个 Action | org.apache.struts2.dispatcher.ServletActionRedirectResult |
plainText | 显示源文件内容,如文件源码 | org.apache.struts2.dispatcher.PlainTextResult |
freemarker | 处理 FreeMarker 模板 | org.apache.struts2.views.freemarker.FreemarkerResult |
httpheader | 控制特殊 http 行为的结果类型 | org.apache.struts2.dispatcher.HttpHeaderResult |
stream | 向浏览器发送 InputSream 对象,通常用来处理文件下载,还可用于返回 AJAX 数据。 | org.apache.struts2.dispatcher.StreamResult |
velocity | 处理 Velocity 模板 | org.apache.struts2.dispatcher.VelocityResult |
xslt | 处理 XML/XLST 模板 | org.apache.struts2.views.xslt.XSLTResult |
表中例举了Struts2中预定义的全部11种结果类型,其中dispatcher是默认的结果类型,主要用来与JSP整合。其中,dispatcher和redirect是比较常用到的结果集。
dispatcher结果类型
dispatcher结果类型用来表示“转发”到指定结果资源,它是struts2默认的结果类型。
<result name="success" type="dispatcher">
<param name="location" >/success.jsp</param>
<param name="parse" >true</param>
</result>
上面的代码中,location参数用于指定Action执行完毕后要转向的目标资源;parse参数是一个布尔型的值,默认是true,表示解析location参数中的OGNL表达式。
redirect结果类型
redirect结果类型用来重定向到新的结果资源,该资源可以是JSP文件,也可以是Action文件。
对本文上面通过ActionContext类访问Servlet API
标题下面的struts.xml代码进行更改:
<action name="login" class="cn.itcast.action.LoginAction">
<result name="success" type="redirect">/success.jsp</result>
<result name="error" type="dispatcher">/error.jsp</result>
</action>
用户名和密码正确,使用redirect重新定向到success.jsp;用户名和密码错误,使用的是dispatcher的结果类型,跳转到error.jsp。