空間站

          北極心空

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

          Struts2與Struts1對比

          Struts2與Struts1Struts2與Struts1對比
          Action 類:
            Struts1要求Action類繼承一個(gè)抽象基類。Struts1的一個(gè)普遍問題是使用抽象類編程而不是接口。
            Struts 2 Action類可以實(shí)現(xiàn)一個(gè)Action接口,也可實(shí)現(xiàn)其他接口,使可選和定制的服務(wù)成為可能。Struts2提供一

          個(gè)ActionSupport基類去實(shí)現(xiàn) 常用的接口。Action接口不是必須的,任何有execute標(biāo)識的POJO對象都可以用作

          Struts2的Action對象。

          線程模式:
            Struts1 Action是單例模式并且必須是線程安全的,因?yàn)閮H有Action的一個(gè)實(shí)例來處理所有的請求。單例策略限制

          了Struts1 Action能作的事,并且要在開發(fā)時(shí)特別小心。Action資源必須是線程安全的或同步的。
            Struts2 Action對象為每一個(gè)請求產(chǎn)生一個(gè)實(shí)例,因此沒有線程安全問題。(實(shí)際上,servlet容器給每個(gè)請求產(chǎn)生

          許多可丟棄的對象,并且不會導(dǎo)致性能和垃圾回收問題)

          Servlet 依賴:
            Struts1 Action 依賴于Servlet API ,因?yàn)楫?dāng)一個(gè)Action被調(diào)用時(shí)HttpServletRequest 和 HttpServletResponse

          被傳遞給execute方法。
            Struts 2 Action不依賴于容器,允許Action脫離容器單獨(dú)被測試。如果需要,Struts2 Action仍然可以訪問初始的

          request和response。但是,其他的元素減少或者消除了直接訪問HttpServetRequest 和 HttpServletResponse的必要

          性。

          可測性:
            測試Struts1 Action的一個(gè)主要問題是execute方法暴露了servlet API(這使得測試要依賴于容器)。一個(gè)第三方

          擴(kuò)展--Struts TestCase--提供了一套Struts1的模擬對象(來進(jìn)行測試)。
            Struts 2 Action可以通過初始化、設(shè)置屬性、調(diào)用方法來測試,“依賴注入”支持也使測試更容易。

          捕獲輸入:
            Struts1 使用ActionForm對象捕獲輸入。所有的ActionForm必須繼承一個(gè)基類。因?yàn)槠渌鸍avaBean不能用作

          ActionForm,開發(fā)者經(jīng)常創(chuàng)建多余的類捕獲輸入。動態(tài)Bean(DynaBeans)可以作為創(chuàng)建傳統(tǒng)ActionForm的選擇,但是

          ,開發(fā)者可能是在重新描述(創(chuàng)建)已經(jīng)存在的JavaBean(仍然會導(dǎo)致有冗余的javabean)。
            Struts 2直接使用Action屬性作為輸入屬性,消除了對第二個(gè)輸入對象的需求。輸入屬性可能是有自己(子)屬性的

          rich對象類型。Action屬性能夠通過 web頁面上的taglibs訪問。Struts2也支持ActionForm模式。rich對象類型,包

          括業(yè)務(wù)對象,能夠用作輸入/輸出對象。這種 ModelDriven 特性簡化了taglib對POJO輸入對象的引用。

          表達(dá)式語言:
            Struts1 整合了JSTL,因此使用JSTL EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。
            Struts2可以使用JSTL,但是也支持一個(gè)更強(qiáng)大和靈活的表達(dá)式語言--"Object Graph Notation Language"

          (OGNL).

          綁定值到頁面(view):
            Struts 1使用標(biāo)準(zhǔn)JSP機(jī)制把對象綁定到頁面中來訪問。
            Struts 2 使用 "ValueStack"技術(shù),使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來。

          ValueStack策略允許通過一系列名稱相同但類型不同的屬性重用頁面(view)。
           
          類型轉(zhuǎn)換:
            Struts 1 ActionForm 屬性通常都是String類型。Struts1使用Commons-Beanutils進(jìn)行類型轉(zhuǎn)換。每個(gè)類一個(gè)轉(zhuǎn)換

          器,對每一個(gè)實(shí)例來說是不可配置的。
            Struts2 使用OGNL進(jìn)行類型轉(zhuǎn)換。提供基本和常用對象的轉(zhuǎn)換器。

          校驗(yàn):
            Struts 1支持在ActionForm的validate方法中手動校驗(yàn),或者通過Commons Validator的擴(kuò)展來校驗(yàn)。同一個(gè)類可以

          有不同的校驗(yàn)內(nèi)容,但不能校驗(yàn)子對象。
            Struts2支持通過validate方法和XWork校驗(yàn)框架來進(jìn)行校驗(yàn)。XWork校驗(yàn)框架使用為屬性類類型定義的校驗(yàn)和內(nèi)容校

          驗(yàn),來支持chain校驗(yàn)子屬性

          Action執(zhí)行的控制:
            Struts1支持每一個(gè)模塊有單獨(dú)的Request Processors(生命周期),但是模塊中的所有Action必須共享相同的生命

          周期。
            Struts2支持通過攔截器堆棧(Interceptor Stacks)為每一個(gè)Action創(chuàng)建不同的生命周期。堆棧能夠根據(jù)需要和不

          同的Action一起使用。

           

          --------------------------------------------------------------------------------
          注釋struts.action.extension
                    The URL extension to use to determine if the request is meant for a Struts action
                     用URL擴(kuò)展名來確定是否這個(gè)請求是被用作Struts action,其實(shí)也就是設(shè)置 action的后綴,例如

          login.do的'do'字。

          struts.configuration
                    The org.apache.struts2.config.Configuration implementation class
                      org.apache.struts2.config.Configuration接口名

          struts.configuration.files
                    A list of configuration files automatically loaded by Struts
                     struts自動加載的一個(gè)配置文件列表

          struts.configuration.xml.reload
                    Whether to reload the XML configuration or not
                     是否加載xml配置(true,false)

          struts.continuations.package
                     The package containing actions that use Rife continuations
                     含有actions的完整連續(xù)的package名稱

          struts.custom.i18n.resources
                    Location of additional localization properties files to load
                     加載附加的國際化屬性文件(不包含.properties后綴)

          struts.custom.properties
                    Location of additional configuration properties files to load
                     加載附加的配置文件的位置


          struts.devMode
                    Whether Struts is in development mode or not
                     是否為struts開發(fā)模式

          struts.dispatcher.parametersWorkaround
                    Whether to use a Servlet request parameter workaround necessary for some versions of WebLogic
                      (某些版本的weblogic專用)是否使用一個(gè)servlet請求參數(shù)工作區(qū)(PARAMETERSWORKAROUND)

          struts.enable.DynamicMethodInvocation
                    Allows one to disable dynamic method invocation from the URL
                      允許動態(tài)方法調(diào)用

          struts.freemarker.manager.classname
                    The org.apache.struts2.views.freemarker.FreemarkerManager implementation class
                     org.apache.struts2.views.freemarker.FreemarkerManager接口名

          struts.i18n.encoding
                    The encoding to use for localization messages
                     國際化信息內(nèi)碼

          struts.i18n.reload
                    Whether the localization messages should automatically be reloaded
                     是否國際化信息自動加載

          struts.locale
                    The default locale for the Struts application
                     默認(rèn)的國際化地區(qū)信息

          struts.mapper.class
                    The org.apache.struts2.dispatcher.mapper.ActionMapper implementation class
                      org.apache.struts2.dispatcher.mapper.ActionMapper接口

          struts.multipart.maxSize
                    The maximize size of a multipart request (file upload)
                     multipart請求信息的最大尺寸(文件上傳用)

          struts.multipart.parser
                    The org.apache.struts2.dispatcher.multipart.MultiPartRequest parser implementation for a

          multipart request (file upload)
                    專為multipart請求信息使用的org.apache.struts2.dispatcher.multipart.MultiPartRequest解析器接口

          (文件上傳用)


          struts.multipart.saveDir
                    The directory to use for storing uploaded files
                     設(shè)置存儲上傳文件的目錄夾

          struts.objectFactory
                    The com.opensymphony.xwork2.ObjectFactory implementation class
                     com.opensymphony.xwork2.ObjectFactory接口(spring)

          struts.objectFactory.spring.autoWire
                    Whether Spring should autoWire or not
                     是否自動綁定Spring

          struts.objectFactory.spring.useClassCache
                    Whether Spring should use its class cache or not
                     是否spring應(yīng)該使用自身的cache

          struts.objectTypeDeterminer
                    The com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation class
                      com.opensymphony.xwork2.util.ObjectTypeDeterminer接口

          struts.serve.static.browserCache
                    If static content served by the Struts filter should set browser caching header properties or

          not
                     是否struts過濾器中提供的靜態(tài)內(nèi)容應(yīng)該被瀏覽器緩存在頭部屬性中

          struts.serve.static
                    Whether the Struts filter should serve static content or not
                     是否struts過濾器應(yīng)該提供靜態(tài)內(nèi)容

          struts.tag.altSyntax
                    Whether to use the alterative syntax for the tags or not
                     是否可以用替代的語法替代tags

          struts.ui.templateDir
                    The directory containing UI templates
                     UI templates的目錄夾

          struts.ui.theme
                    The default UI template theme
                     默認(rèn)的UI template主題

          struts.url.http.port
                    The HTTP port used by Struts URLs
                     設(shè)置http端口

          struts.url.https.port
                    The HTTPS port used by Struts URLs
                     設(shè)置https端口

          struts.url.includeParams
                    The default includeParams method to generate Struts URLs
                    在url中產(chǎn)生 默認(rèn)的includeParams


          struts.velocity.configfile
                    The Velocity configuration file path
                     velocity配置文件路徑

          struts.velocity.contexts
                    List of Velocity context names
                     velocity的context列表


          struts.velocity.manager.classname
                    org.apache.struts2.views.velocity.VelocityManager implementation class
                     org.apache.struts2.views.velocity.VelocityManager接口名

          struts.velocity.toolboxlocation
                    The location of the Velocity toolbox
                     velocity工具盒的位置
          struts.xslt.nocache
                    Whether or not XSLT templates should not be cached
                     是否XSLT模版應(yīng)該被緩存
          在Struts2中,action中的getXXX()只在服務(wù)器啟動時(shí)執(zhí)行一次,一刷新頁面顯示的數(shù)據(jù)內(nèi)容全都沒了,這種問題的解

          決辦法是:
          在web.xml中配置struts2.0時(shí),
          <filter-mapping>
          <filter-name>action2</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>
          把/*改成*.ation就OK了
          一、Struts2配置文件
          Struts2相關(guān)的配置文件有web.xml,struts.xml,struts.properties,
          struts-default.xml,velocity.properties,struts-default.vm。其中web.xml,struts.xml是必須的,其它的配置

          文件可選擇。它們在web應(yīng)用中的功能如下:
          web.xml:包含所有必須的框架組件的web部署描述符。
          Struts.xml:配置包含result/view類型、action映射、攔截器等的Struts2的主要配置文件。
          Struts.properties:配置struts2的框架屬性。
          Struts-default.xml:在文件在struts-action-x.x.jar中,該文件是應(yīng)該被包含在struts.xml中的缺省配置。
          Welocity.properties:重寫了velocity的配置文件。
          Struts-default.vm:相對于velocity的缺省配置。

          二、Struts2配置元素
          Struts2核心的配置文件是缺省的struts.xml。
          必要的時(shí)候,缺省的配置文件可以包含其它的配置文件;struts文件可以放入jar中,并自動插入應(yīng)用程序,這樣每個(gè)

          模塊可以包含自己的配置文件并自動配置。在Freemarker和Velocity模塊中,模板也能從classpath中加載,所以整個(gè)

          模塊可以作為一個(gè)簡單的jar文件被包含。
          Struts.xml配置文件可以包含Interceptor、Action類和Results。
          Struts.xml配置元素說明:

          1、Packages
          Packages:packages把a(bǔ)ctions、results、results types、interceptors
          和interceptor-stacks組裝到一個(gè)邏輯單元中,從概念上講,packages就像一個(gè)對象,可以被其它子包從寫,而且可

          以擁有自己獨(dú)立的部分。
          Name屬性是packages的必填元素,它作為一個(gè)關(guān)鍵字被后邊的包引用;extends元素是可選的,它允許包擴(kuò)展一個(gè)和多

          個(gè)前邊定義的包。注意,
          struts.xml文件是至上而下處理的,所有被擴(kuò)展的包,需要在擴(kuò)展包前定義。
          Abstract元素是可選的,它可以申明一個(gè)不包含actions的配置文件。

          2、Namespace
          Namespace元素把a(bǔ)ctions細(xì)分到邏輯模塊,每一個(gè)namespace都有自己的
          前綴(prefix),namespace避免了action之間的名字沖突,當(dāng)前綴出現(xiàn)在URI中時(shí),這些標(biāo)簽都是名字空間感知的(

          “namespace aware”),所以這些namespace prefix不必嵌入到表單或連接中。
          Default的namespace是一個(gè)空字符串“”,如果在指定的配置文件中,沒有找到action,缺省的namespace也會被查找

          。Local/global策略允許應(yīng)用程序在action “extends”元素層次結(jié)構(gòu)之外,有全局的action配置。缺省的namespace

          也可以不在package中申明。
          Namespace prefix可以注冊為java的申明式安全,以確保授權(quán)的用戶才能訪問namespace的資源。
          Root namespace(“/”)也被支持,root就是當(dāng)直接請求context path的時(shí)候的namespace。

          [個(gè)人理解:namespace的用法就像struts1.x中的path一樣,只不過它在package中什么路徑,而在action中申明

          action名子罷了]

          3、Include
          Include元素使得框架能應(yīng)用“divide and conquer”來配置文件。被include
          的每個(gè)配置文件必須和struts.xml有一樣的格式,一個(gè)大的項(xiàng)目可以采用這樣方式來組織程序模塊。
          Include元素也可以和package交替出現(xiàn),框架將按照順序加載配置文件。

          4、Interceptor configuration
          Interceptor允許應(yīng)用程序在Action方法執(zhí)行前后定義執(zhí)行代碼,
          Interceptor在應(yīng)用程序開發(fā)中十分重要,對于Interceptor有許多用例,如validation, property population,

          security, logging, 和profiling。
          Interceptor被定義為一個(gè)Java類,Interceptor也可以組裝成Interceptor-stack,他們將按照定義的順序執(zhí)行。
          在struts-default.xml中定義了一些缺省的Interceptor-stack,以便框架能很好地運(yùn)行。

          5、Action
          Action是框架的“工作單元”。Action可以指定一個(gè)Interceptor-stack、
          一序列的return type和一序列的異常處理,但只有name屬性是必須的。

           

          --------------------------------------------------------------------------------
          struts2.0簡單的例子今天在apache網(wǎng)站上無意中看到了struts項(xiàng)目2.0.8正式發(fā)布了,懷著欣喜的心情我下載了

          stuts2.0.8完整包。 Struts2.0.8是struts項(xiàng)目和WebWork2.2項(xiàng)目的合并版本,集成了兩大流行MVC框架的優(yōu)點(diǎn),對

          struts框架來說是一個(gè)大的提升,同時(shí)也更大程度地簡化了開發(fā)人員的開發(fā)過程。我簡單地研究了一下這個(gè)新版本,

          現(xiàn)在給大家介紹一個(gè)入門級的小例子,希望能對學(xué)習(xí)這個(gè)新版本的朋友有點(diǎn)幫助。
          這個(gè)例子完成了一次URL調(diào)用返回結(jié)果頁面的過程。
          首先,要從apache網(wǎng)站上下載struts2.0.8的完整包(可以從這里下載:

          http://www.signal42.com/mirrors/apache/struts/binaries/struts-2.0.8-all.zip),解壓后需要找到下列幾個(gè)文

          件:
          commons-logging-1.0.4.jar
          freemarker-2.3.8.jar
          ognl-2.6.11.jar
          struts2-core-2.0.8.jar
          xwork-2.0.3.jar
          然后,我們就開始做第一個(gè)例子,我們就使用經(jīng)典的“HelloWorld”的名字吧!
          1. 制作目錄結(jié)構(gòu)
          如下圖所示:
          stuts2是web應(yīng)用的根目錄。
          2. 拷貝引用文件
          將上面列舉的jar文件拷貝到步驟1中制作的目錄struts2\WEB-INF\lib中。
          3. 制作jsp文件HelloWorld.jsp

          <%@ taglib prefix="s" uri="/struts-tags" %>
          <html>
          <head>
          <title>Hello World!</title>
          </head>
          <body>
          <h2><s:property value="message" /></h2>
          </body>
          </html>
          將該文件拷貝到步驟1中制作的目錄struts2\example中。
          4.制作java文件HelloWorld.java

          package example;

          /** *//**
          * <code>Set welcome message.</code>
          */
          import com.opensymphony.xwork2.ActionSupport;
          public class HelloWorld extends ActionSupport ...{

          public static final String MESSAGE = "Struts is up and running ...";

          public String execute() throws Exception ...{
          setMessage(MESSAGE);
          return SUCCESS;
          }

          private String message;

          public void setMessage(String message)...{
          this.message = message;
          }

          public String getMessage() ...{
          return message;
          }
          }
          使用下面的命令編譯這個(gè)java文件:
          set CLASSPATH=yourdirectory\xwork-2.0-beta-1.jar
          javac HelloWorld.java
          將編譯后的HelloWorld.class文件拷貝到步驟1中制作的目錄struts2\WEB-INF\classes\example中。
          5.制作web應(yīng)用的描述文件web.xml

          <?xml version="1.0" encoding="UTF-8"?>
          <web-app xmlns="     xmlns:xsi="     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-

          app_2_4.xsd"
              version="2.4">

          <display-name>Struts Blank</display-name>

          <filter>
          <filter-name>struts2</filter-name>
          <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
          </filter>

          <filter-mapping>
          <filter-name>struts2</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>

          <welcome-file-list>
          <welcome-file>index.html</welcome-file>
          </welcome-file-list>
          </web-app>
          將該文件拷貝到步驟1中制作的目錄struts2\WEB-INF中。
          6.制作MANIFEST.MF文件(從其它地方隨便找一個(gè)即可)
          將該文件拷貝到步驟1中制作的目錄struts2\META-INF中。
          7.制作struts配置文件struts.xml和struts.properties
          struts.xml文件:

          <!DOCTYPE struts PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
          " <struts>
          <package name="abc" namespace="/example" extends="struts-default">
          <action name="HelloWorld" class="example.HelloWorld">
          <result>/example/HelloWorld.jsp</result>
          </action>
          <!-- Add your actions here -->
          </package>
          </struts>
          struts.properties文件:
          struts.devMode = true
          struts.enable.DynamicMethodInvocation = false
          將這兩個(gè)文件拷貝到步驟1中制作的目錄struts2\ WEB-INF\classes中。
          好了整個(gè)例子的文件我們都搞定了。
          最后,你可以將制作好的web應(yīng)用struts2拷貝到tomcat下運(yùn)行。
          訪問
          http://localhost:8080/struts2/example/HelloWorld.action如果能夠看到頁面上的“Struts is up and

          running ...”提示信息說明你的例子是正確的。

           


          --------------------------------------------------------------------------------
          Struts2.0 中文亂碼1.為了能正確顯示 jsp頁面直接寫的中文 在jsp頁面正確顯示添加下面字符設(shè)置。
             <%@ page contentType="text/html;charset=GBK"%>
          2.為了解決form提交到action中的中文參數(shù)亂碼問題,在src\struts.properties文件添加
          struts.i18n.encoding=GBK



              在struts2-core-2.0.8.jar 包中路徑為struts2-core-2.0.8\org\apache\struts2 有一個(gè)default.properties

          文件
              把struts.i18n.encoding=UTF-8改為struts.i18n.encoding=GBK 或者在struts.xml里面改
              這樣在action中取到的參數(shù)不用自己手工轉(zhuǎn)碼 了。

           

          --------------------------------------------------------------------------------
          Struts 2.0的標(biāo)志(Tag)介紹介紹常用標(biāo)志前,我想先從總體上,對Struts 1.x與Struts 2.0的標(biāo)志庫(Tag

          Library)作比較。  Struts 1.x Struts 2.0
          分類 將標(biāo)志庫按功能分成HTML、Tiles、Logic和Bean等幾部分 嚴(yán)格上來說,沒有分類,所有標(biāo)志都在URI為

          “/struts-tags”命名空間下,不過,我們可以從功能上將其分為兩大類:非UI標(biāo)志和UI標(biāo)志
          表達(dá)式語言(expression languages) 不支持嵌入語言(EL) OGNL、JSTL、Groovy和Velcity
          以上表格,純屬個(gè)人總結(jié),如有所不足或錯(cuò)誤,請不吝指正

          好了,我要開始介紹“常用”(這里所謂的“常用”,是指在已往工作中使用Struts里經(jīng)常用到的)的標(biāo)志了。


            要在JSP中使用Struts 2.0標(biāo)志,先要指明標(biāo)志的引入。通過在JSP的代碼的頂部加入以下代碼可以做到這點(diǎn)。
          <%@taglib prefix="s" uri="/struts-tags" %>

          非UI標(biāo)志
          if、elseif和else
          描述:
          執(zhí)行基本的條件流轉(zhuǎn)。

          參數(shù):

          名稱 必需 默認(rèn) 類型 描述 備注
          test 是  Boolean 決定標(biāo)志里內(nèi)容是否顯示的表達(dá)式 else標(biāo)志沒有這個(gè)參數(shù)
          id 否  Object/String 用來標(biāo)識元素的id。在UI和表單中為HTML的id屬性  

          例子:

          <%@ page contentType="text/html; charset=UTF-8" %>
          <%@ taglib prefix="s" uri="/struts-tags" %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
              <head>
                  <title>Condition Flow</title>
              </head>
              <body>
                  <h3>Condition Flow</h3>           
                  <!--
                      這里有點(diǎn)小技巧:
                      本來可以用#parameters.name[0]來獲得,請求中name的值。但是,在我實(shí)現(xiàn)include例子時(shí),
                      無論我用param標(biāo)志給name賦任何值,#parameters里面不會含有任何值,所以#parameters.name也為空

          值。
                     
                      其原因?yàn)椋?br />             當(dāng)使用include標(biāo)志時(shí),被包含的頁面(included)里#parameters拿到的是包含頁面里的請求參數(shù)。
                     
                      因此,這里必須手工調(diào)用request.getParameter("name")。
                  -->
                  <s:set name="name" value="<%= "'" + request.getParameter("name") + "'" %>" />
                  <s:if test="#name == 'Max'">
                      Max's file here
                  </s:if>
                  <s:elseif test="#name == 'Scott'">
                      Scott's file here
                  </s:elseif>
                  <s:else>
                      Other's file here
                  </s:else>       
              </body>
          </html>
          例1 condition.jsp

          iterator
          描述:
          用于遍歷集合(java.util.Collection)或枚舉值(java.util.Iterator)。

          參數(shù):

          名稱 必需 默認(rèn) 類型 描述
          status 否  String 如果設(shè)置此參數(shù),一個(gè)IteratorStatus的實(shí)例將會壓入每個(gè)遍歷的堆棧
          value 否  Object/String 要遍歷的可枚舉的(iteratable)數(shù)據(jù)源,或者將放入新列表(List)的對象
          id 否  Object/String 用來標(biāo)識元素的id。在UI和表單中為HTML的id屬性 

          例子:

          <%@ page contentType="text/html; charset=UTF-8" %>
          <%@ page import="java.util.List" %>
          <%@ page import="java.util.ArrayList" %>
          <%@ taglib prefix="s" uri="/struts-tags" %>

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <%
              List list = new ArrayList();
              list.add("Max");
              list.add("Scott");
              list.add("Jeffry");
              list.add("Joe");
              list.add("Kelvin");
              request.setAttribute("names", list);
          %>
          <html>
              <head>
                  <title>Iterator</title>
              </head>
              <body>
                  <h3>Names: </h3>
                  <!--
                      1、此處的空property元素用于獲得當(dāng)前iterator的值
                      2、status被設(shè)成stuts,在iterator的里面就可以通過#stuts取得IteratorStatus的對象。

          IteratorStatus類包含當(dāng)前序號信息,如是否第一個(gè)或最后一個(gè),是否為奇數(shù)序號。這些信息在我們做格式化的時(shí)候

          ,顯得非常有用。
                  -->
                  <ol>
                      <s:iterator value="#request.names" status="stuts">               
                          <s:if test="#stuts.odd == true">
                              <li>White <s:property /></li>
                          </s:if>
                          <s:else>
                              <li style="background-color:gray"><s:property /></li>
                          </s:else>
                      </s:iterator>
                  </ol>
              </body>
          </html>
          例2 iterator.jsp

          i18n
          描述:
          加載資源包到值堆棧。它可以允許text標(biāo)志訪問任何資源包的信息,而不只當(dāng)前action相關(guān)聯(lián)的資源包。

          參數(shù):

          名稱 必需 默認(rèn) 類型 描述
          value 是  Object/String 資源包的類路徑(如com.xxxx.resources.AppMsg)
          id 否  Object/String 用來標(biāo)識元素的id。在UI和表單中為HTML的id屬性 

          例子:

          HelloWorld=Hello Wrold!
          例3 classes\ ApplicationMessages.properties


          <%@ page contentType="text/html; charset=UTF-8" %>
          <%@ taglib prefix="s" uri="/struts-tags" %>

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
              <head>
                  <title>Internationization</title>
              </head>
              <body>
                  <h3>
                      <s:i18n name="ApplicationMessages">
                          <s:text name="HelloWorld" />
                      </s:i18n>
                  </h3>
              </body>
          </html>
          例3 i18n.jsp

          include
          描述:
          包含一個(gè)servlet的輸出(servlet或jsp的頁面)。

          參數(shù):

          名稱 必需 默認(rèn) 類型 描述
          value 是  String 要包含的jsp或servlet
          id 否  Object/String 用來標(biāo)識元素的id。在UI和表單中為HTML的id屬性 

          例子:

          <%@ page contentType="text/html; charset=UTF-8" %>
          <%@ taglib prefix="s" uri="/struts-tags" %>

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
              <head>
                  <title>Iterator</title>
              </head>
              <body>
                  <h3>Interator Page</h3>
                  <s:include value="/condition.jsp">
                      <s:param name="name">Max</s:param>
                  </s:include>
                  <h3>i18n</h3>
                  <s:include value="/i18n.jsp" />
              </body>
          </html>
          例4 include.jsp

          param
          描述:
          為其他標(biāo)簽提供參數(shù),比如include標(biāo)簽和bean標(biāo)簽. 參數(shù)的name屬性是可選的,如果提供,會調(diào)用Component的方法

          addParameter(String, Object), 如果不提供,則外層嵌套標(biāo)簽必須實(shí)現(xiàn)UnnamedParametric接口(如TextTag)。


           value的提供有兩種方式,通過value屬性或者標(biāo)簽中間的text,不同之處我們看一下例子:

          <param name="color">blue</param><!-- (A) -->

          <param name="color" value="blue"/><!-- (B) -->
          (A)參數(shù)值會以String的格式放入statck.
          (B)該值會以java.lang.Object的格式放入statck.
           

          參數(shù):

          名稱 必需 默認(rèn) 類型 描述
          name 否  String 參數(shù)名
          value 否  String value表達(dá)式
          id 否  Object/String 用來標(biāo)識元素的id。在UI和表單中為HTML的id屬性 

          例子:
          請參考例4。

          set
          描述:
          set標(biāo)簽賦予變量一個(gè)特定范圍內(nèi)的值。當(dāng)希望給一個(gè)變量賦一個(gè)復(fù)雜的表達(dá)式,每次訪問該變量而不是復(fù)雜的表達(dá)式

          時(shí)用到。其在兩種情況下非常有用: 復(fù)雜的表達(dá)式很耗時(shí) (性能提升) 或者很難理解 (代碼可讀性提高)。

          參數(shù):

          名稱 必需 默認(rèn) 類型 描述
          name 是  String 變量名字
          scope 否  String 變量作用域,可以為application, session, request, page, 或action.
          value 否  Object/String 將會賦給變量的值
          id 否  Object/String 用來標(biāo)識元素的id。在UI和表單中為HTML的id屬性 

          例子:
          請參考例1。

          text
          描述:
          支持國際化信息的標(biāo)簽。國際化信息必須放在一個(gè)和當(dāng)前action同名的resource bundle中,如果沒有找到相應(yīng)

          message,tag body將被當(dāng)作默認(rèn)message,如果沒有tag body,message的name會被作為默認(rèn)message。

          參數(shù):

          名稱 必需 默認(rèn) 類型 描述
          name 是  String 資源屬性的名字
          id 否  Object/String 用來標(biāo)識元素的id。在UI和表單中為HTML的id屬性 

          例子:
          請參考例3。

          url
          描述:
          該標(biāo)簽用于創(chuàng)建url,可以通過"param"標(biāo)簽提供request參數(shù)。


           當(dāng)includeParams的值時(shí)'all'或者'get', param標(biāo)簽中定義的參數(shù)將有優(yōu)先權(quán),也就是說其會覆蓋其他同名參數(shù)的值

          。 

          參數(shù): 略

          例子:

          <%@ page contentType="text/html; charset=UTF-8" %>
          <%@ taglib prefix="s" uri="/struts-tags" %>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
              <head>
                  <title>URL</title>
              </head>
              <body>
                  <h3>URL</h3>           
                  <a href='<s:url value="/i18n.jsp" />'>i18n</a><br />
                  <s:url id="url" value="/condition.jsp">
                      <s:param name="name">Max</s:param>
                  </s:url>       
                  <s:a href="%{url}">if\elseif\else</s:a>
              </body>
          </html>
          例5 url.jsp

          property
          描述:
          得到'value'的屬性,如果value沒提供,默認(rèn)為堆棧頂端的元素。

          參數(shù):

          名稱 必需 默認(rèn) 類型 描述
          default 否  String 如果屬性是null則顯示的default值
          escape 否 true Booelean 是否escape HTML
          value 否 棧頂 Object 要顯示的值
          id 否  Object/String 用來標(biāo)識元素的id。在UI和表單中為HTML的id屬性 

          例子:
          請參考例2。

           

          --------------------------------------------------------------------------------
          UI標(biāo)志UI標(biāo)志又可以分為表單UI和非表單UI兩部分。表單UI部分基本與Struts 1.x相同,都是對HTML表單元素的包裝

          。不過,Struts 2.0加了幾個(gè)我們經(jīng)常在項(xiàng)目中用到的控件如:datepicker、doubleselect、timepicker、

          optiontransferselect等。因?yàn)檫@些標(biāo)志很多都經(jīng)常用到,而且參數(shù)也很多,要在一篇文章詳細(xì)說明并非易事。


           需要深入了解這些標(biāo)志的朋友,可以到以下查看以下網(wǎng)址:
          http://wiki.javascud.org/display/ww2cndoc/Tags WebWork2文檔中文化計(jì)劃(中文)
          http://cwiki.apache.org/WW/tag-reference.html Tag Developers Guide(英文)
          本文有相當(dāng)?shù)膬?nèi)容也來自這兩處。 
           

          --------------------------------------------------------------------------------
          Struts 2.0的Action講解http://www.aygfsteel.com/max/archive/2006/10/25/77157.html

          當(dāng)請求HelloWorld.action發(fā)生時(shí),Struts運(yùn)行時(shí)(Runtime)根據(jù)struts.xml里的Action映射集(Mapping),實(shí)例化

          tutoiral.HelloWorld類,并調(diào)用其execute方法。當(dāng)然,我們可以通過以下兩種方法改變這種默認(rèn)調(diào)用。這個(gè)功能

          (Feature)有點(diǎn)類似Struts 1.x中的LookupDispathAction。

          在classes/sturts.xml中新建Action,并指明其調(diào)用的方法;
          訪問Action時(shí),在Action名后加上“!xxx”(xxx為方法名)。
          現(xiàn)方法一,在classes/sturts.xml中加入下面代碼:
          <action name="AliasHelloWorld" class="tutorial.HelloWorld" method="aliasAction">
             <result>/HelloWorld.jsp</result>
          </action>例2 classes/struts.xml中AlaisHelloWorld Action的配置
          通過上面的兩個(gè)例子,細(xì)心的朋友應(yīng)該可能會發(fā)現(xiàn)classes/tutorial/HelloWorld.java中Action方法(execute和

          aliasAction)返回都是SUCCESS。這個(gè)屬性變量我并沒有定義,所以大家應(yīng)該會猜到它在ActionSupport或其父類中定

          義。沒錯(cuò),SUCCESS在接口com.opensymphony.xwork2.Action中定義,另外同時(shí)定義的還有ERROR, INPUT, LOGIN,

          NONE。

          此外,我在配置Action時(shí)都沒有為result定義名字(name),所以它們默認(rèn)都為success。值得一提的是Struts 2.0中

          的result不僅僅是Struts 1.x中forward的別名,它可以實(shí)現(xiàn)除forward外的很激動人心的功能,如將Action輸出到

          FreeMaker模板、Velocity模板、JasperReports和使用XSL轉(zhuǎn)換等。這些都過result里的type(類型)屬性

          (Attribute)定義的。另外,您還可以自定義result類型。

          下面讓我們來做一個(gè)Velocity模板輸出的例子,首先在classes/struts.xml中新建一個(gè)Action映射(Mapping),將其

          result類型設(shè)為velocity,如以下代碼所示:
          <action name="VMHelloWorld" class="tutorial.HelloWorld">
              <result type="velocity">/HelloWorld.vm</result>
          </action>例3 classes/struts.xml中VMHelloWorld Action的配置

          新建HelloWorld.vm,內(nèi)容如下所示:
          <html>
            <head>
              <title>Velocity</title>
              <meta http-equiv="content-type" content="text/html; charset=UTF-8">
            </head>
            <body>
              <h2>Message rendered in Velocity: $message</h2>
            </body>
          </html>例3 HelloWorld.vm


          很多時(shí)候我的同事會問我:“如果我要取得Servlet API中的一些對象,如request、response或session等,應(yīng)該怎么

          做?這里的execute不像Struts 1.x的那樣在參數(shù)中引入。”開發(fā)Web應(yīng)用程序當(dāng)然免不了跟這些對象打交道。在

          Strutx 2.0你可以有兩種方式獲得這些對象:非IoC(控制反轉(zhuǎn)Inversion of Control)方式和IoC方式。

          非IoC方式

          要獲得上述對象,關(guān)鍵Struts 2.0中com.opensymphony.xwork2.ActionContext類。我們可以通過它的靜態(tài)方法

          getContext()獲取當(dāng)前Action的上下文對象。 另外,org.apache.struts2.ServletActionContext作為輔助類

          (Helper Class),可以幫助您快捷地獲得這幾個(gè)對象。

          HttpServletRequest request = ServletActionContext.getRequest();
          HttpServletResponse response = ServletActionContext.getResponse();
          HttpSession session = request.getSession();
          如果你只是想訪問session的屬性(Attribute),你也可以通過ActionContext.getContext().getSession()獲取或添

          加session范圍(Scoped)的對象。

          IoC方式

          要使用IoC方式,我們首先要告訴IoC容器(Container)想取得某個(gè)對象的意愿,通過實(shí)現(xiàn)相應(yīng)的接口做到這點(diǎn)。具體

          實(shí)現(xiàn),請參考例6 IocServlet.java。
          package tutorial;

          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import javax.servlet.http.HttpSession;

          import org.apache.struts2.ServletActionContext;

          import com.opensymphony.xwork2.ActionContext;
          import com.opensymphony.xwork2.ActionSupport;

          publicclass NonIoCServlet extends ActionSupport {
              private String message;
             
              public String getMessage() {
                  return message;       
              }
             
              @Override
              public String execute() {   
                  ActionContext.getContext().getSession().put("msg", "Hello World from Session!");
                 
                  HttpServletRequest request = ServletActionContext.getRequest();
                  HttpServletResponse response = ServletActionContext.getResponse();       
                  HttpSession session = request.getSession();
                 
                  StringBuffer sb =new StringBuffer("Message from request: ");
                  sb.append(request.getParameter("msg"));
                  sb.append("<br>Response Buffer Size: ");
                  sb.append(response.getBufferSize());
                  sb.append("<br>Session ID: ");
                  sb.append(session.getId());
                 
                  message = sb.toString();
                  return SUCCESS;
              }
          }例6 classes/tutorial/NonIoCServlet.java

          package tutorial;

          import java.util.Map;

          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import javax.servlet.http.HttpSession;

          import org.apache.struts2.interceptor.ServletRequestAware;
          import org.apache.struts2.interceptor.ServletResponseAware;
          import org.apache.struts2.interceptor.SessionAware;

          import com.opensymphony.xwork2.ActionContext;
          import com.opensymphony.xwork2.ActionSupport;

          publicclass IoCServlet extends ActionSupport implements SessionAware, ServletRequestAware,

          ServletResponseAware {
              private String message;
              private Map att;
              private HttpServletRequest request;
              private HttpServletResponse response;   
             
              public String getMessage() {
                  return message;       
              }
             
              publicvoid setSession(Map att) {
                  this.att = att;
              }
             
              publicvoid setServletRequest(HttpServletRequest request) {
                  this.request = request;
              }
             
              publicvoid setServletResponse(HttpServletResponse response) {
                  this.response = response;
              }
             
              @Override
              public String execute() {       
                  att.put("msg", "Hello World from Session!");
                 
                  HttpSession session = request.getSession();
                 
                  StringBuffer sb =new StringBuffer("Message from request: ");
                  sb.append(request.getParameter("msg"));
                  sb.append("<br>Response Buffer Size: ");
                  sb.append(response.getBufferSize());
                  sb.append("<br>Session ID: ");
                  sb.append(session.getId());
                 
                  message = sb.toString();
                  return SUCCESS;
              }
          }例6 classes/tutorial/IoCServlet.java

          <%@ page contentType="text/html; charset=UTF-8" %>
          <%@ taglib prefix="s" uri="/struts-tags"%>
          <html>
          <head>
              <title>Hello World!</title>
          </head>
          <body>
              <h2>
                  <s:property value="message" escape="false"/>
                  <br>Message from session: <s:property value="#session.msg"/>
              </h2>
          </body>
          </html>例6 Servlet.jsp

          <action name="NonIoCServlet" class="tutorial.NonIoCServlet">
              <result>/Servlet.jsp</result>
          </action>
          <action name="IoCServlet" class="tutorial.IoCServlet">
              <result>/Servlet.jsp</result>
          </action>

           


          --------------------------------------------------------------------------------
          在src文件夾中加入struts.properties文件,內(nèi)容如下:
          struts.custom.i18n.resources=globalMessages
          Struts 2.0有兩個(gè)配置文件,struts.xml和struts.properties都是放在WEB-INF/classes/下。
          struts.xml用于應(yīng)用程序相關(guān)的配置
          struts.properties用于Struts 2.0的運(yùn)行時(shí)(Runtime)的配置


          在src文件夾中加入globalMessages_en_US.properties文件,內(nèi)容如下:
          HelloWorld=Hello World!
          在src文件夾中加入globalMessages_zh_CN.properties文件,內(nèi)容如下:
          HelloWorld=你好,世界!

          在WebContent文件夾下加入HelloWorl.jsp文件,內(nèi)容如下:
          <%@ page  contentType="text/html; charset=UTF-8"%>
          <%@taglib prefix="s" uri="/struts-tags"%>
          <html>
          <head>
              <title>Hello World</title>
          </head>
          <body>
              <h2><s:text name="HelloWorld"/></h2>
              <h2><s:property value="%{getText('HelloWorld')}"/></h2>
          </body>
          </html>
          資源文件查找順序
          之所以說Struts 2.0的國際化更靈活是因?yàn)樗梢阅芨鶕?jù)不同需要配置和獲取資源(properties)文件。在Struts

          2.0中有下面幾種方法:

          使用全局的資源文件,方法如上例所示。這適用于遍布于整個(gè)應(yīng)用程序的國際化字符串,它們在不同的包(package)

          中被引用,如一些比較共用的出錯(cuò)提示;
          使用包范圍內(nèi)的資源文件。做法是在包的根目錄下新建名的package.properties和package_xx_XX.properties文件。

          這就適用于在包中不同類訪問的資源;
          使用Action范圍的資源文件。做法為Action的包下新建文件名(除文件擴(kuò)展名外)與Action類名同樣的資源文件。它

          只能在該Action中訪問。如此一來,我們就可以在不同的Action里使用相同的properties名表示不同的值。例如,在

          ActonOne中title為“動作一”,而同樣用title在ActionTwo表示“動作二”,節(jié)省一些命名工夫;
          使用<s:i18n>標(biāo)志訪問特定路徑的properties文件。使用方法請參考我早前的文章《常用的Struts 2.0的標(biāo)志(Tag)

          介紹》。在您使用這一方法時(shí),請注意<s:i18n>標(biāo)志的范圍。在<s:i18n name="xxxxx">到</s:i18n>之間,所有的國

          際化字符串都會在名為xxxxx資源文件查找,如果找不到,Struts 2.0就會輸出默認(rèn)值(國際化字符串的名字)。
          上面我列舉了四種配置和訪問資源的方法,它們的范圍分別是從大到小,而Struts 2.0在查找國際化字符串所遵循的

          是特定的順序,如圖3所示:


          圖3 資源文件查找順序圖
          假設(shè)我們在某個(gè)ChildAction中調(diào)用了getText("user.title"),Struts 2.0的將會執(zhí)行以下的操作:

          查找ChildAction_xx_XX.properties文件或ChildAction.properties;
          查找ChildAction實(shí)現(xiàn)的接口,查找與接口同名的資源文件MyInterface.properties;
          查找ChildAction的父類ParentAction的properties文件,文件名為ParentAction.properties;
          判斷當(dāng)前ChildAction是否實(shí)現(xiàn)接口ModelDriven。如果是,調(diào)用getModel()獲得對象,查找與其同名的資源文件;
          查找當(dāng)前包下的package.properties文件;
          查找當(dāng)前包的父包,直到最頂層包;
          在值棧(Value Stack)中,查找名為user的屬性,轉(zhuǎn)到user類型同名的資源文件,查找鍵為title的資源;
          查找在struts.properties配置的默認(rèn)的資源文件,參考例1;
          輸出user.title。
          參數(shù)化國際化字符串
          許多情況下,我們都需要在動行時(shí)(runtime)為國際化字符插入一些參數(shù),例如在輸入驗(yàn)證提示信息的時(shí)候。在

          Struts 2.0中,我們通過以下兩種方法做到這點(diǎn):

          在資源文件的國際化字符串中使用OGNL,格式為${表達(dá)式},例如:
          validation.require=${getText(fileName)} is required
          使用java.text.MessageFormat中的字符串格式,格式為{ 參數(shù)序號(從0開始), 格式類形(number | date | time

          | choice), 格式樣式},例如:
          validation.between=Date must between {0, date, short} and {1, date, short}
          在顯示這些國際化字符時(shí),同樣有兩種方法設(shè)置參數(shù)的值:

          使用標(biāo)志的value0、value1...valueN的屬性,如:
          <s:text name="validation.required" value0="User Name"/>
          使用param子元素,這些param將按先后順序,代入到國際化字符串的參數(shù)中,例如:
          <s:text name="validation.required">
             <s:param value="User Name"/>
          </s:text>
          讓用戶方便地選擇語言
          開發(fā)國際化的應(yīng)用程序時(shí),有一個(gè)功能是必不可少的——讓用戶快捷地選擇或切換語言。在Struts 2.0中,通過

          ActionContext.getContext().setLocale(Locale arg)可以設(shè)置用戶的默認(rèn)語言。不過,由于這是一個(gè)比較普遍的應(yīng)

          用場景(Scenario),所以Struts 2.0為您提供了一個(gè)名i18n的攔截器(Interceptor),并在默認(rèn)情況下將其注冊到

          攔截器鏈(Interceptor chain)中。它的原理為在執(zhí)行Action方法前,i18n攔截器查找請求中的一個(gè)名

          為"request_locale"的參數(shù)。如果其存在,攔截器就將其作為參數(shù)實(shí)例化Locale對象,并將其設(shè)為用戶默認(rèn)的區(qū)域

          (Locale),最后,將此Locale對象保存在session的名為“WW_TRANS_I18N_LOCALE”的屬性中。

          下面,我將提供一完整示例演示它的使用方法。

          package tutorial;

          import java.util.Hashtable;
          import java.util.Locale;
          import java.util.Map;

          publicclass Locales {
              public Map<String, Locale> getLocales() {
                  Map<String, Locale> locales =new Hashtable<String, Locale>(2);
                  locales.put("American English", Locale.US);
                  locales.put("Simplified Chinese", Locale.CHINA);
                  return locales;
              }
          }tutorial/Locales.java

          <%@taglib prefix="s" uri="/struts-tags"%>
          <script type="text/javascript">
          <!--
              function langSelecter_onChanged() {
                  document.langForm.submit();
              }
          //-->
          </script>
          <s:set name="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/>
          <s:bean id="locales" name="tutorial.Locales"/>
          <form action="<s:url includeParams="get" encode="true"/>" name="langForm"
              style="background-color: powderblue; padding-top: 4px; padding-bottom: 4px;">
              Language: <s:select label="Language"
                  list="#locales.locales" listKey="value"    listValue="key"
                  value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE"
                  name="request_locale" id="langSelecter"
                  onchange="langSelecter_onChanged()" theme="simple"/>
          </form>LangSelector.jsp
          上述代碼的原理為,LangSelector.jsp先實(shí)例化一個(gè)Locales對象,并把對象的Map類型的屬性locales賦予下拉列表(

          select) 。如此一來,下拉列表就獲得可用語言的列表。大家看到LangSelector有<s:form>標(biāo)志和一段Javascript腳

          本,它們的作用就是在用戶在下拉列表中選擇了后,提交包含“reqeust_locale”變量的表單到Action。在打開頁面

          時(shí),為了下拉列表的選中的當(dāng)前區(qū)域,我們需要到session取得當(dāng)前區(qū)域(鍵為“WW_TRANS_I18N_LOCALE”的屬性),

          而該屬性在沒有設(shè)置語言前是為空的,所以通過值棧中l(wèi)ocale屬性來取得當(dāng)前區(qū)域(用戶瀏覽器所設(shè)置的語言)。

          你可以把LangSelector.jsp作為一個(gè)控件使用,方法是在JSP頁面中把它包含進(jìn)來,代碼如下所示: <s:include

          value="/LangSelector.jsp"/>
          在例1中的HellloWorld.jsp中<body>后加入上述代碼,并在struts.xml中新建Action,代碼如下:
          <action name="HelloWorld">
              <result>/HelloWorld.jsp</result>
          </action>
          或者,如果你多個(gè)JSP需要實(shí)現(xiàn)上述功能,你可以使用下面的通用配置,而不是為每一個(gè)JSP頁面都新建一個(gè)Action。
          <action name="*">
              <result>/{1}.jsp</result>
          </action>
          分布運(yùn)行程序,在瀏覽器的地址欄中輸入http://localhost:8080/Struts2_i18n/HelloWorld.action,出現(xiàn)圖4所示頁

          面:

          圖3 HelloWorld.action

          在下拉列表中,選擇“American English”,出現(xiàn)圖5所示頁面:

          圖4 HelloWorld.action
          可能大家會問為什么一定要通過Action來訪問頁面呢?
          你可以試一下不用Action而直接用JSP的地址來訪問頁面,結(jié)果會是無論你在下拉列表中選擇什么,語言都不會改變。

          這表示不能正常運(yùn)行的。其原因?yàn)槿绻苯邮褂肑SP訪問頁面,Struts 2.0在web.xml的配置的過濾器(Filter)就不

          會工作,所以攔截器鏈也不會工作。

          posted on 2007-11-02 12:07 蘆葦 閱讀(2311) 評論(0)  編輯  收藏 所屬分類: Struts
          主站蜘蛛池模板: 菏泽市| 汉源县| 丘北县| 阳江市| 自贡市| 德惠市| 报价| 加查县| 奉新县| 定陶县| 治县。| 伊宁市| 乌兰浩特市| 博客| 彭泽县| 大厂| 金秀| 伊宁市| 甘肃省| 苏尼特右旗| 康乐县| 手游| 秦安县| 云梦县| 泰顺县| 明星| 洛南县| 浦城县| 富蕴县| 安乡县| 太仓市| 屏东市| 堆龙德庆县| 齐齐哈尔市| 三明市| 桑日县| 华阴市| 卢湾区| 屏东县| 车险| 平定县|