本文摘自:李刚 著 《轻量级 Java EE企业应用实战 Struts2+Spring+hibernate整合开发》
Struts2的Action没有和任何Servlet API进行耦合,这是Struts2的一个改良之处,因为Struts2 不再和Servlet进行耦合,从而能够更加轻松的测试该Action。
但对于web应用的控制器而言,不访问Servlet API基本是不可能的,例如,跟踪HTTP Session状态等等。Struts2框架提供了一种更轻松的方式来访问Servlet API。在web应用中通常要访问Servlet API的就是HttpServletRequest、HttpSession和ServletContext,这三个类别分别代表JSP内置对象中的request、session和application。
Struts2提供了一个ActionContext类,Struts2的Action通常可以通过该类来访问Servlet API。下面是ActionContext类中包含的几个常用方法:
(1)Object get(Object key): 该方法类似于调用HttpServletRequest的getAttribute(String name)方法。
(2)Map getApplication():返回一个Map对象,该对象模拟了该应用的ServletContext实例。
(3)static ActionContext getContext():静态方法,获取系统的ActionContext实例。
(4)Map getparameters():获取所有的请求参数,类似于调用HttpServletRequest对象的getParameterMap()方法。
(5)Map getSession():返回一个Map对象,该对象模拟一个HttpSession实例。
(6)void setApplication(Map application):直接传入一个Map实例,该Map实例里面的key-value对转换成application的属性名、属性值。
(7)void setSession(Map session):直接传入一个Map实例,该Map实例里面的key-value对转换成session的属性名、属性值。
下列代码将在Action类中通过ActionContext访问Servlet API,该Action中示范了向request、session和application范围设置属性值:
package ppp;
import com.opensymphony.xwork.ActionContext;
public class LoginAction implements Action {
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 ctx = ActionContext.getContext();
// 通过ActionContext访问application范围的属性值
Integer counter = (Integer) ctx.getApplication().get("counter");
if (counter == null) {
counter = 1;
} else {
counter = counter + 1;
}
// 通过ActionContext设置application属性值
ctx.getApplication().put("counter", counter);
// 通过ActionContext设置session属性值
if (getUsername().equals("scott") && getPassword().equals("tiger")) {
// 通过ApplicationContext设置request范围
ctx.put("tip", "服务器提示:您已经成功登陆");
return SUCCESS;
} else {
// 通过ApplicationContext设置request范围
ctx.put("tip", "服务器提示:登陆失败");
return ERROR;
}
}
}
上述代码第29行,该Action试图从application范围内读取counter属性值,如果该属性不存在,则设置counter为1,然后将该属性放置于application范围中;如果该counter属性存在,则将该counter属性值加1——也就实现了一个简单的计数器功能。
上面的Action包含了username和password两个属性,则意味着提交到Action的表单里应该包含username和password两个属性。
struts.xml配置文件代码如下:
<!DOCTYPE struts PUBLIC
“-//Apache Software Foundation//DTD Struts Configuration 2.0//EN”
“http://struts.apache.org/dtds/struts-2.0dtd “>
<struts>
<!—指定全局化资源文件base名 -->
<constant name = “struts.custom.i18n.resources” value = “messageResource”/>
< !—指定国际化编码所使用的字符集 -->
< constant name = “struts.i18n.encoding” value = “GBK”/>
<!—所有的Action定义都应该放在package下-->
<package name = "login " extends = “struts-default”>
<action name = "login" class = “ppp.LoginAction”>
<!--如果处理结果返回error,则对应/error.jsp视图资源-->
<result name = “error”>/error.jsp</result>
<!--如果处理结果返回success,则对应/welcome.jsp视图资源-->
<result name = “success”>/welcome.jsp</result>
</action>
</package>
</struts>
上面的配置文件中,当ppp.LoginAction返回success逻辑视图名后,系统将会使用/welcome作为实际视图资源。/welcome.jsp代码如下:
<%@page language = “java” contentType = “text/html; charset = UTF-8;”%>
<html>
<head>
<titile>成功页面</title>
</head>
<body>
本站访问次数为:${applicationScope.counter}<br>
${sessionScope.user>,您已经登陆!<br>
${requestScope.tip>
</body>
</html>
上面的7、8、9行代码使用了表达式语言来输出application、session和request范围内的指定属性。前提是这些属性存在并且有值,这些值当然只能在前面的Action中设置。