码迷,mamicode.com
首页 > 其他好文 > 详细

Struts2小部分笔记1

时间:2015-02-03 18:58:25      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

什么是MVC

M-Model 模型
模型的职责是负责业务逻辑。包括两部分:业务数据和业务处理逻辑
比如实体类、DAO、Service都属于模型层。
 
V-View视图
视图的职责是负责显示界面和用户交互
属于视图的类不包含业务逻辑和控制逻辑的JSP(如果在JSP页面中有<%%>就不能算是视图,或者JSP中有转发和重定向的控制也是不可以的)。
 
C-Controller控制器
控制器是模型层M和视图层V之间的桥梁,用于控制流程。
 
 
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
 
<package name="helloworld"  extends="struts-default"
namespace="/">     package的名称不可以重复,主要用于继承,extends可以写成extends="struts-default,json-default,"
 

OGNL表达式

基本类型属性(包括String )  
      例如id ,name
数组和List 
      例如array[0], list[0]
Map
     例如:map[‘key‘], map.key
基本运算
调用方法
调用静态方法
创建List ,Map
       创建List:{1,2,3,4,5}
       创建Map: #{‘key1‘:‘value1‘,‘key2‘:‘value2‘}
关联属性
       empList[1].name
投影
过滤
 
 
Ognl.getValue("id",foo);//基本类型属性
Ognl.getValue("array[0]",foo);//数组,List属性
Ognl.getValue("list[1]",foo);
 
Ognl.getValue("map.one",foo);//Map属性
Ognl.getValue("map[two]",foo);
 
Ognl.getValue("id+100",foo);//基本运算
Ognl.getValue("\‘What is \‘+name",foo);
Ognl.getValue("id>500",foo);
 
Ognl.getValue("name.toUpperCase( )",foo)//调用方法
Ognl.getValue("list.size( )",foo);
Ognl.getValue("map[‘three‘].lastIndexOf(name)", foo);
 
Ognl.getValue("@java.util.Arrays@toString(atty)", foo);//调用静态方法
 
Ognl,getValue("{1,2,3,4,5}",null);//创建List
Ognl.getValue("#{1:‘value1‘,2:‘value2‘ , 3:‘value3‘}",null);//创建Map对象
 
标准OGNL结构
技术分享
技术分享
root对象:Ognl操作的对象
context对象:就是一个Map,用于存放一个和整个系统都相关的公共数据
当有了Ognl引擎,我们就可以访问各种各样的root对象(比如Emp对象,Dept对象)在访问中有一些数据是每一次访问都需要用到的,这些数据就可以保存在context对象中。
 
XWork对Ognl的扩展
技术分享
技术分享
OGNL引擎
CompoundRoot对象:在XWork中,root对象被改为类似“栈”一样的存储空间,在该对象空间内可以存放多个root对象。
当取数据时符合“栈”的规则,如果OGNL表达式是“name”,在CompoundRoot从栈顶开始依次看是否有name属性。
 
 
 
ValueStack基本结构
技术分享
Struts2将XWork对Ognl的扩展这一套机制封装起来,这个对象叫ValueStack。
 
技术分享
 
Struts2在请求到来时,首先会创建一个ValueStack;
然后,把当前的Action对象放入栈顶(CompoundRoot);
Struts2会把ValueStack存放在request中,属性为“struts.valueStack”,
所以标签库可以访问到ValueStack
 
Struts2的许多标签就是通过访问ValueStack获取数据的:
      <s;property value="ognl表达式"/>
      <s:property/>取出ValueStack的栈顶
依次将集合中的对象至于栈顶
<s:iterator value="ognl...list">
<s:property value="name"/>
</s:iterator>
 

Struts2如何支持EL

Struts2通过StrutsRequestWrapper,重写了getAttribute方法。
 
<%@page pageEncoding = "utf-8"%>
<%taglib uri="/struts-tags" prefix="s"%>
<!--struts2通过标签库访问valueStack
<s:property value="ognl表达式"/>通过OGNL表达式访问ValueStack
把得到的数据显示出来
value属性:用户所提供德尔OGNL表达式
如果省略values属性,取出来的是CompoundRoot的栈顶
-->
 
<s:property value="name"/>
可调用方法
<s;property arry[1].toUpperCase()"/>
 
name属性存放于DebugAction中,DebugAction位于ValueStack中,ValueStack存放在request中,我们是不能直接找到name的,为何可以在页面使用EL表达式
因为Struts2支持EL表达式,它通过StrutsRequestWapper重写了getAttribute方法
 
 
 

Action基本原理

每次请求都会创建一个新的Action的实例
       因为每次都对应一个单独的Action,所以不需要考虑线程安全问题
Action对象将置于ValueStack的栈顶
Action的业务方法(默认为execute)根据输入算输出
 

在Action中如何访问Session&Application

1 使用ActionContext访问Session
ActionContext ctx = ActionContext.getContext( );//获取session的方法
Map<String,Object>  session = ctx.getSession( );
session.put(‘user‘, user);
 
Map application = ctx.getApplication( );
session ,application将存放在ValueStack的Context中
 
<s:property value="#session.xxx"/>
<s:property value="#session[user].username"/>
 
<s:property value="#application.xxx"/>
 
不推荐使用ActionContext访问Session的方式,因为这种方式的侵入性较强。ActionContext是Struts2的API ,如果使用其他框架代替目前的Struts2框架,而我们实际项目中的Action的数量非常庞大,每个类都修改会很费劲
 

2 通过实现SessionAware接口访问session(更好)

新建BaseAction implements SessionAware
      protected Map<String,Object> session;//为了让子类也能使用,所以访问控制为protected,还需提供setSession方法
     
所有需要session的XXXAction extends BaseAction
 
接口
org.apache.struts2.interceptor.ServletRequestAware
org.apache.struts2.interceptor.ServletResponseAware
org.apache.struts2.interceptor.SessionAware
org.apache.struts2.util.ServletContextAware
 
request 对应  ServletRequestAware
response对应 ServletResponseAware
session 对应 sessAware
application 对应 ServletContextAware
 
 
使用通配符配置Action
<action name="*_*_*" class="com.{1}Action" method="{2}">
        <result name="success" >/WEB-INF/jsp/{3}.jsp</result>
</action>
 
给Action注入参数
<param name="pageSize">10</param>
 
在result的配置中使用OGNL表达式
<result name="success" type="dispatcher">
        /WEB-INF/jsp/user.jsp?userId=${user.userId}
</result>
 
 

结果类型

 
<package name="core" extends="struts-defalut" namespace="/">
 
chain
dispatcher
freemarker
httpheader
redirect
redirectAction
stream
velocity
xslt
plainText
 
 
<package name="json" extends="json-defalut" namespace="/json">
需要导入json相关的jar包,json-defalut在struts-defalut的基础上增加了json结果类型
json  
 
如果不写type默认为dispatcher
 
 

Struts2核心标签库

UI标签
form
textfield
password
submit
textarea
checkbox
radio
select
 
通用属性,需要主题为xhtml
label
labelposition
required
tooltip
tooltipIconPath
 
cssClass
cssStyle
name
value
 
<s:form></form>
theme
namespace
action
method
 
<s:textfield>  <s:password>
maxLength
size
readonly
 
<s:textarea>
cols
rows
 
<s:checkbox>
<s:checkbox name="product"  fieldValue="1"/>
<s:checkbox name="product"  fieldValue="2"/>
<s:checkbox name="product"  fieldValue="3"/>
 
动态获得
<s:iterator value="products">
   <s:checkbox name="product" fieldValue="%{id}"/>
</s:iterator>
 
<s:radio>
<input type="radio" name="abc" value="1"/>One
<input type="radio" name="abc" value="2"/>Two
<input type="radio" name="abc" value="2"/>Three
<s:radio list="productOptions" label="Radio" name="abc"
        listValue="label" listKey="value"/>
属性含义
name
label
list   需要迭代的集合 OGNL
listValue 作用于每一个选项的提示 OGNL
listKey 作用于每一个要提交的值OGNL
 
<s:select>
<select name="abc">
          <option value="1">One</option>
          <option value="2">Two</option>
          <option value="3">Three></option>
</select>
 
 
Struts2标记
<s:select list="productOptions" label="Select" name="abc"
           listValue="label" listKey="value"/>
属性含义
listValue 对应每一个Option的文本
listKey 对应每一个Option提交的值
headerValue 提示头的文字
headerKey 提示头对应的提交值
 
 
<s:action name="" executeResult="true false"/>
name 表示Action的名称
executeResult 值为true、false,true表示在页面显示action,false表示不显示。
 
 
<s:debug/>
 
<s:iterator value="userList" status="st"></s:iterator>
<s:debug/>
st对应的类是InteratorStatus
//count index first last even odd
count属性 从1开始计数
index属性 下标,从0开始计数
first属性,是否为第一个元素
modulus(n)  count除以n后取余
 
<s:date name="date"  format="yyyy年MM月dd日 E"/>
2015年02月03日 星期二
 
 
<s:url action="XXAction"  var="urladdress"/>
用于产生一个地址,可以连接到某个action
var 自定义的变量名,将产生的地址放入ValueStack中。
<a href="${urladdress}">click me</a>
 
 
<s:url action=""   var=""  includeParams="get/none/all"/>
includeParams属性  值可取get/none/all
      值get 仅get请求本页面的参数,加于本url之后
      值none 表示没有此功能(默认)
      值all  表示自动将请求页面的参数,加于本url之后
 
 
 
