Struts2学习——0700访问Web元素

来源:互联网 发布:狸窝for mac 编辑:程序博客网 时间:2024/05/17 08:32

背景

在Servelt学习的过程中,我们知道,有些情况是要使用web元素的,所谓的web元素就是request、response、session、application。例如,我们在用户登录的应用中,到底怎么确定用户登录了呢,就是往session域中加入一个user。session.setAttribute(“user”,user)。而在struts中肯定也要有一个方式能拿到session,否则,不就没办法完成这个需求了吗?这就是这部分内容的背景。

访问web元素

其实,struts肯定是有地方放这些web元素的,因为struts是使用了filter把东西拦下来,然后再处理的。肯定是在filter中,可以获得这个元素,保存下来。只不过,保存下来的形式,和原来的形式,也许有些不同罢了。

1. 效果与分析a

index.jsp
这里写图片描述

index.jsp代码

<?xml version="1.0" encoding="GB18030" ?><%@ page language="java" contentType="text/html; charset=GB18030"    pageEncoding="GB18030"%><% String context = request.getContextPath(); %><html xmlns="http://www.w3.org/1999/xhtml">    <head>        <meta http-equiv="Content-Type" content="text/html; charset=GB18030" />        <title>Insert title here</title>    </head>    <body>        取得Map类型request,session,application,真实类型 HttpServletRequest, HttpSession, ServletContext的引用:        <ol>            <li>前三者:依赖于容器</li>            <li>前三者:IOC</li> (只用这种)            <li>后三者:依赖于容器</li>            <li>后三者:IOC</li>        </ol>        <br />        <!-- 这有一个表单,用的是post方式,没有设置action -->        <form name="f" action="" method="post">        用户名:<input type="text" name="name"/>        <!-- 两个文本框,密码没有用password类型,差评! -->        密码:<input type="text" name="password"/>            <br />            <input type="button" value="submit1" onclick="javascript:document.f.action='login/login1';document.f.submit();" />            <input type="button" value="submit2" onclick="javascript:document.f.action='login/login2';document.f.submit();" />            <input type="button" value="submit3" onclick="javascript:document.f.action='login/login3';document.f.submit();" />            <input type="button" value="submit4" onclick="javascript:document.f.action='login/login4';document.f.submit();" />        </form>    </body></html>

从上面的代码可以看出,定义了四个提交按钮,每一按钮的action都是不一样的,namespace都是login,struts.xml文件肯定有相关设置。接下来分析struts.xml的代码。

struts.xml

    <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"    "http://struts.apache.org/dtds/struts-2.0.dtd"><struts>    <constant name="struts.devMode" value="true" />    <!-- namespace=/login 和上面所分析相符 -->    <package name="login" extends="struts-default" namespace="/login">    <!-- aciton书写用到了通配符配置,具体可参考前面的博文 -->        <action name="login*" class="com.bjsxt.struts2.user.action.LoginAction{1}">            <!-- result表示,只跳转到同一个jsp页面 -->            <result>/user_login_success.jsp</result>        </action>    </package></struts>

通过查找工程文件,我们知道了对应到相应的Action,总共有四个Action
LoginAction1、LoginAction2、LoginAction3、LoginAction4。

LoginAction1(这是第一种获取web元素的方式)

