本文摘自:李刚 著 《轻量级 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”>
-
- <result name = “error”>/error.jsp</result>
-
- <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中设置。