Struts2笔记

来源:互联网 发布:爱国者诚信联盟知乎 编辑:程序博客网 时间:2024/05/17 23:00

Struts2核心控制器

在web.xml文件中配置过滤器

<filter>    <filter-name>struts2</filter-name>    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>    <!-- 配置常量,后缀名,会覆盖之前所有的同名常量设置 -->    <init-param>        <param-name>struts.action.extension</param-name>        <param-value>action,,</param-value>    </init-param></filter> <filter-mapping>    <filter-name>struts2</filter-name>    <url-pattern>/*</url-pattern></filter-mapping> 

Struts2之Action类

使用Action类时,一般继承ActionSupport类

1.POJO类

POJO(Plain Ordinary Java Object),简单Java对象,无继承,无接口

public class Customer{    /**        Action类中的方法书写要求        public 共有的        必须有返回值,且必须是String类型        方法名可以使任意的,但是不能有参数列表    */    public String add(){        System.out.println("添加客户");        return "add";    }    public String delete(){        System.out.println("添加客户");        return "delete";    }}

2.实现Action接口

  Action接口定义了5个常量,5个常量对应了5个逻辑视图跳转页面,还定义一个execute方法

常量 功能 SUCCESS 成功 INPUT 用于数据表单校验,如果校验失败,跳转INPUT视图 LOGIN 登录 ERROR 错误 NONE 页面不转向

3.实现ActionSupport接口

ActionSupport也继承了Action接口


Struts2配置文件

struts.xml

<pakage>标签属性 描述 name 包名,唯一 extends 继承,一般继承struts-default namspace 名称空间,常用根名称空间”/” abstract 抽象的,很少用,若为true,此包是被继承的
<action>标签属性 描述 name 和名称空间一起决定访问路径 class Action类的全路径(默认值是ActionSupport类) method Action类中执行的方法,默认值execute
<result>标签 描述 name 结果页面逻辑视图名称 type 结果类型(默认转发,可设置其它值)
type 描述 dispatcher 转发 redirect 重定向 chain 多个Action之间跳转,转发 redirectAction 多个Action之间跳转,重定向 stream 文件下载时使用
<struts>    <!--         修改常量         会覆盖default.properties中的同名常量         也可以在struts.properties和web.xml中设置         在包外面设置    -->    <!-- 修改请求路径后缀名,加,,不写后缀也能加载 -->    <constant name="struts.action.extension" value="action,,"/>    <!-- 字符编码 -->    <constant name="struts.i18n.encoding" value="UTF-8"/>    <!-- 整合spring时需要配置 -->    <constant name="struts.objectFactory.spring.autoWire" value="name"/>    <!-- 文件上传大小限制,2M -->    <constant name="struts.multipart.maxSize" value="2097152"/>    <!-- 浏览器缓存,开发环境下关闭,生产环境下打开 -->    <constant name="struts.serve.static.browserCache" value="true"/>    <!-- 动态方法的访问 -->    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>    <!-- 在开发环境下,修改代码后会自动加载,不需要重启服务器 -->    <constant name="struts.devMode" value="false"/>    <!-- 全局结果页面 -->    <global-result>        <result>***.jsp</result>    </global-result>    <!-- 包结构 -->    <pakage name="default" namespace="/" extends="struts-default">        <!-- 配置action name属性与web请求一致 -->        <!-- 传统方式 -->        <action name="addCustomer" class="Customer类的全路径" method="add">            <!-- 配置跳转页面,name属性应等于action中关联方法的返回值 -->            <result name="add">/customer.jsp</result>        </action>        <!-- 通配符方式,应用比较多 -->        <action name="customer_*" class="Customer类的全路径" method="{1}">            <!-- method属性内是第n个出现的*号 -->            <result name="add">/customer.jsp</result>            <result name="delete">/customer.jsp</result>        </action>        <!-- 动态方法访问方式,需要开启常量DynamicMethodInvocation -->        <action name="customer" class="Customer类的全路径">            <result name="add">/customer.jsp</result>            <result name="delete">/customer.jsp</result>        </action>    <!-- 引入配置文件 -->    <include file="com/../struts-part1.xml"/></struts>

Struts2之web请求

<!-- addCustomer.action中的addCustomer与配置文件action标签中的name属性一致 --><!-- 传统方式 --><a href="${pageContext.request.contextPath}/addCustomer.action"></a><!-- 通配符方式 --><a href="${pageContext.request.contextPath}/customer_add.action"></a><a href="${pageContext.request.contextPath}/customer_delete.action"></a><!-- 动态方法访问方式,需要开启常量 --><a href="${pageContext.request.contextPath}/customer!add.action"></a><a href="${pageContext.request.contextPath}/customer!delete.action"></a>

