Struts2学习——0700访问Web元素

背景

在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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值