2011年11月8日

(转贴)数据库连接(内连接,外连接,交叉连接)

数据库连接分为:内连接,外连接(左、右连接,全连接),交叉连接
文章地址 : http://www.zxbc.cn/html/20080527/51189.html
转载 
内连接:把两个表中数据对应的数据查出来 
外连接:以某个表为基础把对应数据查出来(全连接是以多个表为基础) 
student表 
no name 
1     a 
2     b 
3     c 
4     d 
grade表 
no grade 
1     90 
2     98 
3     95 
内连接 inner join(查找条件中对应的数据,no4没有数据不列出来) 
语法:select * from student inner join grade on student.no = grade.no 
结果 
student.no name grade.no grade 
1             a             1         90 
2             b             2         98 
3             c             3         95 
左连接(左表中所有数据,右表中对应数据) 
语法:select * from student left join grade on student.no = grade.no 
结果: 
student.no name grade.no grade 
1                 a         1         90 
2                 b         2         98 
3                 c         3         95 
4                 d     
右连接(右表中所有数据,左表中对应数据) 
语法:select * from student right join grade on student.no = grade.no 
结果: 
student.no name grade.no grade 
1                 a         1         90 
2                 b         2         98 
3                 c         3         95 
全连接 
语法:select * from student full join grade on student.no = grade.no 
结果: 
no name grade 
1     a     90 
2     b     98 
3     c     95 
4     d 
1     a     90 
2     b     98 
3     c     95 
注:access 中不能直接使用full join ,需要使用union all 将左连接和右连接合并后才可以

交叉连接
将两个表所有行组合,连接后的行数为两个表行数的乘积(笛卡尔积)
语法,借用上面的例子应该是
select * from student cross join grade

行数应该为12行 :
no name grade 
1     a     90 
2     b     98 
3     c     95 
4     d  
1     a     90 
2     b     98 
3     c     95 
4     d 
1     a     90 
2     b     98 
3     c     95 
4     d 

posted @ 2011-11-30 17:24 AK47 阅读(475) | 评论 (0)编辑 收藏

JAXB向Xml非根节点添加一个或多个属性

JAXB 向Xml非根节点添加一个或多个属性,直接上代码,关于JAXB的相关注解可查阅JAVA API。

原创文章,转载请注明出处。http://www.blogjava.net/kangdy/archive/2011/11/23/364635.html

code1: colors类  根节点
code1
package com.kangdy.test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Colors")
@XmlAccessorType(XmlAccessType.FIELD)
public class Colors {
    
    @XmlElement(name = "red",nillable=true)
    private Red red;
    
    @XmlElement(name = "blue",nillable=true)
    private Blue blue;

    public Red getRed() {
        return red;
    }

    public Blue getBlue() {
        return blue;
    }

    public void setRed(Red red) {
        this.red = red;
    }

    public void setBlue(Blue blue) {
        this.blue = blue;
    }
}

code2:  Red类  子节点
code2package com.kangdy.test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "red")
@XmlAccessorType(XmlAccessType.FIELD)
public class Red {
    
    private String value;
    
    @XmlAttribute(name = "att1")
    private String att;
    
    public String getValue() {
        return value;
    }
    
    public void setValue(String value) {
        this.value = value;
    }

    public String getAtt() {
        return att;
    }

    public void setAtt(String att) {
        this.att = att;
    }
    
}


code3:  类 Blue 子节点
code3
package com.kangdy.test;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "blue")
@XmlAccessorType(XmlAccessType.FIELD)
public class Blue {
    private String value;
    
    @XmlAttribute(name = "att2")
    private String att2;
    
    @XmlAttribute(name = "att1")
    private String att;
    
    public String getAtt() {
        return att;
    }