Struts2执行流程

Created with Raphaël 2.1.0启动服务器创建核心过滤器StrutsPrepareAndExecuteFilterinit()方法被执行,加载配置文件调用很多拦截器调用目标action中的方法,并返回字符串匹配result,跳转页面结束

Struts2配置文件加载顺序

后加载的配置文件会覆盖之前的配置文件

Created with Raphaël 2.1.0启动服务器创建核心过滤器StrutsPrepareAndExecuteFilterinit()方法被执行,加载配置文件org/apache/struts2/default/default.properties(各种常量)struts-default.xml(大量拦截器,具体功能)struts.xml(自定义)web.xml(自定义)结束

Struts2操作Servlet的API

1.完全解耦合方式

ActionContext——–Action上下文对象

ActionContext context = ActionContext.getContext();//获取请求参数,相当于request.getParameterMap();Map<String,Object> param = context.getParameters()://获取代表Session域的集合,就相当于操作SessionMap<String,Object> session = context.getParameters()://获取Application域,最大的域对象Map<String,Object> application = context.getApplication();//将值存入request域对象context.put("a","a");

2.使用原生Servlet的API的方式

ServletActionContext

//获取原生request域对象HttpServletRequest request = ServletActionContext.getRequest();HttpServletResponse response = ServletActionContext.getResponse();......

Struts2之数据封装

1.属性驱动的方式

1.直接在Action中提供属性的set方法
private String username;private String password;private void setUsername(String username){    this.username = username;}private void setPassword(String password){    this.password = password;}
用户名:<input type="text" name="username">密码:<input type="text" name="password">
2.把数据封装到JavaBean对象当中

在Action中提供,JavaBean的set和get方法
页面使用OGNL表达式的写法

private User user;private void setUser(User user){    this.user = user;}private User getUser(){    return user;}
用户名:<input type="text" name="user.username">密码:<input type="text" name="user.password">
3.把数据封装到集合中
  1. List集合

    private List<User> list;public List<User> getList(){    return list;}public void setList(List<User> list){    this.list = list;}
    <!-- OGNL表达式 -->用户名:<input type="text" name="list[0].username">密码:<input type="text" name="list[0].password">用户名:<input type="text" name="list[1].username">密码:<input type="text" name="list[1].password">
  2. Map集合

    private Map<String,User> map;public Map<String,User> getMap(){    return map;}public void setMap(Map<String,User> map){    this.map = map;}
    <!-- OGNL表达式 -->用户名:<input type="text" name="map['one'].username">密码:<input type="text" name="map['one'].password">用户名:<input type="text" name="map['two'].username">密码:<input type="text" name="map['two'].password">

2.模型驱动的方式

实现ModelDriven接口,必须手动实例化一个对象

//必须手动实例化private User user = new User();public User getModel(){    return User;}//小技巧,正常如下书写,符合JavaBean规范,在jsp页面使用OGNLprivate User model = new User();public User getModel(){    return model;}

Struts2之拦截器

AOP,动态代理
自定义拦截器

public class MyInterceptor extends AbstractInterceptor{    public String intercept(ActionInvocation invocation) throws Exception{        System.out.println("执行Action之前");        String result = invocation.invoke;        System.out.println("执行Action之后");        return result;    }}
  1. 方式1

    <interceptors>    <!-- 定义拦截器 -->    <interceptor name="MyInterceptor" class="com...MyInterceptor"/></interceptors><action name="userAction" class="com...UserAction">    <!-- Action中引用拦截器 -->    <interceptor-ref name="MyInterceptor">    <interceptor-ref name="defaultStack"></action>
  2. 方式2

    <interceptors>    <!-- 定义拦截器 -->    <interceptor name="MyInterceptor" class="com...MyInterceptor"/>    <!-- 自定义拦截器栈 -->    <interceptor-stack name="myStack">        <interceptor-ref name="MyInterceptor">        <interceptor-ref name="defaultStack">    </interceptor-stack></interceptors><action name="userAction" class="com...UserAction">    <!-- Action中引用拦截器 -->    <interceptor-ref name="myStack"></action>

Struts2之OGNL表达式

Struts2 提供值栈,把数据存到值栈中,转发到JSP页面上,在JSP页面中从值栈中取值

<!-- 引入Struts2标签库 --><%@ taglib prefix="s" uri="/struts-tags"%><!-- 使用Struts2标签从值栈中取值  --><s:property value="OGNL表达式"/><!-- 访问对象的方法 --><s:property value="'hello'.length()"/>

