IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Struts2学习之Action中访问Servlet API

    果冻想发表于 2016-03-04 15:26:39
    love 0

    前言

    Struts2框架的设计初衷就是各种解耦,所以,Struts2的Action没有与任何Servlet API耦合,这样带来的好处就是我们在测试Action时会更加的简单、方便;但是话又说回来了,对于Web应用的控制器而言(Action是控制器),不访问Servlet API几乎是不可能的,而Action并没有那么“轻易”让你去使用Servlet API。

    在Action中如果想要使用Servlet API,基本上只有以下三种方法:

    • 通过ActionContext类访问
    • Action直接访问
    • 通过ServletActionContext访问

    这篇文章就对这三种方法进行总结。

    通过ActionContext类访问

    Struts2提供了ActionContext类,Struts2的Action可以通过该类来访问Servlet API。下面是ActionContext类中几个常用的方法:

    • Object get(Object key):该方法类似于调用HttpServletRequest的getAttribute(String name)方法
    • Map getApplication():返回一个Map对象,该对象模拟了该应用的ServletContext实例
    • static ActionContext getContext():静态方法,获取系统的ActionContext实例
    • Map getParameters():获取所有的请求参数;类似于调用HttpServletRequest对象的getParameterMap()方法
    • Map getSession():返回一个Map对象,该Map对象模拟了HttpSession实例
    • void setApplication(Map application):直接传入一个Map实例,将该Map实例里的key-value对转换成application的属性名、属性值
    • void setSession(Map session):直接传入一个Map实例,将该Map实例里的key-value对转换成session的属性名、属性值

    下面通过一个简单的实例来说明如何使用ActionContext。

    public String execute() throws Exception
    {
        if (getUserName() == null || getPassword() == null)
        {
            return INPUT;
        }
    
        // 获取ActionContext对象
        ActionContext ac = ActionContext.getContext();
    
        // 通过ActionContext访问application范围的属性值
        Integer counter = (Integer)ac.getApplication().get("counter");
        if (counter == null)
        {
            counter = 1;
        }
        else
        {
            counter += 1;
        }
    
        // 通过ActionContext设置application范围的属性
        ac.getApplication().put("counter", counter);
    
        if (getUserName().equals("jellythink")
                && getPassword().equals("123456"))
        {
            ActionContext.getContext().getSession().put("user", getUserName());
            ac.put("tip", "服务器提示:您已经成功登陆");
            return SUCCESS;
        }
        else
        {
            ac.put("tip", "服务器提示:登陆失败");
            return ERROR;
        }
    }
    

    通过前台JSP页面,我们可以访问这些属性值:

    <body>
        本站访问次数为:${applicationScope.counter}<br/>
        ${sessionScope.user},您已登陆!<br/>
        ${requestScope.tip}
    </body>
    

    通过ActionContext这种方法访问的前提是必须先要获取ActionContext对象,它彻底的与Servlet API进行了分离,使用这种方法简单易用。

    Action直接访问

    虽然Struts2提供了ActionContext来访问Servlet API,但这种访问毕竟不是直接获得Servlet API的实例,为了可以在Action中直接访问Servlet API,Struts2还提供了以下几个接口:

    接口名称 接口说明
    ServletContextAware 实现该接口的Action可以直接访问Web应用的ServletContext实例
    ServletRequestAware 实现该接口的Action可以直接访问Web应用的HttpServletRequest实例
    ServletResponseAware 实现该接口的Action可以直接访问服务器响应的HttpServletResponse实例

    下面通过一段简单的代码来说说这几个接口的具体使用:

    public class LoginAction extends ActionSupport 
                            implements ServletResponseAware, ServletRequestAware, ServletContextAware
    {
        private String userName;
        private String password;
        private HttpServletResponse response;
        private HttpServletRequest request;
        private ServletContext sc;
    
    // 实现ServletResponseAware接口的方法,设置response属性值
    public void setServletResponse(HttpServletResponse response)
    {
        this.response = response;
    }
    
    // 实现ServletRequestAware接口的方法,设置request属性值
    public void setServletRequest(HttpServletRequest request)
    {
        this.request = request;
    }
    
    // 实现ServletContextAware接口的方法,设置sc属性值
    public void setServletContext(ServletContext sc)
    {
        this.sc = sc;
    }
    
    // ......
    
    public String execute() throws Exception
    {
        // ......   
        Integer counter = (Integer)sc.getAttribute("counter");
        if (counter == null)
        {
            counter = 1;
        }
        else
        {
            counter += 1;
        }
    
        sc.setAttribute("counter", counter);
    
        if (getUserName().equals("jellythink")
                && getPassword().equals("123456"))
        {
            HttpSession session = request.getSession();
            session.setAttribute("user", getUserName());
            request.setAttribute("tip", "服务器提示:您已经成功登陆");
            return SUCCESS;
        }
        else
        {
            request.setAttribute("tip", "服务器提示:登陆失败");
            return ERROR;
        }
    }
    

    这种方法使用起来也比较方便,但是必须要实现对应的三个接口。

    通过ServletActionContext访问

    上面的两种方法要么不是直接访问Servlet API,要么就是需要继承其它的接口。为了能直接访问Servlet API,Struts2还提供了一个ServletActionContext工具类,该工具类提供了以下几个静态方法:

    声明 说明
    static PageContext getPageContext() 取得Web应用的PageContext对象
    static HttpServletRequest getRequest() 取得Web应用的HttpServletRequest对象
    static HttpServletResponse getResponse() 取得Web应用的HttpServletResponse对象
    static ServletContext getServletContext() 取得Web应用的ServletContext对象

    通过ServletActionContext工具类,我们就无需实现接口,就可以直接访问Servlet API,但是这样会加强了Action和Servlet API的耦合,不利于Action的再利用。

    总结

    上面介绍的这三种方法各有各的有点,具体如下:

    方法 优点 缺点
    通过ActionContext类访问 Action和Servlet API完全解耦 并不能调用原生的Servlet API
    Action直接访问 可以调用原生的Servlet API 需要实现对应的接口
    通过ServletActionContext访问 可以调用原生的Servlet API 增加了耦合

    基于此,在实际开发过程中,就看你喜欢用哪种了。反正我喜欢用Action直接访问这种方式,虽然需要实现对应的接口,但是还是比较方便的。

    果冻想-一个原创技术文章分享网站。

    2016年01月23日 于呼和浩特。

    未经允许不得转载:果冻想 » Struts2学习之Action中访问Servlet API



沪ICP备19023445号-2号
友情链接