JavaEE struts2 Action访问Servlet API

struts2的Action没有与任何Servlet API耦合,因此能够更轻松地对Action进行测试。但对于Web应用的控制器来说,不访问Servlet API几乎是不可能的,为此struts2提供了更方便的方式来访问Servlet API。

使用ActionContext访问Servlet API

struts2提供了一个ActionContext类,它具有访问Servlet API的一系列方法。
- static ActionContext getContext():返回当前线程的ActionContext对象;
- Map<String,Object> getApplication():以Map形式返回ServletContext对象的属性集;
- Map<String,Object> getSession():以Map形式返回HttpSession对象的属性集;
- void setSession(Map<String,Object> session):设置HttpSession对象的属性集;
- HttpParameters getParameters():相当于HttpServletRequest的getParameterMap方法;
- void setParameters(HttpParameters parameters):设置HttpServletRequest对象的属性集;
- Object get(String key):相当于HttpServletRequest的getAttribute方法;
- void put(String key, Object value):相当于HttpServletRequest的setAttribute方法。

下面编写一个简单的Web应用,在登录页面输入用户名和密码,登录成功后显示登录次数(ServletContext作用域属性,没有实际意义)、用户名(HttpSession作用域属性)和当前时间(HttpServletRequest作用域属性)。

最终的项目结构如下:
project_structure

首先提供国际化资源文件供JSP页面使用

# message.properties

usename=用户名
password=密  码
login=登录
loginPage=登录页
welcomePage=欢迎页
errorPage=错误页
welcomeTip=欢迎您,{0}!这是您第{1}次登录,当前时间:{2}
errorTip=对不起,“{0}”此用户不存在

使用native2ascii工具对其转码得到message_zh_CN.properties文件,另外还可以提供一个message_en_US.properties文件(关于native2ascii工具,可以参考这篇文章:《native2ascii Java的一个文件转码工具(properties文件汉字转换)》)。

然后编写JSP页面

<!-- login.jsp -->

<body>
  <s:form action="firstlogin">
    <s:textfield name="username" key="username"/>
    <s:textfield name="password" key="password"/>
    <s:submit key="login"/>
  </s:form>
</body>

这里还在web.xml对JSP页面进行了一些常规配置:

<!-- web.xml -->

  <jsp-config>
      <jsp-property-group>
          <!-- 配置范围 -->
          <url-pattern>*.jsp</url-pattern>
          <!-- 使用EL表达式 -->
          <el-ignored>false</el-ignored>
          <!-- 禁用JSP脚本 -->
          <scripting-invalid>true</scripting-invalid>
          <!-- JSP页面的编码方式 -->
          <page-encoding>UTF-8</page-encoding>
          <!-- JSP页面的抬头 -->
          <include-prelude>head.jspf</include-prelude>
      </jsp-property-group>
  </jsp-config>

如果在对JSP页面配置后出现cvc-complex-type.2.4.a: Invalid content was found starting with element错误,可以将http://www.springmodules.org/schema/cache/springmodules-cache.xsd http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd这段话加入到xml文件的”xmlns:xsi”标签中。

welcome.jsp和error.jsp两个页面的编写更为简单,这里不再列出。

接着定义Action类

// FirstLoginAction.java

public class FirstLoginAction extends ActionSupport {
    private String username;
    private String password;
    private static final SimpleDateFormat sdf=
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final long serialVersionUID = 1L;

    public String getUsername() { return username; }
    public String getPassword() { return password; }
    public void setUsername(String u) { username=u; }
    public void setPassword(String p) { password=p; }

    @Override
    public String execute() throws Exception {
        super.execute();

        if(username.equals("张三") && password.equals("123456")) {
            // 登录次数
            ActionContext ac=ActionContext.getContext();
            Integer vc=(Integer) ac.getApplication().get("visitCount");
            if(vc==null)
                vc=new Integer(0);
            vc=vc+1;
            ac.getApplication().put("visitCount", vc);
            // 用户名
            ac.getSession().put("username", username);
            // 当前时间
            ac.put("currentTime", sdf.format(new Date()));

            return SUCCESS;
        }
        else
            return ERROR;
    }
}

在execute方法中,使用ActionContext分别向application、session和request作用域中添加了属性(ActionContext对象的put方法相当于HttpServletRequest对象的setAttribute方法),这些属性将在JSP页面中被使用。

最后还需要对此Action对象进行配置

<!struts-first.xml -->

<struts>
    <package name="first" extends="struts-default">
        <action name="firstlogin" class="com.zzw.action.first.FirstLoginAction">
            <result name="input">/login.jsp</result>
            <result name="success">/welcome.jsp</result>
            <result name="error">/error.jsp</result>
        </action>
    </package>