    public void setAtt(String att) {
        this.att = att;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getAtt2() {
        return att2;
    }

    public void setAtt2(String att2) {
        this.att2 = att2;
    }
}

code4: main类
code4
package com.kangdy.test;

import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Jaxbtest {
    public static void main(String[] args) throws Exception {

        StringWriter writer = new StringWriter();
        JAXBContext jc = JAXBContext.newInstance(Colors.class);
        Marshaller ma = jc.createMarshaller();
        ma.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        
        Colors colors = new Colors();
        Red red = new Red();
        red.setAtt("att-red");
        red.setValue("red");
        Blue blue = new Blue();
        blue.setValue("blue");
        blue.setAtt("att-blue");
        blue.setAtt2("blue-att2");
        colors.setRed(red);
        colors.setBlue(blue);
        
        ma.marshal(colors, writer);
        System.out.println(writer.toString());

    }
}

运行结果:
结果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Colors>
    <red att1="att-red">
        <value>red</value>
    </red>
    <blue att1="att-blue" att2="blue-att2">
        <value>blue</value>
    </blue>
</Colors>

posted @ 2011-11-23 14:33 AK47 阅读(10080) | 评论 (4)编辑 收藏

(转载)关于paramsPrepareParamsStack

原帖地址:
http://hi.baidu.com/%CC%AB%C6%BD%D1%F31986/blog/item/110b13b1384e805e08230259.html
转贴

paramsPrepareParamsStack在Struts 2.0中是一个很奇妙的interceptor stack,以至于很多人疑问为何不将其设置为默认的interceptor stack。paramsPrepareParamsStack主要解决了ModelDriven和Preparable的配合问题,从字面上理解来说, 这个stack的拦截器调用的顺序为:首先params,然后prepare,接下来modelDriven,最后再params。Struts 2.0的设计上要求modelDriven在params之前调用,而业务中prepare要负责准备model,准备model又需要参数,这就需要在 prepare之前运行params拦截器设置相关参数,这个也就是创建paramsPrepareParamsStack的原因。流程如下:
   1. params拦截器首先给action中的相关参数赋值,如id  
   2. prepare拦截器执行prepare方法,prepare方法中会根据参数,如id,去调用业务逻辑,设置model对象
   3. modelDriven拦截器将model对象压入value stack,这里的model对象就是在prepare中创建的
   4. params拦截器再将参数赋值给model对象
   5. action的业务逻辑执行 依据此stack,一个action的代码通常如下

public class UserAction extends ActionSupport implements ModelDriven, Preparable {
    private User user;
    private int id;
    private UserService service; // user business service

    public void setId(int id) {
        this.id = id;
    }

    /**
     * create a new user if none exists, otherwise load the user with the
     * specified id
     */
    public void prepare() throws Exception {
        if (id == 0) {
            user = new User();
        } else {
            user = service.findUserById(id);
        }
    }

    public Object getModel() {
        return user;
    }

    /**
     * create or update the user and then view the created user
     */
    public String update() {
        if (id == 0) {
            service.create(user);
        } else {
            service.update(user);
        }
        return "redirect";
    }

    /**
     * delete the user and go to a default home page
     */
    public String delete() {
        service.deleteById(id);
        return "home";
    }

    /**
     * show the page allowing the user to view the existing data
     */
    public String view() {
        return "view";
    }

