軟件藝術(shù)思考者  
          混沌,彷徨,立志,蓄勢...
          公告
          日歷
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          隨筆分類(86)

          隨筆檔案(85)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

           

          不少人看過或了解過Velocity,名稱字面翻譯為:速度、速率、迅速,用在Web開發(fā)里,用過的人可能不多,大都基本知道和在使用Struts,到底Velocity和Struts是如何聯(lián)系,怎么看待Velocity呢?讓我們來嘗試一下,了解Velocity的概念,通過在這里的介紹,強調(diào)在技術(shù)選擇上的問題,讓大家在選擇項目開發(fā)時,可以考慮Velocity,另外也讓大家了解它的思想,畢竟它提供了一個很好的思維方式,給大家換換筋骨,換一種思考的方式。

          本文基于你對Java開發(fā)有一定基礎(chǔ),知道MVC,Struts等開發(fā)模式。

          Velocity是一種Java模版引擎技術(shù),該項目由Apache提出,由另外一種引擎技術(shù)Webmacro引深而來。那什么是官方的Velocity定義呢?Apache對它的定義是:一種基于Java的模板引擎,但允許任何人使用簡單而強大的模板語言來引用定義在Java代碼中的對象。目前最新的版本是1.4,可以在http://jakarta.apache.org/velocity/index.html查找更多信息。

          ?其實說白了Velocity也就是MVC架構(gòu)的一種實現(xiàn),但它更多的是關(guān)注在Model和View之間,作為它們的橋梁。對于MVC的最流行架構(gòu)Struts來說,相信大家都不陌生,很多開發(fā)人員已經(jīng)大量在使用Struts架構(gòu),包括IBM的Websphere 5以上的管理平臺版本,Struts技術(shù)很好的實踐了MVC,它有效的減少Java代碼在View(Jsp)中的出現(xiàn),但在Model和View之間還是依靠Struts的Taglib技術(shù)來實現(xiàn),試想如果前臺開發(fā)的網(wǎng)頁設(shè)計師對Struts乃至Taglib不熟(相信也挺難熟的,包括后期的維護人員也一樣),將會對網(wǎng)頁設(shè)計師和前臺開發(fā)工程師的相互協(xié)作開發(fā)帶來很大的難度,現(xiàn)實開發(fā)中也還是存在這樣事實,網(wǎng)頁設(shè)計師和前臺開發(fā)之間的工作或多或少還是存在一定的耦合,怎樣最大限度的解決這個難題呢?還是讓我們來看看Velocity或者說這個概念吧。

          ?先做一個最簡單的Velocity開發(fā)例子,讓大家看看Velocity是怎樣工作的:

          1、?創(chuàng)建1個文件,文件名為:hellovelocity.vm,即velocity模版(其實和html一樣),內(nèi)容:



          Welcome $name to Javayou.com!
          today is $date.

          2、?創(chuàng)建1個java文件,HelloVelocity.java,內(nèi)容:
          package com.javayou.velocity;
          import java.io.StringWriter;
          import java.util.*;
          import org.apache.velocity.app.VelocityEngine;
          import org.apache.velocity.Template;
          import org.apache.velocity.VelocityContext;

          /**
          ?* @author Liang.xf 2004-12-14
          ?*/
          public class HelloVelocity {
          ?public static void main(String[] args) throws Exception {
          ??
          ??//初始化并取得Velocity引擎
          ??VelocityEngine ve = new VelocityEngine();
          ??ve.init();?
          ??//取得velocity的模版
          ??Template t = ve.getTemplate("hellovelocity.vm");
          ??//取得velocity的上下文context
          ??VelocityContext context = new VelocityContext();
          ??//把數(shù)據(jù)填入上下文
          ??context.put("name", "Liang");
          ??context.put("date", (new Date()).toString());
          ??
          ??//為后面的展示,提前輸入List數(shù)值
          ??List temp = new ArrayList();
          ??temp.add("1");
          ??temp.add("2");
          ??context.put("list", temp);

          ??//輸出流
          ??StringWriter writer = new StringWriter();
          ??//轉(zhuǎn)換輸出
          ??t.merge(context, writer);
          ??System.out.println(writer.toString());
          ?}
          }

          3、?在http://jakarta.apache.org/site/binindex.cgi上下載Velocity 1.4 zip,解壓后獲取velocity-1.4.jar,用它來編譯上面的類HelloVelocity.java。

          4、?把1上的hellovelocity.vm copy到運行的當(dāng)前目錄下,運行HelloVelocity還需要其他類包,可以從下載后的velocity1.4.zip來,\velocity-1.4\build\lib,把commons-collections.jar、logkit-1.0.1.jar引入后運行java -cp .\bin; -Djava.ext.dirs=.\lib2 com.javayou.velocity.HelloVelocity,假設(shè)class編譯到.\bin目錄,而我們所需的類包放到.\lib2目錄內(nèi),運行結(jié)構(gòu)如下:



          Welcome Liang to Javayou.com!
          today is Tue Dec 14 19:26:37 CST 2004.

          以上是最簡單的運行結(jié)果,怎么樣,知道個大概吧,模版hellovelocity.vm里的2個定義變量$name和$date分別被context.put("name", "Liang")和context.put("date", (new Date()).toString())所設(shè)的值替代了。

          由此看來業(yè)務(wù)流程處理包括業(yè)務(wù)結(jié)果基本在model這層全部解決,而view這一層基本只用使用簡單的VTL(Velocity Template Language)來展示。這樣,Jsp豈不是不用了么?是的,這樣的使用模式有點象早前的CGI方式:)由Velocity自動輸出代碼,并且Velocity在這方面的能力也很強,Turbine里就采用了Velocity來產(chǎn)生很多代碼。

          在Velocity中,變量的定義都是使用“$”開頭的,$作為Velocity的標(biāo)識符。字母、數(shù)字、中劃和下劃線都可以作為Velocity的定義變量。

          此外我們還需要注意的是Velocity特色的變量定義,如:$student.No、$student.Address,它有2層含義:第1種是如果student是hashtable,則將從hashtable中提取key為No和Address的值,另外第2種就是它有可能是調(diào)用方法,即上面2個變量將被轉(zhuǎn)換為student.getNo()和student.getAddress()。Velocity對在servlet中的java code返回的值有對象,還可以調(diào)用對象的方法,如$ student.getAddress()等等,在此就不一一舉例和深入了。

          上面的例子只是簡單的舉例,現(xiàn)在當(dāng)然不少人已經(jīng)不滿足這樣的例子了,實際的應(yīng)用中我們還常常需要作些選擇性展示和列舉一些迭代數(shù)據(jù),如List列表,當(dāng)然Velocity(具體來說應(yīng)該是VTL模版語言)也支持這項功能,此外還支持其他一些常用的展示,如模版內(nèi)部的變量(如Jsp內(nèi)的變量),還有強大一些的如創(chuàng)建宏以實現(xiàn)自動化,讓我們繼續(xù)接著往下看吧。

          我們還是使用上面的例子,把模版hellovelocity.vm中的內(nèi)容改為:
          #set( $iAmVariable = "good!" )
          Welcome $name to Javayou.com!
          today is $date.
          $iAmVariable

          重新執(zhí)行上面的運行命令,結(jié)果:
          Welcome Liang to Javayou.com!
          today is Tue Dec 14 22:44:39 CST 2004.
          good!

          可以看得模版中的變量定義為# set開頭的語句,不是很難理解,執(zhí)行后模版中的變量$iAmVariable都轉(zhuǎn)換成定義的值:good!

          再來看看簡單的選擇,把模版hellovelocity.vm中的內(nèi)容改為:
          #set ($admin = "admin")
          #set ($user = "user")
          #if ($admin = = $user)
          ? Welcome admin!
          #else
          ? Welcome user!
          #end

          執(zhí)行運行命令,結(jié)果:
          ? Welcome user!

          可以看到判斷語句只是簡單的#if ()、#else、#end,不是很復(fù)雜。
          接著繼續(xù)來看看迭代數(shù)據(jù)吧,把模版hellovelocity.vm中的內(nèi)容改為:
          #foreach( $product in $list )
          ?

        1. $product
          #end

          ?

          執(zhí)行運行命令,結(jié)果:

        2. 1
        3. 2
          把在例子中預(yù)先保存在VelocityContext的List中的值列舉了出來,是不是很方便啊?僅僅只是用了#foreach($variable in xx) 而已,如果上面的List換成Hashtable,則可以用下面的語法:
          #foreach($key in $hashVariable.keySet() )
          ?
        4. $key ‘s value: $ hashVariable.get($key)
          #end
          一點不覺得這些腳本很復(fù)雜。
          還有不少人還會問,如果是javabean怎么辦?好的,我們增加一個bean:
          package com.javayou.velocity;

          ?

          /**
          ?* @author Liang.xf? 2004-12-14
          ?*/
          public class Student {
          ?//注意class的屬性是public的
          ?public String no = "";
          ?public String address = "";
          ?public Student(String _no, String _address) {
          ??no = _no;
          ??address = _address;
          ?}
          ?
          ?public String getAddress() {
          ??return address;
          ?}
          ?
          ?public void setAddress(String address) {
          ??this.address = address;
          ?}
          ?
          ?public String getNo() {
          ??return no;
          ?}
          ?
          ?public void setNo(String no) {
          ??this.no = no;
          ?}
          }
          這個Student是實足的javabean,或者說是data bean,常見的用來裝載數(shù)據(jù)的類,然后我們修改HelloVelocity.java,把:
          temp.add("1");
          ?temp.add("2");
          替換成:
          ?temp.add(new Student("123", "Guangzhou"));
          ?temp.add(new Student("456", "Zhuhai"));

          再把hellovelocity.vm的內(nèi)容改為:
          #foreach ($s in $students)
          ? <$velocityCount> Address: $s.address
          #end
          重新編譯和執(zhí)行運行命令,結(jié)果如下:
          ? <1> Address: Guangzhou
          ? <2> Address: Zhuhai
          這樣把list中Student的數(shù)據(jù)打印了出來,大功告成!這里用了Velocity的內(nèi)建變量$velocityCount,指的是默認(rèn)的列舉序號,從1開始,也可以改成0開始,但需要在Velocity.properties中更改,Velocity.properties位于velocity-1.4.jar包內(nèi)的目錄org\apache\velocity\runtime\defaults 下。
          再復(fù)雜一些的迭代怎么處理呢?我們看看下面的模版例子就清楚了:
          #foreach ($element in $list)
          ??? -- inner foreach --
          ??? #foreach ($element in $list)
          ??????? This is $element.
          ??????? $velocityCount
          ??? #end
          ??? -- inner foreach --

          ??? -- outer foreach --
          ??? This is $element.
          ??? $velocityCount
          ??? -- outer foreach --
          #end

          看出來了吧,Velocity是支持標(biāo)簽嵌套的,這個可是很強大的功能,這里就不深入演示了,如果有興趣,自己試試吧。

          其實,稍為深入思考剛剛我們舉的例子,就已經(jīng)可以看出來,Velocity的用處在哪里?即Servlet + Velocity的模式,另外,還記得我們早期Jsp開發(fā)的模式Jsp+JavaBean嗎?在這里,我們更改為Servlet+JavaBean+Velocity,想想,是不是已經(jīng)替代了Jsp+JavaBean,并更徹底的把Java代碼去除在Jsp(vm)外,如果光使用Struts(Servlet+Jsp),那么帶來的代價是Java代碼總或多或少出現(xiàn)在Jsp上,即使可以做到不出現(xiàn)Java代碼,但做過復(fù)雜架構(gòu)系統(tǒng)的開發(fā)者都知道,代價也是很昂貴的,并且在可維護性、和網(wǎng)頁設(shè)計師的集成開發(fā)上存在一定的困難,所以我們在這里能感覺到,Servlet+JavaBean+Velocity的模式較好的實現(xiàn)了OOD的概念。而在效率上,大家也不用擔(dān)心,此種結(jié)合方式比Servlet+Jsp的方式要高效一些。

          愿意了解Velocity的人應(yīng)該不少,但真正實用到項目的,也許不多(還是有些項目在使用,如Jute),畢竟和Jsp比起來,Jsp更標(biāo)準(zhǔn)、更廣泛使用和有不少開發(fā)工具已經(jīng)支持Jsp開發(fā)。但Velocity的功能不會僅僅局限在和Jsp競爭的局面,由上可看出它在自動代碼輸出方面功能很強,前面提到Turbine就是采用Velocity來生成很多代碼,你也可以稍加改動就可以做成代碼生成器,或其他模版生成上,都是很不錯的想法。

          好了,我們再來看看要深入Velocity來做項目,還需要注意的一些常見問題吧,首先是國際化的問題,

          Velocity本身支持模版的國際化編碼轉(zhuǎn)換,看看Velocity提供的方法:
          Public Template getTemplate (Stirng template, String encoding),
          由此推測這樣做其實不能徹底的做到國際化。

          ?//------------------------------------------(2)--------------------------------------------
        5. /*
          ?* Copyright 2000-2001,2006 The Apache Software Foundation.
          ?*
          ?* Licensed under the Apache License, Version 2.0 (the "License");
          ?* you may not use this file except in compliance with the License.
          ?* You may obtain a copy of the License at
          ?*
          ?*????? http://www.apache.org/licenses/LICENSE-2.0
          ?*
          ?* Unless required by applicable law or agreed to in writing, software
          ?* distributed under the License is distributed on an "AS IS" BASIS,
          ?* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
          ?* See the License for the specific language governing permissions and
          ?* limitations under the License.
          ?*/

          Servlet直接繼承VelocityServlet。需要引入velocity-dep-1.4.jar,velocity-1.4.jar兩個包。

          package com.javayou;
          import java.io.IOException;
          import java.io.FileNotFoundException;

          import java.util.ArrayList;
          import java.util.List;
          import java.util.Properties;
          import java.util.Vector;

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

          import org.apache.velocity.Template;
          import org.apache.velocity.context.Context;
          import org.apache.velocity.servlet.VelocityServlet;
          import org.apache.velocity.app.Velocity;
          import org.apache.velocity.exception.ResourceNotFoundException;
          import org.apache.velocity.exception.ParseErrorException;

          /**
          ?* Sample of how to use the VelocityServlet.
          ?* This example shows how to add objects to the context and
          ?* pass them to the template.
          ?*
          ?* @author willians He
          ?* @author <a href="mailto:hzxmsn@163.com">willians He.</a>
          ?* @version $Id: SampleServlet.java,v 1.5.8.1 2006/07/15 10:01:29 geirm Exp $
          ?*/
          public class SampleServlet extends VelocityServlet
          {
          ???
          ??? /**
          ???? *?? Called by the VelocityServlet
          ???? *?? init().? We want to set a set of properties
          ???? *?? so that templates will be found in the webapp
          ???? *?? root.? This makes this easier to work with as
          ???? *?? an example, so a new user doesn't have to worry
          ???? *?? about config issues when first figuring things
          ???? *?? out
          ???? */
          ??? protected Properties loadConfiguration(ServletConfig config )
          ??????? throws IOException, FileNotFoundException
          ??? {
          ??????? Properties p = new Properties();

          ??????? /*
          ???????? *? first, we set the template path for the
          ???????? *? FileResourceLoader to the root of the
          ???????? *? webapp.? This probably won't work under
          ???????? *? in a WAR under WebLogic, but should
          ???????? *? under tomcat :)
          ???????? */

          ??????? String path = config.getServletContext().getRealPath("/");

          ??????? if (path == null)
          ??????? {
          ??????????? System.out.println(" SampleServlet.loadConfiguration() : unable to "
          ?????????????????????????????? + "get the current webapp root.? Using '/'. Please fix.");

          ??????????? path = "/";
          ??????? }

          ??????? p.setProperty( Velocity.FILE_RESOURCE_LOADER_PATH,? path );

          ??????? /**
          ???????? *? and the same for the log file
          ???????? */

          ??????? p.setProperty( "runtime.log", path + "velocity.log" );

          ??????? return p;
          ??? }


          ??? /**
          ???? *? <p>
          ???? *? main routine to handle a request.? Called by
          ???? *? VelocityServlet, your responsibility as programmer
          ???? *? is to simply return a valid Template
          ???? *? </p>
          ???? *
          ???? *? @param ctx a Velocity Context object to be filled with
          ???? *???????????? data.? Will be used for rendering this
          ???? *???????????? template
          ???? *? @return Template to be used for request
          ???? */??
          ??? public Template handleRequest( HttpServletRequest request,
          ?HttpServletResponse response, Context ctx )
          ??? {???????
          ??????? /*
          ???????? *? set up some data to put into the context
          ???????? */

          ??????
          ??????? String p1 = "Bob-->congratulation to? Bob";
          ??????? String p2 = "Harold-->congratulation to? Harold";
          ??????? String p3 = "Bob--->this is Wrong enter Bob";
          ??????? String p4 = "Harold-->this is Wrong enter? Harold";
          ??????? String jpgurl2="/test/picture/lxy01.jpg";
          ??????? String jpgurl1="/test/picture/ch020.jpg";
          ???????
          //????? 為后面的展示,提前輸入List數(shù)值
          ??????? List temp = new ArrayList();
          ??????? temp.add(new Students("123", "Guangzhou"));
          ??????? temp.add(new Students("321", "Guangzhou"));
          ??????? temp.add(new Students("456", "Shanghai"));
          ??????? temp.add(new Students("654", "Shanghai"));
          ??????? ctx.put("list", temp);

          ???????
          ??????? Vector personList = new Vector();
          ??????? Vector personList2 = new Vector();
          ???????
          ??????? String name=null;
          ??????? String pass=null;
          ??????? if(!request.getParameterMap().isEmpty())
          ??????? {
          ??????????? name = request.getParameter("Account");
          ??????????? pass = request.getParameter("Password");
          ???????????
          ??????? }else {
          ??????????? ?name="myname";
          ??????????? ?pass="123456";
          ??????? }
          ???????
          ??????? if(name.equals("myname")&&pass.equals("123456")) {??????
          ??????????? ?personList.addElement( p1 );
          ??????????? ?personList.addElement( p2 );
          ??????????? ?personList2.addElement( jpgurl1 );
          ??????? }
          ??????? else{
          ??????????? ?personList.addElement( p3 );????
          ??????????? ?personList.addElement( p4 );
          ??????????? ?personList2.addElement( jpgurl2 );
          ??????? }

          ??????? /*
          ???????? *? Add the list to the context.
          ???????? *? This is how it's passed to the template.
          ???????? */

          ??????? ctx.put("theList", personList );
          ??????? ctx.put("theImageList", personList2 );
          ???????
          ??????? /*
          ???????? *? get the template.? There are three possible
          ???????? *? exceptions.? Good to know what happened.
          ???????? */

          ??????? Template outty = null;
          ???????
          ??????? try
          ??????? {
          ??????????? //outty =? getTemplate("sample.html");
          ??????????? outty=getTemplate("templat/picMoudle/pic1.html");
          ???????????
          ???????????
          ??????? }
          ??????? catch( ParseErrorException pee )
          ??????? {
          ??????????? System.out.println("SampleServlet : parse error for template " + pee);
          ??????? }
          ??????? catch( ResourceNotFoundException rnfe )
          ??????? {
          ??????????? System.out.println("SampleServlet : template not found " + rnfe);
          ??????? }
          ??????? catch( Exception e )
          ??????? {
          ??????????? System.out.println("Error " + e);
          ??????? }
          ??????? return outty;
          ??? }
          ??
          }
          ?

          Students.java

          /*
          ?* 創(chuàng)建日期 2006-7-18
          ?*
          ?* TODO 要更改此生成的文件的模板,請轉(zhuǎn)至
          ?* 窗口 - 首選項 - Java - 代碼樣式 - 代碼模板
          ?*/
          package com.javayou;

          /**
          ?* @author?Willian He
          ?*
          ?*/
          public class Students {
          ??? public String no = "";
          ??? public String address = "";
          ??? public Students(String _no, String _address) {
          ????? no = _no;
          ????? address = _address;
          ??? }
          ??? public String getAddress() {
          ??????? return address;
          ?????? }
          ??? public void setAddress(String address) {
          ??????? this.address = address;
          ?????? }
          ??? public String getNo() {
          ??????? return no;
          ?????? }
          ??????
          ?????? public void setNo(String no) {
          ??????? this.no = no;
          ?????? }

          }

          模板

          pic1.html

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
          <head>
          ?<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
          ???
          ?<title>Sample Picture page</title></head>
          <body bgcolor="#ffffff">
          <center>

          <h2>Hello ,How are you!</h2>
          <i>Here's the list of picture</i>

          #set ($foo="The Velocity")
          <table width="750" height="200" border="1" cellpadding="1" cellspacing="1">
          ??? <tr>
          ?? <td bgcolor="#eeeeee" align="center">
          ???Show the picture??<br>?
          ??##foreach ($s1 in $list)
          ???#foreach ($s in $list)
          ????#if($s.address=="Shanghai")
          ?????this is<$velocityCount> Address: $s.address $s.no<br>
          ????#else?
          ?????that is<$velocityCount> Address: $s.no,$s.address <br>?
          ????#end
          ???#end
          ??##end???
          ??????? </td>
          ??? </tr>
          ??? #foreach ($name in $theList)
          ??? <tr align="center">
          ??????? <td bgcolor="#eeeeee">$name</td>
          ??? </tr>
          ??? #end
          ??? #foreach ($name in $theImageList)
          ??? <tr>
          ??????? <td align="center"><img src="$name"? title="give me" /></td>
          ?</tr>
          ?<tr>
          ??<td align="center"><font color="#ff0255">$name</font></td>
          ??? </tr>
          ??? #end
          ? <tr>
          ?????? <td bgcolor="#green" align="center">$foo</td>
          ??? </tr>
          </table>
          #macro(tablerows $color $somelist)
          #foreach($something in $somelist)
          ?<tr>
          ?<td bgcolor=$color>$something</td>
          ?</tr>

          #end
          #end

          #set($greatlakes=["Superior","Michigan","Huron","Erie","Ontario"])
          #set($color=("bllack"))
          <table>
          #tablerows($color $greatlakes)
          </table>
          <a href="http://localhost:8080/test/MyJsp.jsp">回上一頁</a>

          </center>
          </html>


        6. posted on 2007-01-14 16:55 智者無疆 閱讀(1545) 評論(2)  編輯  收藏 所屬分類: about java
          評論:
          • # re:tomcat下最終的中文亂碼解決之道  selt Posted @ 2007-01-18 18:15
            打開tomcat的server.xml文件
            <Connector port="80"
            maxThreads="150"
            minSpareThreads="25"
            maxSpareThreads="75"
            enableLookups="false"
            redirectPort="8443"
            acceptCount="100"
            debug="0"
            connectionTimeout="20000" disableUploadTimeout="true"
            URIEncoding="GBK"/>
            找了好多地方,才在j道上找到的   回復(fù)  更多評論   

          • # re: Velocity學(xué)習(xí)與實踐(轉(zhuǎn))   selt Posted @ 2007-01-18 18:19
            WebWork+Velocity中文問題解決:

            1、webwork.properties文件中,添加:
            webwork.i18n.encoding = GB2312
            它主要是用來設(shè)置WebWork UI標(biāo)簽庫的編碼,如果不設(shè)置它將通過
            System.getProperty("file.encoding")來獲取默認(rèn)字符編碼。

            2、velocity.properties文件中,添加:
            input.encoding=GB2312
            output.encoding=GB2312
            default.contentType=text/html; charset=GB2312
            它是用來設(shè)置.vm頁面的編碼方式

            3、寫一個Filter,將編碼設(shè)置為GB2312。詳細(xì)請看附件中的SetCharacterEncodingFilter文件和Web.xml的配置。
            它解決Action數(shù)據(jù)傳遞時的編碼。

            建議:中文編碼推薦統(tǒng)一使用:GBK,它的字符集比GB2312更全。
            經(jīng)過我的試驗,這個過濾器加不加是無所謂的。
            在執(zhí)行第一,二條之后,再把tomcat的默認(rèn)編碼改為gb2312即可  回復(fù)  更多評論   

           
          Copyright © 智者無疆 Powered by: 博客園 模板提供:滬江博客


             觀音菩薩贊

          主站蜘蛛池模板: 高唐县| 平利县| 新乡市| 米林县| 双牌县| 建阳市| 广西| 上饶市| 葫芦岛市| 长沙市| 云浮市| 积石山| 普洱| 乌拉特中旗| 晋宁县| 二连浩特市| 定南县| 五峰| 乌拉特中旗| 德江县| 稻城县| 长寿区| 新密市| 商都县| 平利县| 苍南县| 鄂托克旗| 澜沧| 江永县| 克拉玛依市| 绥阳县| 白山市| 车致| 江都市| 正安县| 皮山县| 上栗县| 蓬安县| 西吉县| 古浪县| 乐清市|