package com.bjsxt.struts2.user.action;import java.util.Map;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;public class LoginAction1 extends ActionSupport {    //定义所需要的成员变量web元素,不过这里的类型是map型    private Map request;    private Map session;    private Map application;    //在构造函数中,从ActionContext中取得web元素的Map类型值    public LoginAction1() {        request = (Map)ActionContext.getContext().get("request");        session = ActionContext.getContext().getSession();        application = ActionContext.getContext().getApplication();    }    //在execute方法中,往各个map类型的web元素中加入值    public String execute() {        request.put("r1", "r1");        session.put("s1", "s1");        application.put("a1", "a1");        return SUCCESS;     }   }

分析完Action1之后,我们得到了第一种获得web元素的方式,不过这种方式,获得是map类型的web元素,好像并不是我们所需要的。

到底是不是我们需要的,因为它最后是要跳转到user_login_success.jsp,所以我们看看这个jsp的内容是什么,以及submit之后的效果是什么样的。

user_login_success.jsp

<?xml version="1.0" encoding="GB18030" ?><%@ page language="java" contentType="text/html; charset=GB18030"    pageEncoding="GB18030"%>    <%@taglib uri="/struts-tags" prefix="s" %><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=GB18030" /><title>Insert title here</title></head><body>    User Login Success!    <br />    <s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br />    <s:property value="#session.s1"/> | <%=session.getAttribute("s1") %> <br />    <s:property value="#application.a1"/> | <%=application.getAttribute("a1") %> <br />    <s:property value="#attr.a1"/><br />    <s:property value="#attr.s1"/><br />    <s:property value="#attr.r1"/><br />    <s:debug></s:debug>    <br /></body></html>

具体分析上述代码中的几句

<s:property value="#request.r1"/> | <%=request.getAttribute("r1") %> <br />

前半句话的意思是从Stack Context中拿到requset中r1这个key相对应的value。
而这个Stack Context就是debug下拉下来能见到的。

这里写图片描述

如果前半句话的东西不算什么,后半句就很有意思了。通过Servlet和Jsp基本知识学习,我们明白,后半句话的意思是,它能够拿到request域中的r1值,说明我们刚在在Action存进去的Map类型request和实际的request是有对应关系的。往那个map里面存,就是往相应web元素的Attribute里面存。

这就可以解决我们实际的登陆问题了,只要在Action中put这么个User,就可以表示这个用户登录了。

【另】解释一下代码中的

<s:property value="#attr.a1"/><br />
  • 要从Stack Context 中取出相应的数据,必须用value=#key的格式

  • attr是Stack Context中的一个成员,指所有域中存的Attribute,相当于学习servlet时,在jsp中写${key},就是在所有域中,找key名称的属性,但是最好不要用,因为我们取key相对应的值,最好应该精确取。

【附】 attr在Stack Context中的位置图

这里写图片描述

2. 效果与分析b

上面分析的是以第一种方法来获取web元素,现在要说的是以第二种方法来获取IOC(控制反转),其实不同的地方也就是在Action,因为我们就先分析一下Action

LoginAction2

package com.bjsxt.struts2.user.action;import java.util.Map;import org.apache.struts2.interceptor.ApplicationAware;import org.apache.struts2.interceptor.RequestAware;import org.apache.struts2.interceptor.SessionAware;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;//与上一个方法最不同之处,它实现了三个接口public class LoginAction2 extends ActionSupport implements RequestAware,SessionAware, ApplicationAware {    private Map<String, Object> request;    private Map<String, Object> session;    private Map<String, Object> application;    //DI dependency injection 依赖注入    //IoC inverse of control  控制反转    public String execute() {        request.put("r1", "r1");        session.put("s1", "s1");        application.put("a1", "a1");        return SUCCESS;     }    @Override    public void setRequest(Map<String, Object> request) {        this.request = request;    }    @Override    public void setSession(Map<String, Object> session) {        this.session = session;    }    @Override    public void setApplication(Map<String, Object> application) {        this.application = application;    }}

具体过程是这样的,Struts new一个Action之后,它会看看这个Action有没有实现RequestAware,SessionAware, ApplicationAware接口,如果有,Struts会把自己得到的request、session、application赋给Action定义出来的几个成员变量。Action直接就获得了web元素,这个IoC方法是最常见的。

stuts2利用IoC方法获取web元素框图

3. 效果与分析c、d

至于实际要用到的HttpServletRequest之类,其实获取十分简单

LoginAction3

package com.bjsxt.struts2.user.action;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.struts2.ServletActionContext;import com.opensymphony.xwork2.ActionSupport;public class LoginAction3 extends ActionSupport {    private HttpServletRequest request;    private HttpSession session;    private ServletContext application;    public LoginAction3() {        request = ServletActionContext.getRequest();        session = request.getSession();        application = session.getServletContext();    }    public String execute() {        request.setAttribute("r1", "r1");        session.setAttribute("s1", "s1");        application.setAttribute("a1", "a1");        return SUCCESS;     }}

如下代码所示,直接利用这个ServletActioncontext拿到Request
进而拿到session和application

request = ServletActionContext.getRequest();session = request.getSession();application = session.getServletContext();

LoginAction4

package com.bjsxt.struts2.user.action;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.apache.struts2.interceptor.ServletRequestAware;import com.opensymphony.xwork2.ActionSupport;public class LoginAction4 extends ActionSupport implements ServletRequestAware {    private HttpServletRequest request;    private HttpSession session;    private ServletContext application;    public String execute() {        request.setAttribute("r1", "r1");        session.setAttribute("s1", "s1");        application.setAttribute("a1", "a1");        return SUCCESS;     }    @Override    public void setServletRequest(HttpServletRequest request) {        this.request = request;        this.session = request.getSession();        this.application = session.getServletContext();    }}

获得实际web元素也是实现接口,实现的是ServletRequestAware接口,之后Struts就会帮你注入了,你就不用管它了,特别的方便。

这部分内容就介绍到这里

若有不足之处,请不吝赐教

0 0
原创粉丝点击