    /**
     * show the page allowing the user to view the existing data and change the
     * values
     */
    public String edit() {
        return "input";
    }

在上述代码中,edit和view都不需要根据id再为界面准备数据,因为prepare方法已经准备好了model,这些方法很简单。对于update 方法,prepare首先会从数据库中加载数据,然后params拦截器会将参数值付给model,在update直接更新就可以,不会出现数据被乱更新 的情况。象Hibernate框架,会判断哪些字段更新了,然后进行更新,性能也不会损失。
通过paramsPrepareParamsStack可以让流程更明确,代码更简洁,也更利于大家的交流。

posted @ 2011-11-16 15:39 AK47 阅读(425) | 评论 (0)编辑 收藏

(转载) Struts 2杂谈(1):ValueStack对象的传送带机制

Struts 2杂谈(1):ValueStack对象的传送带机
作者:nokiaguy  原文地址:http://blog.csdn.net/nokiaguy/article/details/4684750
转贴
   众所周知,Strut 2的Action类通过属性可以获得所有相关的值,如请求参数、Action配置参数、向其他Action传递属性值(通过chain结果)等等。要获得 这些参数值,我们要做的唯一一件事就是在Action类中声明与参数同名的属性,在Struts 2调用Action类的Action方法(默认是execute方法)之前,就会为相应的Action属性赋值。
    要完成这个功能,有很大程度上,Struts 2要依赖于ValueStack对象。这个对象贯穿整个Action的生命周期(每个Action类的对象实例会拥有一个ValueStack对象)。当 Struts 2接收到一个.action的请求后,会先建立Action类的对象实例,并且将Action类的对象实例压入ValueStack对象中(实际 上,ValueStack对于相当一个栈),而ValueStack类的setValue和findValue方法可以设置和获得Action对象的属性 值。Struts 2中的某些拦截器正是通过ValueStack类的setValue方法来修改Action类的属性值的。如params拦截器用于将请求参数值映射到相 应成Action类的属性值。在params拦截器中在获得请求参数值后,会使用setValue方法设置相应的Action类的属性。
    从这一点可以看出,ValueStack对象就象一个传送带,当客户端请求.action时,Struts 2在创建相应用Action对象后就将Action对象放到了ValueStack传送带上,然后ValueStack传送带会带着Action对象经过 若干拦截器,在每一拦截器中都可以通过ValueStack对象设置和获得Action对象中的属性值。实际上,这些拦截器就相当于流水线作业。如果要对 Action对象进行某项加工,再加一个拦截器即可,当不需要进行这项工作时,直接将该拦截器去掉即可。
    下面我们使用一个例子来演示这个过程。在这个例子中实现了一个拦截器,该拦截器的功能是将一个属性文件中的key-value对映射成相应的属性的值。如下面是一个属性文件的内容:

    name = 超人
    price = 10000

    我们可以在Action类中定义name和price属性,在Action中引用这个拦截器后,就会自动为属性赋值。
    在使用该拦截器有如下规则:
    1.  拦截器读取的属性文件路径由path参数指定。
    2.  属性文件的编码格式由encoding参数指定,默认值是UTF-8。
    3.  如果某个key中包含有“.”(该符号不能出现在标识符中),则有如下处理方法:
    (1)将Action类的属性名定义为去掉“.”的key。例如,key为person.name,而属性名可定义为personname。
    (2)将Action类的属性名定义为将“.”替换成其他字符的表示符号。例如,key为person.name,而属性名可定义为person_name,其中“_”由separator参数指定。
    4.  如果key太长,也可以直接使用Action参数进行映射,例如,key为country.person.name,可做如下映射:
      <param name="countrypersonname">name</param>
      要注意的是,name属性值不能包含“.”,因此,应将key值中的“.”去掉。现在就可以直接在Action类中定义名为name的属性的,name属性的值会与key值相同。
    5.  上面所有的规则可以同时使用。

拦截器的源代码:

package interceptors;

import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import java.io.InputStream;
import java.io.FileInputStream;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.util.ValueStack;

public class PropertyInterceptor extends AbstractInterceptor
{
    
private static final String DEFAULT_PATH_KEY = "path";
    
private static final String DEFAULT_ENCODING_KEY = "encoding";
    
private static final String DEFAULT_SEPARATOR_KEY = "separator";

    
protected String pathKey = DEFAULT_PATH_KEY;
    
protected String encodingKey = DEFAULT_ENCODING_KEY;
    
protected String separatorKey = DEFAULT_SEPARATOR_KEY;

    
public void setPathKey(String pathKey) 
    {
        
this.pathKey = pathKey;
    }

    
public void setEncodingKey(String encodingKey)
    {
        
this.encodingKey = encodingKey;
    }

    
public void setSeparatorKey(String separatorKey)
    {
        
this.separatorKey = separatorKey;
    }

