<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    2011年11月30日

    (轉貼)數據庫連接(內連接,外連接,交叉連接)

    數據庫連接分為:內連接,外連接(左、右連接,全連接),交叉連接
    文章地址 : 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 閱讀(489) | 評論 (0)編輯 收藏

    2011年11月23日

    JAXB向Xml非根節點添加一個或多個屬性

    JAXB 向Xml非根節點添加一個或多個屬性,直接上代碼,關于JAXB的相關注解可查閱JAVA API。

    原創文章,轉載請注明出處。http://www.tkk7.com/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 閱讀(10126) | 評論 (4)編輯 收藏

    2011年11月16日

    (轉載)關于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 閱讀(439) | 評論 (0)編輯 收藏

    2011年11月11日

    (轉載) 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值中的“.”去掉?,F在就可以直接在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 閱讀(372) | 評論 (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 閱讀(818) | 評論 (0)編輯 收藏

    2011年11月9日

    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 閱讀(1776) | 評論 (0)編輯 收藏

    structs2 filter的執行順序

    根據servlet2.3規范filter執行是按照web.xml配置的filter-mapping先后順序進行執行。
    所以自己配置的過濾器放在structs2的過濾器之前。

    posted @ 2011-11-09 15:44 AK47 閱讀(374) | 評論 (0)編輯 收藏

    2011年11月8日

    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 閱讀(1443) | 評論 (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 閱讀(1636) | 評論 (0)編輯 收藏

    2011年11月1日

    重新認識Java finally

    關于java finally 網上有2篇文章個人認為相當不錯
    以下是轉貼內容:

    1 . JAVA finally字句的異常丟失和返回值覆蓋解析
    原帖地址 :
    http://blog.csdn.net/sureyonder/article/details/5560538
    轉貼
    Java虛擬機在每個try語句塊和與其相關的catch子句的結尾 處都會“調用”finally子句的子例程。實際上,finally子句在方法內部的表現很象“微型子例程”。finally子句正常結束后-指的是finally子句中最后一條語句正常執行完畢,不包括拋出異常,或執行return、continue、break等情況,隸屬于這個finally子句的微型子例程執行“返回”操作。程序在第一次調用微型子例程的地方繼續執行后面的語句。

    finally“微型子例程”不等同于方法函數的調用,finally子句都是在同一個棧內執行的,微型子例程的“返回”操作也不會涉及到方法退棧,僅僅是使程序計數器pc跳轉到同一個方法的一個不同的位置繼續執行。
    一 異常丟失
        public static void exceptionLost()  
         {  
           try  
           {  
             try  
             {  
               throw new Exception( "exception in try" );  
             }  
             finally  
             {  
               throw new Exception( "exception in finally" );  
             }  
           }  
           catch( Exception e )  
           {  
             System.out.println( e );  
           }  
         }  

    exceptionLost()的輸出結果是“exception in finally”,而不是try塊中拋出的異常,這是JAVA異常機制的一個瑕疵-異常丟失。

    在字節碼中,throw語句不是原子性操作。在較老的JDK中,exceptionLost()中try塊的throw語句分解為幾步操作:
    1) 把Exception("exception in try")對象引用存儲到一個局部變量中
      astore_2  // pop the reference to the thrown exception, store into local variable 2
    2) 調用finally微型子程序
    3) 把局部變量中的Exception("exception in try")對象引用push到操作數棧頂,然后拋出異常
      aload_2  // push the reference to the thrown exception from local variable 2

      athrow   // throw the exception

    如果finally通過break、return、continue,或者拋出異常而退出,那么上面的第3步就不會執行。

    在JDK1.6中,通過字節碼我們可以看到,finally子句作為一種特殊的catch來實現的,下面是exceptionLost()方法的異常表:

    Exception table:
      from   to   target  type
       0     10    10     any
     0     21    21     Class java/lang/Exception

    finally可以捕獲從0行到9行之間拋出的任何類型(any)的異常,并重新拋出捕獲的異常,或者拋出一個自己構造的新異常,這個新異常就會覆蓋try語句塊中的異常。
    二 返回值覆蓋

        public static int getValue()  
         {  
           int value = 0;  
             
           try  
           {  
             value = 100;  
               
             return value;  
           }  
           finally  
           {  
             value = 200;  
           }  
         }  

    這個方法的返回值是100還是200?結果是100。
    在字節碼中,return語句不是原子性操作,它會把getValue()中的return語句分解為幾步操作:
    1) 把value值存儲到一個局部變量(這里命名為temp)中:
       iload_0   // push local variable 0 - the 100
       istore_2   //  pop an int (the 100), store into local varaible 2
    2) 調用finally微型子程序
    3) 把局部變量(指temp)的值push到操作數棧頂,然后返回到調用方法
         iload_2  // push local varaible 2 - the 100
       ireturn      // return int on top of the stack - the 100: return 100

    由于return語句在返回之前會把返回值保存到一個臨時的局部變量中,所以在finally子句內對value重新賦值不會影響返回值。

    了解finally子句內在的一些知識,我們能夠了解finally能夠做什么和不能夠做什么,這樣會幫助我們正確使用finally子句。

    2 . 關于 Java 中 finally 語句塊的深度辨析
    原帖地址 :
    http://www.ibm.com/developerworks/cn/java/j-lo-finally/index.html?ca=drs-
    轉貼
    關于 Java 虛擬機是如何編譯 finally 語句塊的問題,有興趣的讀者可以參考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 節 Compiling finally。那里詳細介紹了 Java 虛擬機是如何編譯 finally 語句塊。實際上,Java 虛擬機會把 finally 語句塊作為 subroutine(對于這個 subroutine 不知該如何翻譯為好,干脆就不翻譯了,免得產生歧義和誤解。)直接插入到 try 語句塊或者 catch 語句塊的控制轉移語句之前。但是,還有另外一個不可忽視的因素,那就是在執行 subroutine(也就是 finally 語句塊)之前,try 或者 catch 語句塊會保留其返回值到本地變量表(Local Variable Table)中。待 subroutine 執行完畢之后,再恢復保留的返回值到操作數棧中,然后通過 return 或者 throw 語句將其返回給該方法的調用者(invoker)。請注意,前文中我們曾經提到過 return、throw 和 break、continue 的區別,對于這條規則(保留返回值),只適用于 return 和 throw 語句,不適用于 break 和 continue 語句,因為它們根本就沒有返回值。

    posted @ 2011-11-01 16:56 AK47 閱讀(831) | 評論 (0)編輯 收藏

    僅列出標題  下一頁
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿

    隨筆分類

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 久久青草免费91线频观看不卡| 久久免费看黄a级毛片| 亚洲国产精品久久66| 37pao成人国产永久免费视频| 亚洲日本VA中文字幕久久道具| 亚洲国产精品综合久久网络| 亚洲一区免费观看| 亚洲欧美日韩中文字幕一区二区三区| 久久久久亚洲精品天堂久久久久久| 91在线手机精品免费观看| 久久亚洲欧美国产精品| 久久亚洲国产伦理| 国产精品免费电影| 日韩精品极品视频在线观看免费| 在线观看亚洲AV日韩A∨| 国产亚洲免费的视频看| 免费观看男人免费桶女人视频| 中文永久免费观看网站| 久久乐国产综合亚洲精品| 亚洲欧洲日产国码av系列天堂| 成人看的午夜免费毛片| 日韩精品久久久久久免费| 色吊丝性永久免费看码| 色偷偷亚洲女人天堂观看欧| 国产亚洲精品岁国产微拍精品| 日本免费一区二区三区最新| 99免费视频观看| 精品97国产免费人成视频| 亚洲一卡2卡3卡4卡5卡6卡| 亚洲毛片在线观看| 激情综合色五月丁香六月亚洲| 在线播放免费播放av片| 3344永久在线观看视频免费首页| 中文字幕手机在线免费看电影 | 无码少妇一区二区浪潮免费 | 免费大片在线观看网站| a级毛片无码免费真人| 久久免费精品视频| 成人国产精品免费视频| 一级毛片大全免费播放下载| 亚洲第一se情网站|