对于WEB应用的控制器而言,不访问ServletAPI几乎是不可能的,例如跟踪HTTPSession状态等。Struts2框架提供了一种更轻松的方式访问Servlet API。WEB应用中通常需要访问Servlet API就是HttpServletRequest、HttpSession、ServletContext,这三个接口分别代表JSP内置对象中的request、session、application。Struts2提供了ActionContext类来访问Servlet API的。下面列出几个常的方法。
(1). Object get(Object key):该方法类似于调用HttpServletRequest的getAttribute(Stringname)方法。
(2). Map getApplication():返回一个Map对象,该对象模拟了该 应用的ServletContext实例。
(3). static Action getContext():静态方法,获取系统的ActionContext实例。
(4). Map getParameters():获取所有方法的请求。类似于调用HttpServletRequest对象的getParameterMap()方法。
(5). Map getSession():返回一个Map对象,该对象模拟了HttpSession实例
(6). void setApplication(Mapapplication):直接传入一个Map实例,将该Map实例里的key-value对转换成application的属性名、属性值。
(7). void setSession(Map session):直接传入一个Aap实例,将该Map实例里的key-value对转成session的属性名、属性值。
下面笔者给出了具体的例子来说明。
i. 定义Action的类
public class LoginAction implements Action { private String username; private String password; // username的setter和getter方法 public void setUsername(String username) { this.username = username; } public String getUsername() { return this.username; } // password的setter和getter方法 public void setPassword(String password) { this.password = password; } public String getPassword() { return this.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范围的属性 ctx.getSession().put("user" , getUsername()); if (getUsername().equals("owen") && getPassword().equals("owen") ) { // 通过ActionContext设置request范围的属性 ctx.put("tip" , "服务器提示:您已经成功的登录"); return SUCCESS; } // 通过ActionContext设置request范围的属性 ctx.put("tip" , "服务器提示:登录失败"); return ERROR; } }
ii. 配置struts.xml.(跟前面一样,此处省略)
iii. 创建物理视图
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>成功页面</title> </head> <body> 本站访问次数为:${applicationScope.counter}<br/> ${sessionScope.user},您已经登录!<br/> ${requestScope.tip} </body> </html>
虽然Struts2提供了ActionContext来访问ServletAPI,但这种访问毕竟不是直接获得Servlet API的实例。为了在Action中直接访问Servlet API,Struts2还提供了如下的接口:
(1). ServletContextAware:实现接口的Action可能直接访问Web应用的ServletContext实例。
(2). ServletRequestAware:实现接口的Action可以直接访问用户请求的HttpServletRequest实例。
(3). ServletResponseAware:实现 该接口的Action可以直接访问服务器响应的HttpServletResponse实例。
下面笔者将通过HttpServletResponse为系统添加Cookie对象,本应用将继续使用前一个的JSP页面。下面给出Action类。
public class LoginAction implements Action,ServletResponseAware { private String username; private String password; private HttpServletResponse response; // 重写实现ServletResponseAware接口必须实现的方法 public void setServletResponse(HttpServletResponse response) { this.response = response; } // username的setter和getter方法 public void setUsername(String username) { this.username = username; } public String getUsername() { return this.username; } // password的setter和getter方法 public void setPassword(String password) { this.password = password; } public String getPassword() { return this.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范围的属性 ctx.getSession().put("user" , getUsername()); if (getUsername().equals("owen") && getPassword().equals("owen") ) { // 通过response添加Cookie Cookie c = new Cookie("user" , getUsername()); c.setMaxAge(60 * 60); response.addCookie(c); // 通过ActionContext设置request范围的属性 ctx.put("tip" , "服务器提示:您已经成功的登录"); return SUCCESS; } // 通过ActionContext设置request范围的属性 ctx.put("tip" , "服务器提示:登录失败"); return ERROR; } }
JSP页面添加如下的代码:
Cookie值:${cookie.user.value}
为了能直接访问Servlet API,Struts2还提供了一个ServletActionContext工具类,这个类包含了如下几个静态方法。
(1). static PageContextgetPageContext():取得Web应用的PageContext对象。
(2). static HttpServletRequestgetRequest():取得Web应用的HttpServletRequest对象
(3). static HttpServletRequestgetResponse():取得Web应用的HttpServletResponse对象
(4). static ServletContextgetServletContext():取得Web应用的ServletContext对象
下面笔者给出了Action类
public class LoginAction implements Action { private String username; private String password; // username的setter和getter方法 public void setUsername(String username) { this.username = username; } public String getUsername() { return this.username; } // password的setter和getter方法 public void setPassword(String password) { this.password = password; } public String getPassword() { return this.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范围的属性 ctx.getSession().put("user" , getUsername()); if (getUsername().equals("owen") && getPassword().equals("owen") ) { // 通过response添加Cookie Cookie c = new Cookie("user" , getUsername()); c.setMaxAge(60 * 60); ServletActionContext.getResponse().addCookie(c); // 通过ActionContext设置request范围的属性 ctx.put("tip" , "服务器提示:您已经成功的登录"); return SUCCESS; } // 通过ActionContext设置request范围的属性 ctx.put("tip" , "服务器提示:登录失败"); return ERROR; } }