    @Override
    
public String intercept(ActionInvocation invocation) throws Exception
    {
        ActionConfig config 
= invocation.getProxy().getConfig();

        Map
<String, String> parameters = config.getParams();
        
if (parameters.containsKey(pathKey))
        {
            String path 
= parameters.get(pathKey);
            String encoding 
= parameters.get(encodingKey);
            String separator 
= parameters.get(separatorKey);
            
if (encoding == null)
                encoding 
= "UTF-8";
            
if (separator == null)
                separator 
= "";
            path 
= invocation.getAction().getClass().getResource(path)
                    .getPath();
            Properties properties 
= new Properties();
            InputStream is 
= new FileInputStream(path);
            java.io.Reader reader 
= new java.io.InputStreamReader(is, encoding);
            
            properties.load(reader);
            ActionContext ac 
= invocation.getInvocationContext();
            ValueStack stack 
= ac.getValueStack();
            System.out.println(stack.hashCode());
            Enumeration names 
= properties.propertyNames();
            
while (names.hasMoreElements())
            {
                
//  下面会使用setValue方法修改ValueStack对象中的相应属性值
                String name = names.nextElement().toString();
                
if (!name.contains("."))
                    stack.setValue(name, properties.get(name)); 

                String newName 
= null;
                newName 
= parameters.get(name.replaceAll("//."""));
                
if (newName != null)
                    stack.setValue(newName, properties.get(name));

                
if (!separator.equals(""))
                {
                    newName 
= name.replaceAll("//.""");
                    stack.setValue(newName, properties.get(name));
                }               
                newName 
= name.replaceAll("//.", separator);
                stack.setValue(newName, properties.get(name));
            } 
        }
        
return invocation.invoke();
    }
}

用于测试的Action类的源代码:

package actions;

public class MyAction
{
    
private String name;
    
private Integer price;
    
private String log4jappenderstdout;
    
private String log4j_rootLogger;
    
private String conversionPattern;

    
public String getName()
    {
        
return name;
    }

    
public void setName(String name)
    {
        
this.name = name;
    }

    
public Integer getPrice()
    {
        
return price;
    }

    
public void setPrice(Integer price)
    {
        
this.price = price;
    }

    
public String getLog4jappenderstdout()
    {
        
return log4jappenderstdout;
    }

    
public void setLog4jappenderstdout(String log4jappenderstdout)
    {
        
this.log4jappenderstdout = log4jappenderstdout;
    }

    
public String getLog4j_rootLogger()
    {
        
return log4j_rootLogger;
    }

    
public void setLog4j_rootLogger(String log4j_rootLogger)
    {
        
this.log4j_rootLogger = log4j_rootLogger;
    }

    
public String getConversionPattern()
    {
        
return conversionPattern;
    }

    
public void setConversionPattern(String conversionPattern)
    {
        
this.conversionPattern = conversionPattern;
    }

    
public String execute()
    {
        System.out.println(
"name:" + name);
        System.out.println(
"price:" + price);
        System.out.println(
"log4jappenderstdout:" + log4jappenderstdout);
        System.out.println(
"log4j_rootLogger:" + log4j_rootLogger);
        System.out.println(
"conversionPattern:" + conversionPattern);
        
return null;
    }
}

Action类的配置代码如:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
    "http://struts.apache.org/dtds/struts-2.1.dtd"
>
<struts>
    
<package name="struts" extends="struts-default">

        
<interceptors>
            
<interceptor name="property"
                class
="interceptors.PropertyInterceptor" />
            
<interceptor-stack name="myStack">
                
<interceptor-ref name="defaultStack" />
                
<interceptor-ref name="property" />
            
</interceptor-stack>
        
</interceptors>
        
<action name="test" class="actions.MyAction">
            
<interceptor-ref name="myStack" />
            
<param name="path">/log4j.properties</param>
            
<param name="encoding">UTF-8</param>
            
<param name="separator">_</param>
            
<param name="log4jappenderstdoutlayoutConversionPattern">
                conversionPattern
            
</param>

        
</action>
    
</package>
</struts>

  请将log4j.properties文件复制到WEB-INF/classes目录,并在该文件中加入name和price属性。

测试结果:

name:中国
price:
34
log4jappenderstdout:org.apache.log4j.ConsoleAppender
log4j_rootLogger:error
, stdout
conversionPattern:%d{ABSOLUTE} %5p %c{
1}:%L - %m%n

