对于Struts2应用中的开发者来说,Action才是整个应用系统的核心,开发者需要提供大量的Action类,并且在struts.xml文件中对Action类进行配置,Action中包含了对用户请求的处理逻辑,因此,我们也称Action为业务控制器。
相对于Struts1而言,Struts2采用的低侵入式的设计,Struts2不要求Action类继承任何的Struts2基类,或者实现任何的Struts2的接口,在这种设计方式下,Struts2的Action类是一个非常普通的POJO(Plain Old Java Objects,译为普通的Java对象。但是通常会包含一个没有参数的execute()方法),从而,有很好的代码复用性。
Struts2通常直接使用Action来封装HTTP请求参数,因此,Action类里面还应该包含与请求参数相对应的属性,并且为这些属性提供getter和setter方法。
比如说,用户请求包含user和password两个请求参数,那么Action就应该提供user和两个属性来封装用户的请求参数,并且为user和password提供对应的getter和setter方法,西面是处理该请求的Action的代码片段。
//处理用户请求的Action类,这个只是一个POJO类
//不需要继承任何的基类,不需要实现任何的接口
public class LoginAction {
//提供两个属性来封装HTTP请求的参数
private String user;
private String password;
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//Action类默认来处理用户请求的方法,execute
public String execute(){
//处理结束,返回一个字符串,这个字符串将对应视图物理资源
return "success";
}
}
上面的Action类只是一个普通的Java类,这个Java类提供了两个属性,user和password,这个两个属性分别对应两个HTTP请求参数。
即使Action需要处理的请求包含user和password两个HTTP请求参数,Action类也是可以不包含user和password两个属性的,因为系统是通过对应的getter和setter方法来处理请求参数的,而不是通过属性的名字来处理请求参数的,也就是说,如果包含user的HTTP请求参数,Action类里面是否包含user属性并不重要,重要的是要包含void setUser(String user)和String getUser()这两个方法。
Action类的属性,不仅可以用于封装请求参数,还可以用于封装处理结果。比如,如果希望将服务器提示的“登录成功”在下一个页面中输出,那么,我们可以在Action类中增加一个tip属性(其他属性名也可以),并且为该属性提供对应的getter和setter方法,也就是为Action类增加如下的代码片段。
//封装服务器提示的tip属性
private String tip;
public String getTip() {
return tip;
}
public void setTip(String tip) {
this.tip = tip;
}
一旦在Action中设置了tip属性的值,我们就可以在下一个页面当中使用struts2标签来输出该属性的值,在jSP页面当中输出tip属性值的代码片段如下。
<!-- 使用Struts2标签来输出tip属性的值 -->
<s:property value=”tip”/>
系统不会严格区分Action里面的哪个属性是用来封装请求参数的属性,哪个事用来封装结果的属性,对于系统来说,封装请求参数和封装处理结果的属性石完全平等的。如果用户的HTTP请求里面包含了tip的请求参数,系统就会调用Action的void setTip(String tip)方法,通过这种方式,名为tip的请求参数就可以传给Action实例,如果Action类里面没有包含对应的方法,那么名字为tip的请求参数也就无法传入该Action。
同样,在JSP页面中输出的Action属性的时候,它也不会区分该属性是用来封装请求参数的还是用于封装处理结果的属性,所以说,使用Struts2的标签既可以输出Action的处理结果,也可以输出Http请求参数值。
下面举一个例子:
这是一个Action类,主要对请求参数进行验证处理。
public class LoginAction implements Action {
//User类型属性封装请求参数
private User user;/自定义/用户类,包含name和pass两个属性
private String tip;//系统提示
//省略user和tip的setter和getter函数
@Override
public String execute() throws Exception {
//通过user属性的name属性和pass属性来判断控制逻辑
if (getUser().getName().equals("Kinga") && getUser().getPass().equals("123")) {
setTip("转换成功");
return SUCCESS;
} else {
setTip("转换失败");
return ERROR;
}
}
}
以下是一个本应用的struts.xml的内容。
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<!-- 指定Struts 2配置文件的根元素 -->
<struts>
<!-- 指定国际化编码所使用的字符集 -->
<constant name="struts.i18n.encoding" value="GBK"/>
<!-- 设置Struts 2为开发者模式 -->
<constant name="struts.devMode" value="true"/>
<!-- 所有的Action定义都应该放在package下 -->
<package name="lee" extends="struts-default">
<action name="login" class="org.crazyit.app.domain.LoginAction">
<!-- 定义三个逻辑视图和物理资源之间的映射 -->
<result name="error">/error.jsp</result>
<result name="success">/welcome.jsp</result>
</action>
</package>
</struts>
这是一个jsp登录页面,填了用户为Kinga,密码为123后,点击“转换”按钮,则系统会将请求提交给login,由LoginAction类处理。
input.jsp页面代码:
<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="GBK"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!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=GBK">
<title>基于OGNL的类型转换</title>
</head>
<body>
<s:form action="login">
<s:textfield name="user.name" label="用户名"/>
<s:password name="user.pass" label="密码"/>
<tr>
<td colspan="2">
<s:submit value="转换" theme="simple"/>
<s:reset value="重填" theme="simple"/>
</td>
</tr>
</s:form>
</body>
</html>
由LoginAction类可知,处理完请求之后,若用户名和密码正确(分别为Kinga和123),则LoginAction会返回逻辑名“success”,其映射到名为“welcome.jsp”的物理视图。
welcome.jsp的页面代码如下:
<%@ page language="java" contentType="text/html; charset=GBK"
pageEncoding="GBK"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>欢迎你</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
</head>
<body>
<s:property value="tip"/>
<s:property value="user.name"/>
欢迎你登录!
<hr/>
</body>
</html>
其他的struts配置在这里不详细说明。运行input.jsp,页面如下:
填上用户名和密码后,点击“转换”,则可以看到如下页面: