Struts2核心配置

摘要:Struts2框架学习笔记(二)

Struts2的核心配置

Struts2常量配置

常量配置

1.在default.properties 中配置

默认值,不会在该配置文件中配置

2.在struts.properties中配置

基本不会在该配置文件中配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
###设置默认编码集为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>标签同级

1
2
<!-- 声明常量 -->
<constant name="" value=""></constant>

示例:

1
2
3
4
5
6
7
8
9
<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>子元素指定常量

1
2
3
4
5
6
7
8
9
10
<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属性共同决定访问路径
1
2
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
1
2
3
4
dispatcher(默认)和redirect:result标签中“/”代表的是项目根路径,不写就代表当前路径下
chain和redirectAction:result标签中“/”没有任何意义,不需要写,写了就是多余,也就是只能从当前路径去指定页面!!!
chain:只能转发到同一命名空间下的Action
redirect:可以重定向到action中去,也可以重定向到显示页面中去

struts配置文件分离

用于按模块开发,在struts.xml配置文件中使用<include file=" "/>包含指定的文件夹

案例1:有两个配置文件struts-part1.xml和struts-part2.xml,可以在struts.xml中配置:

1
2
3
4
<struts>
<include file="struts-part1.xml"/>
<include file="struts-part2.xml"/>
</struts>

案例2:在cn.itcast.action.demo包下有一个配置文件struts_demo.xml,引入该配置文件到struts.xml中

1
2
3
<struts>
<include file="cn/itcast/action/demo/struts_demo.xml"/>
</struts>

Action的配置

实现Action控制类

Action类的书写格式有三种方法

方法一: Action类可以不继承特殊的类或不实现任何特殊的接口或者父类,仅仅是一个POJO,即简单的Java对象(Plain Ordinary Java Object) ,要有一个公共的无参的构造方法和一个execute方法

代码如下:

1
2
3
4
5
6
7
8
package cn.itcast.action;

public class HelloWorldAction {
public String execute (){
return "success";

}
}

方法二: 创建一个类去实现指定的一个接口:com.opensymphony.xwork2.Action

这个接口中只有一个抽象方法

1
public abstract String execute()throws Exception;

同时还有5个String类型的静态属性:ERROR、SUCCESS、INPUT、NONE、LOGIN

常量:

1
2
3
4
5
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”;

代码如下:

1
2
3
4
5
6
7
8
9
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接口,并提供了数据的校验。

代码如下:

1
2
3
4
5
6
7
8
9
package cn.itcast.action;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport{
public String execute ()throws Exception{
return SUCCESS;
}
}

struts.xml配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<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类

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
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

1
2
3
4
5
6
<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配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<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里面使用通配符配置。

1
2
3
4
5
6
7
<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的动态方法调用

在实际生活中,Action太多不便管理,为了减少Action,通常在一个Action中编写不同的方法处理不同的请求,如编写LoginAction,其中login()方法处理登陆请求,register()方法处理注册请求,此时可以采用动态方法调用来处理。

在使用动态方法调用时,在Action的名字中使用!符号来标识要调用方法的名称,语法格式如下:

1
<form action="Action名称!方法名称">

使用动态方法调用将请求提交给Action时,表单中的每个按钮提交事件都交给同一个Action,只是对应Action中的不同方法。只需要在struts.xml中只要配置该Action

1
2
3
<action name="Action名字" class="包名.Action类名">
<result">/test.jsp</result>
</action>

当开启动态方法调用功能时,应当将下面的常量置为true

1
2
<!-- 动态方法调用是否开启,默认是关闭的 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false"></constant>

不推荐使用动态方法调用,因为会存在安全隐患。

访问Servlet API的方法

通过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

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
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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

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"%>
<!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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ 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

1
2
3
4
5
6
7
8
9
10
11
<%@ 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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配置

1
2
3
4
5
6
7
<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

1
2
3
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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配置

1
2
3
4
5
6
7
<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

1
2
3
<body>
<div algin=center>${requestScope.message}</div>
</body>

发布项目,访问context
在这里插入图片描述
借助ServletActionContext类的帮助,也可以在Action中直接访问Servlet API,避免了Action实现AxxAction等接口。

在开发中应优先使用ActionContext来避免和Servlet API耦合

Aciton处理请求参数

在Struts2中,页面的请求数据和Action有两种基本的对应方式,分别是字段驱动(FileldDriven)方式和模型驱动(ModelDriven)方式。其中,字段驱动也叫做为属性驱动。

属性驱动

1.基本数据类型字段驱动方式的数据传递:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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>元素配置代码如下所示:

1
2
3
4
5
<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,则表示不支持。

上面的配置可以简化为:

1
2
3
<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默认的结果类型。

1
2
3
4
<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代码进行更改:

1
2
3
4
<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。