    由于property拦截器在defaultStack后引用,因此,在该拦截器中设置的属性值是最终结果,如果将property拦截器放在 defaultStack前面(将两个<interceptor-ref>元素掉换一下),就可以通过同名胜Action配置参数或请求参数 来干预最终究输出结果了。

posted @ 2011-11-11 17:21 AK47 阅读(350) | 评论 (0)编辑 收藏

(转贴)Struts2数据传输的背后机制:ValueStack(值栈)

     摘要: (转)Struts2数据传输的背后机制:ValueStack(值栈)原文地址 :http://blog.csdn.net/li_tengfei/article/details/6098134转载 1.     数据传输背后机制:ValueStack(值栈)   在这一切的背后,是因为有了ValueStack(值栈)!   Valu...  阅读全文

posted @ 2011-11-11 16:19 AK47 阅读(806) | 评论 (0)编辑 收藏

structs2配置UrlRewriteFilter

转载每个网页或请求都是一个url地址,一般,这个地址可能是.do,.page,.action之类的并加上'?'号、'&'号查询串等构成的一个长长的的url。很urgly。

一般的url----------------------------------------------------------较好的url
http://www.xxx.net/user/profile.do?id=20001   ====> http://www.xxx.net/user/20001
http://www.xxx.net/forum/board.do?name=java   ====> http://www.xxx.net/forum/java
http://www.xxx.net/forum/thread.do?id=29923   ====> http://www.xxx.net/thread/29923

后者明显较为直观和漂亮。

使用url rewrite可以很好的改善这个状况。网站url rewrite应用是非常广泛的,良好的url设计给用户带来的非常好的体验,同时也能吸引搜索引擎的注意。
原文地址:http://www.iteye.com/topic/53834
使用方式:
1 配置web.xml文件
样例:
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>osivFilter</filter-name>
        <filter-class>
            org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <filter-mapping>
        <filter-name>osivFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--配置UrlRewriteFilter过滤器-->
    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>*.html</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    <filter>
        <filter-name>struts-prepare</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter</filter-class>
        <init-param>
            <param-name>actionPackages</param-name>
            <param-value>com.secneo.action.*.*</param-value>
        </init-param>
    </filter>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>

    <filter>
        <filter-name>struts-execute</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter</filter-class>
    </filter>
    <filter>
        <filter-name>struts-cleanup</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <!--在structs2中使用UrlRewriteFilter过滤器-->
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.action</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.tld</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.tag</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>struts-prepare</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts-prepare</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts-prepare</filter-name>
        <url-pattern>*.tld</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>struts-execute</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts-execute</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts-execute</filter-name>
        <url-pattern>*.tld</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>struts-cleanup</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts-cleanup</filter-name>
        <url-pattern>*.action</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>struts-cleanup</filter-name>
        <url-pattern>*.tld</url-pattern>
    </filter-mapping>
    <listener>
        <listener-class>
            org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>
2  在WEB-INF目录下添加urlrewrite.xml 文件,根据具体需要写规则
样例:
<?xml version="1.0" encoding="utf-8"?>
<urlrewrite>
    <rule>
        <from>^/(.*).html$</from>
        <to type="forward">/$1.action</to>
    </rule>
    <rule>
        <from>^/(.*).html?(.*)$</from>
        <to type="forward">/$1.action?$2</to>
    </rule>
</urlrewrite>

posted @ 2011-11-09 17:22 AK47 阅读(1762) | 评论 (0)编辑 收藏

structs2 filter的执行顺序

根据servlet2.3规范filter执行是按照web.xml配置的filter-mapping先后顺序进行执行。
所以自己配置的过滤器放在structs2的过滤器之前。

posted @ 2011-11-09 15:44 AK47 阅读(353) | 评论 (0)编辑 收藏

structs2拦截器

深入struct2拦截器  这篇文章很好,细致讲解了structs2和拦截器的原理。
http://zhanghong.iteye.com/blog/452465
转载在每次对你的 Action的 execute()方法请求时,系统会生成一个 ActionInvocation对象,这个对象保存了 action和你所配置的所有的拦截器以及一些状态信息。比如你的应用使用的是 defaultStack,系统将会以拦截器栈配置的顺序将每个拦截器包装成一个个 InterceptorMapping(包含拦截器名字和对应的拦截器对象 )组成一个 Iterator保存在 ActionInvocation中。在执行 ActionInvocation的 invoke()方法时会对这个 Iterator进行迭代,每次取出一个 InterceptorMapping,然后执行对应 Interceptor的 intercept(ActionInVocation inv)方法,而 intercept(ActionInInvocation inv)方法又包含当前的 ActionInInvcation对象作为参数,而在每个拦截器中又会调用 inv的 invoke()方法,这样就会进入下一个拦截器执行了,这样直到最后一个拦截器执行完,然后执行 Action的 execute()方法 (假设你没有配置访问方法,默认执行 Action的 execute()方法 )。在执行完 execute()方法取得了 result后又以相反的顺序走出拦截器栈,这时可以做些清理工作。最后系统得到了一个 result,然后根据 result的类型做进一步操作。

配置拦截器:Struts2中提供了大量的拦截器,多个拦截器可以组成一个拦截器栈,系统配置了一个默认的拦截器栈 defaultStack,具体包括那些拦截器以及顺序可以在struts-default.xml中找到。
1)
<package name="default" extends="struts-default">
   <interceptors>
       <interceptor name="timer" class=".."/>
       <interceptor name="logger" class=".."/>
   </interceptors>