</struts>
<!-- struts.xml -->

<struts>
    <constant name="struts.custom.i18n.resources" value="message"/>
    <constant name="struts.i18n.encoding" value="GBK"/>
    <constant name="struts.devMode" value="true"/>

    <include file="com/zzw/action/first/struts-first.xml"/>
</struts>

这里使用分模块配置的方式进行struts2的配置(如果项目非常庞大,分模块的方式更容易配置,当然使用专业的构建工具更好)。

运行此Web项目,在浏览器地址栏输入http://localhost:8080/StrutsUseServletAPI/login.jsp,用户名输入“张三”,密码输入“123456”,登录后刷新几次(为了测试登录次数),可以看到类似如下的结果:
result

注意浏览器地址栏变为http://localhost:8080/StrutsUseServletAPI/firstlogin.action

实现接口以访问Servlet API

struts2提供了如下接口以访问Servlet API:
- ServletContextAware:实现该接口的Action可以访问ServletContext对象;
- ServletRequestAware:实现该接口的Action可以访问HttpServletRequest对象;
- ServletResponseAware:实现该接口的Action可以访问HttpServletResponse对象。

下面以接口的方式改写上述程序:

// SecondLoginAction.java

public class SecondLoginAction extends ActionSupport implements ServletContextAware, ServletRequestAware {
    private String username;
    private String password;
    private static final SimpleDateFormat sdf=
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final long serialVersionUID = 1L;

    ServletContext application;
    HttpServletRequest request;

    public String getUsername() { return username; }
    public String getPassword() { return password; }
    public void setUsername(String u) { username=u; }
    public void setPassword(String p) { password=p; }

    @Override
    public void setServletRequest(HttpServletRequest r) {
        request=r;
    }

    @Override
    public void setServletContext(ServletContext a) {
        application=a;
    }

    @Override
    public String execute() throws Exception {
        super.execute();

        if(username.equals("张三")&&password.equals("123456")) {
            // 登录次数
            Integer vc=(Integer) application.getAttribute("visitCount");
            if(vc==null)
                vc=new Integer(0);
            vc=vc+1;
            application.setAttribute("visitCount", vc);
            // 用户名
            ActionContext.getContext().getSession().put("username", username);
            // 当前时间
            request.setAttribute("currentTime", sdf.format(new Date()));
            return SUCCESS;
        }
        else
            return ERROR;
    }
}

注意,struts2没有提供接口以访问HttpSession对象。

将login.jsp页面中的form表单的action属性更改为secondlogin,运行结果与之前类似,只不过浏览器的地址栏显示的是http://localhost:8080/StrutsUseServletAPI/secondlogin.action

使用ServletActionContext访问Servlet API

struts2还提供了一个ServletActionContext工具类,通过此类的静态方法可以访问Servlet API:
- static PageContext getPageContext():获得PageContext对象;
- static HttpServletRequest getRequest():获得HttpServletRequest对象;
- static HttpServletResponse getResponse():获得HttpServletResponse对象;
- static ServletContext getServletContext():获得ServletContext对象。

注意,ServletActionContext类没有提供HttpSession的访问方法,不过它比ActionContext对象多了一个PageContext的访问方法。

下面继续改写上述程序,以ServletActionContext方式访问Servlet API:

// ThirdLoginAction.java

public class ThirdLoginAction extends ActionSupport {
    private String username;
    private String password;
    private static final SimpleDateFormat sdf=
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final long serialVersionUID = 1L;

    public String getUsername() { return username; }
    public String getPassword() { return password; }
    public void setUsername(String u) { username=u; }
    public void setPassword(String p) { password=p; }

    @Override
    public String execute() throws Exception {
        super.execute();

        if(username.equals("张三")&&password.equals("123456")) {
            // 登录次数
            ServletContext application=ServletActionContext.getServletContext();
            Integer vc=(Integer) application.getAttribute("visitCount");
            if(vc==null)
                vc=new Integer(0);
            vc=vc+1;
            application.setAttribute("visitCount", vc);
            // 用户名
            ActionContext.getContext().getSession().put("username", username);
            // 当前时间
            ServletActionContext.getRequest().setAttribute("currentTime", sdf.format(new Date()));
            return SUCCESS;
        }
        else
            return ERROR;
    }
}

修改login.jsp页面的form表单的action属性为thirdlogin,运行结果与之前类似,不过浏览器的地址栏变为http://localhost:8080/StrutsUseServletAPI/thirdlogin.action

源码

上述所有源代码已经上传到github:
https://github.com/jzyhywxz/StrutsUseServletAPI

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值