有时,我们希望valueStack中的某些数据能存放于4个范围内(pageContext、request、session、application),更加方便操作
<s:set  var=""  value = "" scope=""/>
从valueStack中取出数据,放入4个范围中
scope 指定4个范围之一(pageContext、request、session、application)
value  Ognl表达式
<s:url action="XXAction" var="urladdress"/>
<a href="${urladdress}">click me</a>
<s:set var="url" value="#urladdress" scope="pageContext"/>
<a href="${url}">Click me</a>
 
 
<s:if  test="userList.size()>5">
</s:if>
 
 
 
在页面可以直接使用Action中的含有get方法的字段。
 
技术分享
 
技术分享
 

拦截器

struts-default.xml
在<interceptors>标签中定义了许多拦截器
比如
<interceptor  name="fileUpload">
封装了文件上传的功能,对应的类为
class="org.apache.struts2.interceptor.FileUploadInterceptor"/>
 
 
<interceptor-stack name="basicStack">
......
</interceptor-stack>
拦截器栈,在拦截器栈 中包含着若干拦截器的引用
如果“拦截器” 比作文件,那么“拦截器“相当于文件夹。
 
"拦截器栈"中,还可以有"拦截器栈",那么可以说"拦截器栈"也可以当做"拦截器"来用,相当于我们认为"文件夹"也是"文件"的一种。
 
 

总结一下

1)在package中定义拦截器
<interceptor name="" class="类完全限定名">
2)在package中定义拦截器栈
 <interceptor-stack name="">
         <interceptor-ref name="">
</interceptor-stack>
 
3)package中定义默认拦截器
<default-interceptor-ref name=""/>
4)action定义拦截器
<action name=""   class="">
         <!-- 表示访问该action前先调用这个拦截器-->
         <interceptor-ref name="">
                <param name=""></param>
         </interceptor>
</action>
 
 
文件上传的拦截器配置
<interceptor-ref name="fileUpload">
      <param name="maximumSize">102400</param>
</interceptor-ref>
<interceptor-ref name="basicStack"/> 这里用defalutStack吧?
上传文件如果大于102400字节,将报500错误
 
File file1
String file1FileName//固定格式
String file1ContentType
 
 
技术分享
 技术分享

Struts2控制流程

请求到来
创建ValueStack(Action放栈顶),进行初始化
调用拦截器Interceptor,在拦截器中是可以访问ValueStack的
调用Action,执行execute( )方法
调用Result,Result负责把数据显示该用户
最后到页面,通过标签取出数据 
 

自定义拦截器

public class SomeInterceptor implements Intercepor{
      public void destroy(){ }
      public void init( ){ }
      public String intercept(ActionInvocation actionInvocation)   throws Exception{
         //获取ValueStack对象
        ValueStack stack = actionInvocation.getStack( );
        //获取和设置ValueStack中的值
         stack.findValue("ognl表达式");
         stack.setValue(arg0,arg1)
      
      //调用Action 的2种方法,在调用拦截器的过程中,我们通过手动添加代码来调用Action
      //第1种
       String result = actionInvocation.invoke( );
     //第2种
       String result = actionInvocation.invokeActionOnly( );       
 
      return "two";
      }
}
 
ActionInvocation类封装了Action调用过程中所需要的一切API,
技术分享

actionInvocation.invoke( )和actionInvocation.invokeActionOnly( )的区别是什么?

如果拦截器SomeInterceptor中调用了actionInvocation.invoke( )方法,将调用Result对象,既然有了Reslut对象,execute 方法已经执行了返回结果
那么在SomeInterceptor中,返回值是什么都可以
String result = actionInvocation.invoke( );
return "abc";
所以,如果在拦截器中调用了actionInvocation.invoke( ),返回结果 return null即可。
 
如果拦截器SomeInterceptor中调用了actionInvocation.invokeActionOnly( )方法,将不会调用Result对象,这样一来,拦截器SomeInterceptor的intercept( ) 方法的返回值是必须写的。
String result = actionInvocation.invokeActionOnly( );
return "fail";
 
所以,要想让拦截器决定返回值是什么(返回到哪个页面),则调用actionInvocation.invokeActionOnly( )方法。
 
 

自定义拦截器步骤

1)实现Interceptor接口,实现intercept方法
2)获取ValueStack
 ValueStack stack = actionInvocation.getStack( );
获取Servlet API
HttpServletRequest request = ServletActionContext.getRequest( );
HttpServletResponse response = ServletActionContext.getResponse( );
ServletContext application = ServletActionContext.getServletContext( );
调用Action
Action连Result一起调用
actionInvocation.invoke();
此后,intercept方法的返回值无意义
只调用Action,没有调用Result
actionInvocation.invokeActionOnly( );
此后,由intercept( )方法的返回值来决定执行哪个Result
设置参数
 
 
 

Struts2小部分笔记1

标签:

原文地址:http://www.cnblogs.com/LDDXFS/p/4270466.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!