Struts 2.x权威指南
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.5.3 Action直接访问ServletAPI

虽然 Struts 2 提供了 ActionContext 来访问 Servlet API,但这种访问毕竟不能直接获得Servlet API实例,为了在Action中直接访问Servlet API,Struts 2还提供了如下系列接口。

ServletContextAware:实现该接口的 Action 可以直接访问 Web 应用的 ServletContext实例。

ServletRequestAware:实现该接口的Action可以直接访问用户请求的HttpServletRequest实例。

ServletResponseAware:实现该接口的 Action 可以直接访问服务器响应的HttpServletResponse实例。

下面以ServletResponseAware为例,介绍如何在Action中访问HttpServletResponse对象。本应用将通过HttpServletResponse为系统添加Cookie对象,本应用将继续使用如图3.14所示的登录页面,该页面提交给如下的Action处理。

程序清单:codes\03\3.5\access-servlet-api\WEB-INF\src\org\crazyit\struts2\action\LoginAction.java

// 处理用户请求的Action
public class LoginAction
    implements Action , ServletResponseAware
{
    // 需要访问的HttpSerlvetResponse对象
    private HttpServletResponse response;
    // 封装请求参数的两个属性
    private String username;
    private String password;
    // username属性的getter和setter方法
    public String getUsername()
    {
          return username;
    }
    public void setUsername(String username)
    {
          this.username = username;
    }
    // password属性的setter和getter方法
    public String getPassword()
    {
          return password;
    }
    public void setPassword(String password)
    {
          this.password = password;
    }
    // 实现ServletResponseAware接口必须实现的方法
    @Override
    public void setServletResponse(HttpServletResponse response)
    {
          // 在该方法内就可以访问该Web应用对客户端的响应对象
          this.response = response;
    }
    //处理用户请求的execute方法
    public String execute() throws Exception
    {
          // 创建一个Cookie对象
          Cookie c = new Cookie("user" , getUsername());
          // 设置Cookie对象的最大生存时间
          c.setMaxAge(60 * 60);
          // 使用HttpServletResponse添加Cookie对象
          response.addCookie(c);
          return SUCCESS;
    }
}

通过查看Struts 2的API文档,发现要实现ServletResponseAware接口,仅要求实现如下方法。

public void setServletResponse(HttpServletResponse response):实现此方法时,该方法内有一个HttpServletResponse参数,该参数就代表了Web应用对客户端的响应。我们在setServletResponse(HttpServletResponse response)方法内访问到Web应用的响应对象,并将该对象设置成 Action 的成员属性,从而允许在 execute 方法中访问该HttpServletResponse对象。

与此类似的是,如果一个Action实现了ServletRequestAware接口,则必须实现如下方法。

public void setServletRequest(HttpServletRequest request):通过实现此方法,从而允许Action直接访问HttpServletRequest对象。

为了直接访问Servlet API,Struts 2提供了一个ServletActionContext,这个类包含了如下几个静态方法。

PageContext getPageContext():取得Web应用的PageContext对象。

HttpServletRequest getRequest():取得Web应用的HttpServletRequest对象。

HttpServletResponse getResponse():取得Web应用的HttpServletResponse对象。

ServletContext getServletContext():取得Web应用的ServletContext对象。

借助于ServletActionContext类的帮助,开发者也可以在Action中直接访问Servlet API,避免Action类需要实现XxxAware接口——虽然如此,但该Action依然与Servlet API直接耦合,一样不利于程序解耦。

提示:

可以通过 ServletActionContext 类的帮助,从而以更简单的方式来直接访问Servlet API。

当该Action处理完用户请求后,Web应用向客户机中添加了一个Cookie对象。下面的JSP页面通过表达式来访问Cookie值,该JSP页面的代码如下。

程序清单:codes\03\3.5\access-servlet-api\WEB-INF\content\welcome.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=GBK" />
    <title>成功页面</title>
</head>
<body>
    从系统中读取的Cookie值:${cookie.user.value}
</body>
</html>

当用户输入用户名、密码,并单击“提交”按钮后,重复刷新上面的 JSP 页面,将看到如图3.16所示的页面效果。

图3.16 通过HttpServletResponse添加Cookie

必须指出的是,虽然可以在Action类中获取HttpServletResponse,但希望通过HttpServletResponse来生成服务器响应没有太大意义,因为Action只是控制器,即如果在Action中书写如下代码:

// 试图在Servlet中直接生成输出的代码
response.getWriter().println("Hello World");

上面代码在标准Servlet中会生成对客户端的输出,但在Struts 2的Action中没有任何实际意义。

提示:

即使我们在Struts 2的Action类中获得了HttpServletResponse对象,也不要尝试直接在Action中生成对客户端的输出!