struts2--初级

2017.2.2-2017.2.6

Struts2介绍

  1. Struts2框架是基于MVC模式的开源Java EE框架,使用可以对使用Java EE技术的web项目开发进行代码的分层,优点是有利于维护。
  2. 它是WebWork框架和Struts1框架的基础上综合开发出来的产物,但Struts2的核心代码主要来自WebWork框架。
  3. Struts2的优点主要体现在解耦上,其他的附属技术也比Struts1有所加强,使用上更加快捷方便,比如简化了配置文件的代码。
  4. 在网站http://struts.apache.org/上可以找到其全部相关资料。

下载最新版的zip文件struts-2.5.8-all

其中apps是Struts2的demo示例项目,docs是开发文档及使用手册,lib是jar,src则是Struts2框架的源代码。

必要的jar文件

第一个项目

版本2.3.24,参考Struts/apps文件夹下的项目

  1. 引入jar包,在apps文件夹下找
  2. 创建action

    package action;
    /*
     * (1)每次访问servlet的时候,都会执行service方法
     * -写类继承HttpServlet,重写类里面的方法
     * -在web.xml中配置servlet访问路径
     * 
     * (2)访问action,每次访问action的时候,默认执行execute方法
     * -配置action方法
     */
    public class hello {
        public String execute(){
            return "ok";
        }
    }
    
  3. 配置action类访问路径

    (1)创建Struts2核心配置文件<br>
    -核心配置文件名称(struts.xml)和位置(src/)是固定的<br>
    -引入dtd约束
    
    <package name="default" namespace="/" extends="struts-default">
        <!-- name:访问名城 -->
        <action name="hello" class="action.hello">
            <!-- 配置方法的返回页面 -->
           <result name="ok">/ok.jsp</result>
        </action>
    </package>
    
  4. 配置struts2过滤器

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
  5. 访问路径http:localhost/struts(项目名)/hello(action名)

struts执行过程

过滤器是在服务区启动时创建,创建过滤器时执行init方法。
init方法主要加载配置文件(自带的和手工创建的web.xml和struts.xml)

struts.xml里的package标签

<package name="default" namespace="/" extends="struts-default">
    <!-- name:访问名城 -->
       <action name="hello" class="action.hello">
        <!-- 配置方法的返回页面 -->
          <result name="ok">/ok.jsp</result>
       </action>
</package>

为了区分不同的action,要配置action,必须首先写package标签,在package里面才能配置action。
(1)name属性
在一个配置文件中可以写多个package标签,name属性值不能相同
(2)extends属性
属性值是固定的,”struts-default”,写了这个属性之后,在package里面配置的类才具有action功能
(3)namespace属性
namespace属性值和action标签里面的name属性值构成访问路径,默认为”/”

action标签

action配置action访问路径
(1)name属性
namespace属性值和action标签里的name属性值构成访问路径,在package里面可以配置多个action标签,但是action的name属性值不能相同。
(2)class属性
action全路径
(3)method属性
让action里面多个方法执行,使用method进行配置。

result标签

根据action的方法返回值,配置到不同的路径里面
(1)name属性
和action方法的返回值一样

(2)type属性
配置如何到路径中(转发或者重定向),默认为转发(地址栏不改变)。

修改Struts2默认常量值

在struts.xml中进行配置

<constant name="struts.i18n.encoding" value="UTF-8"></constant>

还有两种方式(了解)
- 在src下面创建struts.properties,进行修改
- 在web.xml进行配置

最常用常量

struts.i18n.encoding=UTF-8

表单提交数据有中文乱码问题
-post提交直接设置编码
-get提交做编码转换
如果在action获取表单通过post方式提交中文,中文乱码问题系统会自动解决

分模块开发

单独写配置文件,把配置文件引入到核心配置文件中

<include file="cn/zcw/action/hello.xml"></include>

Action编写方式(3种)

  1. 创建普通类,这个不继承任何类,不实现任何接口
  2. 创建类,实现接口Action
  3. 创建类,继承类ActionSupport

*访问action的方法(3种)

  1. 使用action标签的method属性,在这个属性里面写执行action的方法
  2. 使用通配符方式实现

    <action name="a*" class="......" method="{1}"></action>
    
  3. 动态访问实现(不用)

在action里面的方法有返回值,如果返回值的类型必须是String,
如果action里面的方法可以没有返回值,这时候result标签不需要配置。
(1)把返回类型设置为void。(2)返回“none”

全局结果页面

应用场景:当有多个action方法的返回值相同且到达的页面也是相同。

 <package name="default" namespace="/" extends="struts-default">

    <global-results>
        <result name="ok">/ok.jsp</result>
    </global-results>
    <!-- name:访问名称 -->
    <action name="hello" class="action.hello">
        <!-- 配置方法的返回页面 -->
       <!-- <result name="ok">/ok.jsp</result> -->
    </action>