Struts2之值栈

每一个请求都对应一个valuestack对象
struts框架把 ValueStack对象保存在request域对象中名为"struts.vlaueStack"的请求属性中

1.值栈ValueStack的结构

  • ValueStack是由root栈和context栈组成
  • root栈是一个Arraylist集合
  • Action默认会被压入root栈
  • context栈是一个Map集合
  • 默认压入以下Map集合
  • 如果从root栈取值,OGNL表达式默认情况下不能写#,<s:property value="表达式"/>
  • 如果从context栈中取值,OGNL表达式默认情况下需要写#,<s:property value="#表达式"/>
  • 只要说操作值栈,默认说就是操作root栈,context栈默认是框架压栈
context栈,key context栈,value 方法 request Map<k,v> ServletActionContext.getRequest(); session Map<k,v> ActionContext.getContext().getSession(); application Map<k,v> ActionContext.getContext().getApplication(); parameters Map<k,v> ActionContext.getContext().getParameters(); attr Map<k,v> 按顺序检索request,session,application下的属性
//获取值栈的三种方法ValueStack vs1 = (ValueStack)request.getAttribute("struts.vlaueStack");ValueStack vs2 = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);ValueStack vs3 = ActionContext.getContext().getValueStack();

2.将数据压入root栈

  • push(Object);
    将Object压入root栈栈顶

    ValueStack vs = ActionContext.getContext().getValueStack();vs.push(Object);
  • set(key,value)
    向root栈栈顶压入Map集合,把key和value存入到Map集合中
    如已存在Map集合,那直接把key和value存入Map集合中

3.jsp页面从root栈取值

<!-- vs.put(Object); --><!-- 数字为0则从栈顶取后面所有,为1则取栈顶下面开始取后面所有 --><s:property value="[0]"/><!-- 数字为0则取栈顶,为1则取栈顶下面一个 --><s:property value="[0].top"/><!-- vs.set("key","value"); --><s:property value="[0].top.key"/>
<!--User user = new User("username","password");vs.push(user);--><s:property value="[0].top.username"/><s:property value="[0].top.password"/><!-- [0].top可以省略 --><s:property value="username"/><s:property value="password"/>
<!--User user = new User("username","password");vs.set("user",user);--><s:property value="[0].top.user.username"/><s:property value="[0].top.user.password"/><!-- [0].top可以省略 --><s:property value="user.username"/><s:property value="user.password"/>
//Action默认会被压入root栈,user为Action属性private User user;public User getUser(){    return user;}public void setUser(User user){    this.user = user;}User user = new User("username","password");vs.set("user",user);//将user放入栈顶Map集合
<!-- 从栈顶取 --><s:property value="user.username"/><s:property value="user.password"/><!-- 从Action中取 --><s:property value="[1].top.user.username"/><s:property value="[1].top.user.password"/>
//在值栈中保存list集合,push和set二选一List<User> list = new ArrayList<User>();list.add(new User("aaa","111"));list.add(new User("aaa","111"));vs.push(list);//直接压入栈顶vs.set("list",list)//放入栈顶的Map集合中
<!-- push,从值栈中取出list集合 --><s:property value="[0].top[0].username"/><s:property value="[0].top[1].username"/><!-- set,从值栈中取出list集合 --><s:property value="list[0].username"/><s:property value="list[1].username"/>

3.Struts2迭代标签iterator

<!--value:值栈中取出的,需要迭代的list集合var:迭代过程中遍历的对象--><!--如果写了var,会把迭代产生的对象压入context栈中,从context取值要加#--><s:iterator value="list" var="user" >    <s:property value="#user.username"/>    <s:property value="#user.username"/></s:iterator><!--如果不写var,会把迭代产生的对象压入root栈中--><s:iterator value="list">    <s:property value="username"/>    <s:property value="password"/></s:iterator>

4.从context栈取值

context栈中,默认已经压入request,Session,application,parameters,attr

HttpServletRequest request = ServletActionContext.getRequest();request.setAttrribute("aaa","111");request.getSession.setAttrribute("bbb","222");
<!--从context栈取值,要加#--><s:property value="#request.aaa"/><s:property value="#session.bbb"/>

5.使用EL表达式从值栈取值

//在值栈中保存list集合,push和set二选一List<User> list = new ArrayList<User>();list.add(new User("aaa","111"));list.add(new User("aaa","111"));vs.push(list);//直接压入栈顶vs.set("list",list)//放入栈顶的Map集合中
<c:foreach item="${list}" var="user">    ${user.username}    ${user.password}</c:foreach>

原创粉丝点击