2011年11月30日

          (轉(zhuǎn)貼)數(shù)據(jù)庫連接(內(nèi)連接,外連接,交叉連接)

          數(shù)據(jù)庫連接分為:內(nèi)連接,外連接(左、右連接,全連接),交叉連接
          文章地址 : http://www.zxbc.cn/html/20080527/51189.html
          轉(zhuǎn)載 
          內(nèi)連接:把兩個表中數(shù)據(jù)對應(yīng)的數(shù)據(jù)查出來 
          外連接:以某個表為基礎(chǔ)把對應(yīng)數(shù)據(jù)查出來(全連接是以多個表為基礎(chǔ)) 
          student表 
          no name 
          1     a 
          2     b 
          3     c 
          4     d 
          grade表 
          no grade 
          1     90 
          2     98 
          3     95 
          內(nèi)連接 inner join(查找條件中對應(yīng)的數(shù)據(jù),no4沒有數(shù)據(jù)不列出來) 
          語法:select * from student inner join grade on student.no = grade.no 
          結(jié)果 
          student.no name grade.no grade 
          1             a             1         90 
          2             b             2         98 
          3             c             3         95 
          左連接(左表中所有數(shù)據(jù),右表中對應(yīng)數(shù)據(jù)) 
          語法:select * from student left join grade on student.no = grade.no 
          結(jié)果: 
          student.no name grade.no grade 
          1                 a         1         90 
          2                 b         2         98 
          3                 c         3         95 
          4                 d     
          右連接(右表中所有數(shù)據(jù),左表中對應(yīng)數(shù)據(jù)) 
          語法:select * from student right join grade on student.no = grade.no 
          結(jié)果: 
          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 
          結(jié)果: 
          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 將左連接和右連接合并后才可以

          交叉連接
          將兩個表所有行組合,連接后的行數(shù)為兩個表行數(shù)的乘積(笛卡爾積)
          語法,借用上面的例子應(yīng)該是
          select * from student cross join grade

          行數(shù)應(yīng)該為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 閱讀(495) | 評論 (0)編輯 收藏

          2011年11月23日

          JAXB向Xml非根節(jié)點(diǎn)添加一個或多個屬性

          JAXB 向Xml非根節(jié)點(diǎn)添加一個或多個屬性,直接上代碼,關(guān)于JAXB的相關(guān)注解可查閱JAVA API。

          原創(chuàng)文章,轉(zhuǎn)載請注明出處。http://www.aygfsteel.com/kangdy/archive/2011/11/23/364635.html

          code1: colors類  根節(jié)點(diǎn)
          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類  子節(jié)點(diǎn)
          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 子節(jié)點(diǎn)
          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());

              }
          }

          運(yùn)行結(jié)果:
          結(jié)果
          <?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 閱讀(10142) | 評論 (4)編輯 收藏

          2011年11月16日

          (轉(zhuǎn)載)關(guān)于paramsPrepareParamsStack

          原帖地址:
          http://hi.baidu.com/%CC%AB%C6%BD%D1%F31986/blog/item/110b13b1384e805e08230259.html
          轉(zhuǎn)貼

          paramsPrepareParamsStack在Struts 2.0中是一個很奇妙的interceptor stack,以至于很多人疑問為何不將其設(shè)置為默認(rèn)的interceptor stack。paramsPrepareParamsStack主要解決了ModelDriven和Preparable的配合問題,從字面上理解來說, 這個stack的攔截器調(diào)用的順序?yàn)椋菏紫萷arams,然后prepare,接下來modelDriven,最后再params。Struts 2.0的設(shè)計(jì)上要求modelDriven在params之前調(diào)用,而業(yè)務(wù)中prepare要負(fù)責(zé)準(zhǔn)備model,準(zhǔn)備model又需要參數(shù),這就需要在 prepare之前運(yùn)行params攔截器設(shè)置相關(guān)參數(shù),這個也就是創(chuàng)建paramsPrepareParamsStack的原因。流程如下:
             1. params攔截器首先給action中的相關(guān)參數(shù)賦值,如id  
             2. prepare攔截器執(zhí)行prepare方法,prepare方法中會根據(jù)參數(shù),如id,去調(diào)用業(yè)務(wù)邏輯,設(shè)置model對象
             3. modelDriven攔截器將model對象壓入value stack,這里的model對象就是在prepare中創(chuàng)建的
             4. params攔截器再將參數(shù)賦值給model對象
             5. action的業(yè)務(wù)邏輯執(zhí)行 依據(jù)此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都不需要根據(jù)id再為界面準(zhǔn)備數(shù)據(jù),因?yàn)閜repare方法已經(jīng)準(zhǔn)備好了model,這些方法很簡單。對于update 方法,prepare首先會從數(shù)據(jù)庫中加載數(shù)據(jù),然后params攔截器會將參數(shù)值付給model,在update直接更新就可以,不會出現(xiàn)數(shù)據(jù)被亂更新 的情況。象Hibernate框架,會判斷哪些字段更新了,然后進(jìn)行更新,性能也不會損失。
          通過paramsPrepareParamsStack可以讓流程更明確,代碼更簡潔,也更利于大家的交流。

          posted @ 2011-11-16 15:39 AK47 閱讀(444) | 評論 (0)編輯 收藏

          2011年11月11日

          (轉(zhuǎn)載) Struts 2雜談(1):ValueStack對象的傳送帶機(jī)制

          Struts 2雜談(1):ValueStack對象的傳送帶機(jī)
          作者:nokiaguy  原文地址:http://blog.csdn.net/nokiaguy/article/details/4684750
          轉(zhuǎn)貼
             眾所周知,Strut 2的Action類通過屬性可以獲得所有相關(guān)的值,如請求參數(shù)、Action配置參數(shù)、向其他Action傳遞屬性值(通過chain結(jié)果)等等。要獲得 這些參數(shù)值,我們要做的唯一一件事就是在Action類中聲明與參數(shù)同名的屬性,在Struts 2調(diào)用Action類的Action方法(默認(rèn)是execute方法)之前,就會為相應(yīng)的Action屬性賦值。
              要完成這個功能,有很大程度上,Struts 2要依賴于ValueStack對象。這個對象貫穿整個Action的生命周期(每個Action類的對象實(shí)例會擁有一個ValueStack對象)。當(dāng) Struts 2接收到一個.action的請求后,會先建立Action類的對象實(shí)例,并且將Action類的對象實(shí)例壓入ValueStack對象中(實(shí)際 上,ValueStack對于相當(dāng)一個棧),而ValueStack類的setValue和findValue方法可以設(shè)置和獲得Action對象的屬性 值。Struts 2中的某些攔截器正是通過ValueStack類的setValue方法來修改Action類的屬性值的。如params攔截器用于將請求參數(shù)值映射到相 應(yīng)成Action類的屬性值。在params攔截器中在獲得請求參數(shù)值后,會使用setValue方法設(shè)置相應(yīng)的Action類的屬性。
              從這一點(diǎn)可以看出,ValueStack對象就象一個傳送帶,當(dāng)客戶端請求.action時,Struts 2在創(chuàng)建相應(yīng)用Action對象后就將Action對象放到了ValueStack傳送帶上,然后ValueStack傳送帶會帶著Action對象經(jīng)過 若干攔截器,在每一攔截器中都可以通過ValueStack對象設(shè)置和獲得Action對象中的屬性值。實(shí)際上,這些攔截器就相當(dāng)于流水線作業(yè)。如果要對 Action對象進(jìn)行某項(xiàng)加工,再加一個攔截器即可,當(dāng)不需要進(jìn)行這項(xiàng)工作時,直接將該攔截器去掉即可。
              下面我們使用一個例子來演示這個過程。在這個例子中實(shí)現(xiàn)了一個攔截器,該攔截器的功能是將一個屬性文件中的key-value對映射成相應(yīng)的屬性的值。如下面是一個屬性文件的內(nèi)容:

              name = 超人
              price = 10000

              我們可以在Action類中定義name和price屬性,在Action中引用這個攔截器后,就會自動為屬性賦值。
              在使用該攔截器有如下規(guī)則:
              1.  攔截器讀取的屬性文件路徑由path參數(shù)指定。
              2.  屬性文件的編碼格式由encoding參數(shù)指定,默認(rèn)值是UTF-8。
              3.  如果某個key中包含有“.”(該符號不能出現(xiàn)在標(biāo)識符中),則有如下處理方法:
              (1)將Action類的屬性名定義為去掉“.”的key。例如,key為person.name,而屬性名可定義為personname。
              (2)將Action類的屬性名定義為將“.”替換成其他字符的表示符號。例如,key為person.name,而屬性名可定義為person_name,其中“_”由separator參數(shù)指定。
              4.  如果key太長,也可以直接使用Action參數(shù)進(jìn)行映射,例如,key為country.person.name,可做如下映射:
                <param name="countrypersonname">name</param>
                要注意的是,name屬性值不能包含“.”,因此,應(yīng)將key值中的“.”去掉。現(xiàn)在就可以直接在Action類中定義名為name的屬性的,name屬性的值會與key值相同。
              5.  上面所有的規(guī)則可以同時使用。

          攔截器的源代碼:

          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對象中的相應(yīng)屬性值
                          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文件復(fù)制到WEB-INF/classes目錄,并在該文件中加入name和price屬性。

          測試結(jié)果:

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

              由于property攔截器在defaultStack后引用,因此,在該攔截器中設(shè)置的屬性值是最終結(jié)果,如果將property攔截器放在 defaultStack前面(將兩個<interceptor-ref>元素掉換一下),就可以通過同名勝Action配置參數(shù)或請求參數(shù) 來干預(yù)最終究輸出結(jié)果了。

          posted @ 2011-11-11 17:21 AK47 閱讀(376) | 評論 (0)編輯 收藏

          (轉(zhuǎn)貼)Struts2數(shù)據(jù)傳輸?shù)谋澈髾C(jī)制:ValueStack(值棧)

               摘要: (轉(zhuǎn))Struts2數(shù)據(jù)傳輸?shù)谋澈髾C(jī)制:ValueStack(值棧)原文地址 :http://blog.csdn.net/li_tengfei/article/details/6098134轉(zhuǎn)載 1.     數(shù)據(jù)傳輸背后機(jī)制:ValueStack(值棧)   在這一切的背后,是因?yàn)橛辛薞alueStack(值棧)!   Valu...  閱讀全文

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

          2011年11月9日

          structs2配置UrlRewriteFilter

          轉(zhuǎn)載每個網(wǎng)頁或請求都是一個url地址,一般,這個地址可能是.do,.page,.action之類的并加上'?'號、'&'號查詢串等構(gòu)成的一個長長的的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可以很好的改善這個狀況。網(wǎng)站url rewrite應(yīng)用是非常廣泛的,良好的url設(shè)計(jì)給用戶帶來的非常好的體驗(yàn),同時也能吸引搜索引擎的注意。
          原文地址: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 文件,根據(jù)具體需要寫規(guī)則
          樣例:
          <?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 閱讀(1783) | 評論 (0)編輯 收藏

          structs2 filter的執(zhí)行順序

          根據(jù)servlet2.3規(guī)范filter執(zhí)行是按照web.xml配置的filter-mapping先后順序進(jìn)行執(zhí)行。
          所以自己配置的過濾器放在structs2的過濾器之前。

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

          2011年11月8日

          structs2攔截器

          深入struct2攔截器  這篇文章很好,細(xì)致講解了structs2和攔截器的原理。
          http://zhanghong.iteye.com/blog/452465
          轉(zhuǎn)載在每次對你的 Action的 execute()方法請求時,系統(tǒng)會生成一個 ActionInvocation對象,這個對象保存了 action和你所配置的所有的攔截器以及一些狀態(tài)信息。比如你的應(yīng)用使用的是 defaultStack,系統(tǒng)將會以攔截器棧配置的順序?qū)⒚總€攔截器包裝成一個個 InterceptorMapping(包含攔截器名字和對應(yīng)的攔截器對象 )組成一個 Iterator保存在 ActionInvocation中。在執(zhí)行 ActionInvocation的 invoke()方法時會對這個 Iterator進(jìn)行迭代,每次取出一個 InterceptorMapping,然后執(zhí)行對應(yīng) Interceptor的 intercept(ActionInVocation inv)方法,而 intercept(ActionInInvocation inv)方法又包含當(dāng)前的 ActionInInvcation對象作為參數(shù),而在每個攔截器中又會調(diào)用 inv的 invoke()方法,這樣就會進(jìn)入下一個攔截器執(zhí)行了,這樣直到最后一個攔截器執(zhí)行完,然后執(zhí)行 Action的 execute()方法 (假設(shè)你沒有配置訪問方法,默認(rèn)執(zhí)行 Action的 execute()方法 )。在執(zhí)行完 execute()方法取得了 result后又以相反的順序走出攔截器棧,這時可以做些清理工作。最后系統(tǒng)得到了一個 result,然后根據(jù) result的類型做進(jìn)一步操作。

          配置攔截器:Struts2中提供了大量的攔截器,多個攔截器可以組成一個攔截器棧,系統(tǒng)配置了一個默認(rèn)的攔截器棧 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>

          攔截器執(zhí)行順序:
          <interceptor-stack name="xaStack">
            <interceptor-ref name="thisWillRunFirstInterceptor"/>
            <interceptor-ref name="thisWillRunNextInterceptor"/>
            <interceptor-ref name="followedByThisInterceptor"/>
            <interceptor-ref name="thisWillRunLastInterceptor"/>
          </interceptor-stack>

          執(zhí)行順序:
          thisWillRunFirstInterceptor
            thisWillRunNextInterceptor
              followedByThisInterceptor
                thisWillRunLastInterceptor
                  MyAction1
                  MyAction2 (chain)
                  MyPreResultListener
                  MyResult (result)
                thisWillRunLastInterceptor
              followedByThisInterceptor
            thisWillRunNextInterceptor
          thisWillRunFirstInterceptor


          自定義攔截器:必須實(shí)現(xiàn) com.opensymphony.xwork2.interceptor.Interceptor 也可以繼承 AbstractInterceptor

          攔截器要保證線程安全。因?yàn)閟tructs2中攔截器會在請求間共享

          posted @ 2011-11-08 18:35 AK47 閱讀(1447) | 評論 (0)編輯 收藏

          (轉(zhuǎn)貼)struts2 工作原理圖

               摘要: 原貼地址:http://blog.csdn.net/qjyong/article/details/1795833轉(zhuǎn)貼 最近學(xué)習(xí)struts2,其實(shí)它就是webwork2.2的升級版,現(xiàn)附上原理圖 上圖來源于Struts2官方站點(diǎn),是Struts 2 的整體結(jié)構(gòu)。一個請求在Struts2框架中的處理大概分為以下幾個步驟1 客戶端初始化一個指向Servlet容器(例如Tomcat)的請求2 ...  閱讀全文

          posted @ 2011-11-08 15:10 AK47 閱讀(1640) | 評論 (0)編輯 收藏

          2011年11月1日

          重新認(rèn)識Java finally

          關(guān)于java finally 網(wǎng)上有2篇文章個人認(rèn)為相當(dāng)不錯
          以下是轉(zhuǎn)貼內(nèi)容:

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

          finally“微型子例程”不等同于方法函數(shù)的調(diào)用,finally子句都是在同一個棧內(nèi)執(zhí)行的,微型子例程的“返回”操作也不會涉及到方法退棧,僅僅是使程序計(jì)數(shù)器pc跳轉(zhuǎn)到同一個方法的一個不同的位置繼續(xù)執(zhí)行。
          一 異常丟失
              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()的輸出結(jié)果是“exception in finally”,而不是try塊中拋出的異常,這是JAVA異常機(jī)制的一個瑕疵-異常丟失。

          在字節(jié)碼中,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) 調(diào)用finally微型子程序
          3) 把局部變量中的Exception("exception in try")對象引用push到操作數(shù)棧頂,然后拋出異常
            aload_2  // push the reference to the thrown exception from local variable 2

            athrow   // throw the exception

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

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

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

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

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

          這個方法的返回值是100還是200?結(jié)果是100。
          在字節(jié)碼中,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) 調(diào)用finally微型子程序
          3) 把局部變量(指temp)的值push到操作數(shù)棧頂,然后返回到調(diào)用方法
               iload_2  // push local varaible 2 - the 100
             ireturn      // return int on top of the stack - the 100: return 100

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

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

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

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

          僅列出標(biāo)題  下一頁
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 霍城县| 舟曲县| 秦皇岛市| 乳源| 白城市| 开化县| 延庆县| 乌鲁木齐县| 枞阳县| 孟村| 仪征市| 马尔康县| 彩票| 即墨市| 五指山市| 顺义区| 石林| 尼勒克县| 温州市| 巴林左旗| 赤城县| 遂昌县| 奉新县| 广宗县| 延长县| 长宁县| 尤溪县| 泗洪县| 哈密市| 施秉县| 德州市| 巴马| 醴陵市| 襄汾县| 东兰县| 察雅县| 诏安县| 文昌市| 会泽县| 满洲里市| 繁昌县|