</package>

局部结果页面

<action name="hello" class="action.hello">
    <!-- 配置方法的返回页面 -->
    <!-- <result name="ok">/ok.jsp</result> -->      
</action>

优先级:全局结果页面 < 局部结果页面

result标签的type属性

  1. dispatcher,转发(默认),地址栏不变
  2. redirect,重定向,地址栏改变
  3. chain,转发到action,存在缓存问题,一般不使用

    <--! list为action的name值 -->
    <result name="success" type="chain">list</result>
    
  4. redirectAction,重定向到action

    <result name="success" type="redirectAction">list</result>
    

action获取表单提交数据

  1. 使用ActionContext类(官方推荐)

    首先提交form表单,action值为访问action的路径。
    action类核心代码:
    
    //1.获得ActionContext对象
    ActionContext context=ActionContext.getContext();
    //2.调用方法得到表单数据,value是输入的值
    Map<String, Object> params = context.getParameters();
    Set<String> keys=params.keySet();
    for (String key : keys) {
        //根据key得到value
        //返回数组形式,因为输入项中可能有复选框的情况
        Object[] obj=(Object[]) params.get(key);
        System.out.println(Arrays.toString(obj));
    }
    
  2. 使用ServletActionContext类

    核心代码:
    
    //通过ServletActionContext类得到request对象
    HttpServletRequest request=ServletActionContext.getRequest();
    String username=request.getParameter("username");
    String password=request.getParameter("password");
    System.out.println(username+":"+password);
    
  3. 使用接口注入方式(了解即可)

action中操作域对象(3个)

//1.request域
HttpServletRequest request=ServletActionContext.getRequest();
//2.session域
HttpSession session=request.getSession();
//3.ServletContext域
ServletContext context=request.getServletContext();

Struts2封装获取表单数据方式

  1. 属性封装

    在action中声明与表单name一样的成员变量并且实现其的set方法。但不能把数据直接封装到实体类对象里面
    
  2. 模型驱动封装(重点)

    使用模型驱动可以直接将表单数据封装到实体类对象里
    1.action实现接口ModelDriven
    2.在action中创建实体类对象
    3.实现接口里面的getModel方法,返回创建的对象
    
  3. 表达式封装(会用)

    1、声明实体类
        public User user;
    2、生成实体类变量的get、set方法
    3、将表单的name写成对象属性形式,如:
        <input type="text" name="user.username"/>
    

不能同时用属性封装和模型驱动封装获取同意表单数据,如果同时使用则默认执行模型驱动封装。

比较表达式封装和模型驱动封装

相同点:两个都可以讲数据封装到实体类对象里面

不同点:模型驱动只能把数据封装到一个实体类对象里面,表达式封装可以把数据封装到不同的实体类对象里面

封装数据到List

1、声明List变量
    private List<User> list;
2、生成List的get、set方法 
3、在表单输入项里面写表达式
    <input type="text" name="list[0].username"/>

封装数据到Map

1、声明Map集合
    private Map<String,User> map;
2、生成get、set方法
3、在页面里写表达式
<input type="text" name="map['one'].username"/>
......
<input type="text" name="map['abc'].username"/> 

ognl配合struts2使用

实例:输出字符串长度

1.引入ognl的jar包

2.引入标签 <%@ taglib uri="/struts-tags" prefix="s"%>
3.配合Struts标签使用<s:property value="'abc'.length()"/>

什么是值栈

值栈是struts2里面提供的一种存储机制,类似于域对象,可以存值和取值。在action里面把数据放到值栈里,在页面中获取值栈数据。

Servlet和action的区别

Servlet:默认第一次访问时创建,只创建一次,单实例对象
action:访问时创建,每次访问时都会创建action对象,多实例对象

值栈存储位置

每个action对象里面都有一个值栈对象(只有一个)

获取值栈对象

常用方式:

//1、获取ActionContext类的对象
ActionContext context=ActionContext.getContext();
//2、调用方法得到值栈对象
ValueStack stack=context.getValueStack();

值栈内部结构

  1. 第一部分root,结构为list集合。一般都是操作root里面数据
  2. 第二部分context,结构为map集合

向值栈中放入数据

  1. 获取值栈对象,调用其的set方法
  2. 获取值栈对象,调用其的push方法
  3. 在action中设置变量属性,实现其get方法

获取值栈的字符串

应用设置action对象属性(如username)的方法向值栈中添加数据,在页面中使用struts2和ongl表达式显示结果:

<s:property value="username"/>

从值栈中获取对象

<S:property vlaue="user.username"/>

从值栈中获取list(3种)

1.<s:property value="list[0].username"/>
2.
    <s:iterator value="list">
        <s:property value="username"/>
    </S:iterator>
3.
    <s:iterator value="list" var="user">
        <s:property value="#user.username"/>
    </S:iterator>

获取set方式的值