   <action name="login"
      class="tutorial.Login">
        <interceptor-ref name="timer"/>
        <interceptor-ref name="logger"/>
         <result name="input">login.jsp</result>
         <result name="success"
            type="redirectAction">/secure/home</result>
   </action>
</package>

2)
<package name="default" extends="struts-default">
   <interceptors>
        <interceptor name="timer" class=".."/>
        <interceptor name="logger" class=".."/>
        <interceptor-stack name="myStack">
           <interceptor-ref name="timer"/>
           <interceptor-ref name="logger"/>
       <interceptor-ref name="defaultStack"/>    
        </interceptor-stack>
    </interceptors>

<action name="login"
     class="tutuorial.Login">
         <interceptor-ref name="myStack"/>
         <result name="input">login.jsp</result>
         <result name="success"
             type="redirectAction">/secure/home</result>
</action>
</package>

拦截器执行顺序:
<interceptor-stack name="xaStack">
  <interceptor-ref name="thisWillRunFirstInterceptor"/>
  <interceptor-ref name="thisWillRunNextInterceptor"/>
  <interceptor-ref name="followedByThisInterceptor"/>
  <interceptor-ref name="thisWillRunLastInterceptor"/>
</interceptor-stack>

执行顺序:
thisWillRunFirstInterceptor
  thisWillRunNextInterceptor
    followedByThisInterceptor
      thisWillRunLastInterceptor
        MyAction1
        MyAction2 (chain)
        MyPreResultListener
        MyResult (result)
      thisWillRunLastInterceptor
    followedByThisInterceptor
  thisWillRunNextInterceptor
thisWillRunFirstInterceptor


自定义拦截器:必须实现 com.opensymphony.xwork2.interceptor.Interceptor 也可以继承 AbstractInterceptor

拦截器要保证线程安全。因为structs2中拦截器会在请求间共享

posted @ 2011-11-08 18:35 AK47 阅读(1429) | 评论 (0)编辑 收藏

(转贴)struts2 工作原理图

     摘要: 原贴地址:http://blog.csdn.net/qjyong/article/details/1795833转贴 最近学习struts2,其实它就是webwork2.2的升级版,现附上原理图 上图来源于Struts2官方站点,是Struts 2 的整体结构。一个请求在Struts2框架中的处理大概分为以下几个步骤1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求2 ...  阅读全文

posted @ 2011-11-08 15:10 AK47 阅读(1623) | 评论 (0)编辑 收藏

<2011年11月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

导航

统计

常用链接

留言簿

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