在action中使用:stack.set("name","zcw");
在页面中获取:<s:property value="name"/>

获取push设置的值

<s:property value="[0].top"/>

为什么EL表达式可以获取值栈中的数据

EL表达式用于获取域对象的值,首先从request域获取值,如果获取到直接返回;

如果获取不到,则从值栈中把值获取出来,把值放到域对象里面。

ognl中#、%

使用ognl获取request域中的值,首先加上#,再写context的key名称,最后写域对象名称。

action类:
request.setAttribute("req","hello");
页面:
<s:property value="#request.req"/>

在struts2标签里面使用ognl表达式,如果直接在struts2表单标签里面使用ognl表达式不识别,只用%之后才会识别。

<s:textfield name="name" value="%{#request.req}"></s:textfield>

struts2拦截器介绍

1.struts2是框架,封装了很多的功能,struts2里面封装的功能都是在拦截器里面
2.struts2里面封装了很多的功能,有很多拦截器,不是每次这些拦截器都执行,每次只执行默认的拦截器。
3.执行时间:在action对象创建之后,在action的方法执行之前。

拦截器底层思想

  1. aop思想

    AOP切面模式编程,不修改源代码即可增加功能。
    
  2. 责任链模式

    要执行多个操作,有添加、修改、删除三个操作。
    首先执行添加操作,添加操作执行后,做类似于放行操作,执行修改操作,修改操作执行之后做类似放行操作,执行删除操作。
    
    过滤链:一个请求有多个过滤器进行过滤,每个过滤器只有做放行才能到下一个过滤器。
    

过滤器和拦截器的区别

(1)过滤器:过滤器理论上可以过滤任意内容,比如html、jsp、servlet、图片路径

(2)拦截器:拦截器只可以拦截action

拦截器实现过程

  1. 第一步 创建类,继承MethodFilterInterceptor类,实现重写其doInterceptor方法
  2. 第二步 重写MethodFilterInterceptor类里面的方法写拦截器逻辑

    package intercept;
    
    import javax.servlet.http.HttpServletRequest;
    import org.apache.struts2.ServletActionContext;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
    
    public class demo extends MethodFilterInterceptor{
    
        protected String doIntercept(ActionInvocation invocation) throws Exception {
            HttpServletRequest request=ServletActionContext.getRequest();
            Object username=request.getSession().getAttribute("username");
            if(username!=null){
                //类似于放行操作,执行action方法
                return invocation.invoke();
            }
            else{
                //达到login的访问路径
                return "login";
            }
        }
    
    }
    
  3. 第三步 配置action和拦截器关系(注册拦截器)

    1. 在要拦截的action标签所在的package标签里面声明拦截器

      <!-- 声明拦截器 -->
      <interceptors>
          <interceptor name="logininterceptor" class="cn.zcw.interceptor.Login">
      </interceptor>
      
    2. 在具体的action标签里面使用声明的拦截器

    3. struts2里面执行很多的默认拦截器。但是如果在action里面配置自定义拦截器,默认的拦截器就不会执行了。解决办法:把默认拦截器手动使用一次

配置拦截器,对action里面所有的方法都进行拦截

要使某个方法不被拦截器拦截,需要配置

<interceptor-ref name="logininterceptor">
    <--! 不被拦截的方法用逗号隔开 -->
    <param name="excludeMethods">login</param>
</interceptor-ref>  

struts2标签库

struts2标签只能在JSP页面中使用

  1. s:property:和ognl表达式在JSP页面中获取值栈数据
  2. s:iterator:获取值栈list集合数据,表示list集合
  3. s:debug:查看值栈结构和数据

struts2表单标签(会用)

<s:form>
    <!-- 普通输入项 -->
    <s:textfield name="username" label="name"></s:textfield>
    <!-- 密码输入项 -->
    <s:password name="password" label="password"></s:password>
    <!-- 单选输入项 -->
    <!-- value属性值和显示的一样 -->
    <s:radio list="{'女','男'}" name="sex" lable="性别"></s:radio>
    <!-- value属性值和显示的不一样 -->
    <s:radio list="#{'nv':'女','nan':'男' }" name="sex1" label="性别"></s:radio>
    <!-- 复选输入框 -->
    <s:checkboxlist list="{'乒乓球','打代码'}" name="hobby" label="爱好"></s:checkboxlist>
    <!-- 下拉输入框 -->
    <s:select list="{'中学','高中','大学'}" name="level" label="受教育水平"></s:select>
    <!-- 文件上传 -->
    <s:file name="file" label="文件上传"></s:file>
    <!-- 文本域 -->
    <s:textarea rows="10" cols="6" name="resume" label="简历"></s:textarea>
    <!-- 提交按钮 -->
    <s:submit value="提交"></s:submit>
    <!-- 重置 -->
    <s:reset value="重置"></s:reset>

</s:form>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值