Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學(xué);靜其心,可悟天下之理;恒其心,可成天下之業(yè)。

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評(píng)論 :: 0 Trackbacks
          本文是在理解官方指南的基礎(chǔ)上,用實(shí)例實(shí)現(xiàn)Axis2提供的4種調(diào)用機(jī)制,并給出測(cè)試結(jié)果。
          author: ZJ 07-3-13
          Blog:
          http://zhangjunhd.blog.51cto.com/
           
          1.使用Axis2的底層API開發(fā)Web Service Server端
          1.1創(chuàng)建一個(gè)WebService(取名為MyService)
              在MyService中有兩個(gè)operations,如下所示。
          public void ping(OMElement element){}//IN-ONLY模式。僅僅接收OMElement,并對(duì)其處理。
          public OMElement echo(OMElement element){}//IN_OUT模式。接收OMElemen,并返回OMElement。
           
          1.2如何寫Web Service
          1)創(chuàng)建實(shí)現(xiàn)服務(wù)的類。
          2)創(chuàng)建services.xml來解析這個(gè)Web Service。
          3)將其打包成一個(gè)*.aar文檔(Axis Archive)。
          4)部署Web Service。
           
          1.2.1 創(chuàng)建實(shí)現(xiàn)服務(wù)的類
              此類中提供的方法必須與Web Service(在services.xml中聲明)中的operations對(duì)應(yīng)。除非你提供了數(shù)據(jù)綁定,否則所有的方法只能接收一個(gè)參數(shù),其類型為OMElement。
          public class MyService{
            public void ping(OMElement element){...}
            public OMElement echo(OMElement element){...}
          }
          MyService.java
          package userguide.example1;
          import org.apache.axiom.om.OMElement;
          import org.apache.axis2.AxisFault;
          import javax.xml.stream.XMLStreamException;
          public class MyService {
              public OMElement echo(OMElement element) throws XMLStreamException {
                  //Praparing the OMElement so that it can be attached to another OM Tree.
                  //First the OMElement should be completely build in case it is not fully built and still
                  //some of the xml is in the stream.
                  element.build();
                  //Secondly the OMElement should be detached from the current OMTree so that it can
                  // be attached some other OM Tree. Once detached the OmTree will remove its
                 // connections to this OMElement.
                  element.detach();
                  return element;
              }
              public void ping(OMElement element) throws XMLStreamException {
                  //Do some processing
              }
              public void pingF(OMElement element) throws AxisFault{
                  throw new AxisFault("Fault being thrown");
              }
          }
           
          1.2.2 創(chuàng)建services.xml
              Axis2使用services.xml來充當(dāng)一個(gè)Web Servicea的配置文件。每一個(gè)使用Axis2部署的Web Service都必須擁有一個(gè)services.xml。
          <services>
            <description>
              This is a sample Web Service with two operations,echo and ping.
            </description>
            <parameter name=”ServiceClass” locked=”false”>
            userguide.example1.MyService
            </parameter>
            <operation name=”echo”>
              <messageReceiver class=”org.apache.axis2.receivers.RawXMLINOutMessageReceiver”/>
              <actionMapping>urn:echo</actionMapping>
            </operation>
            <operation name=”ping”>
              <messageReceiver class=”org.apache.receivers.RawXMLINOnlyMessageReceiver”/>
              <actionMapping>urn:ping</actionMapping>
            </operation>
          </service>
          注:The actionMapping is required only if you want to enable WS-Addressing.
              可以創(chuàng)建一個(gè)services.xml,其中包含一組服務(wù)。這樣在運(yùn)行期,你可以在這些服務(wù)間共享信息。
          <serviceGroup>
            <service name=”Service1”>
              <!--details for Services1-->
            </service>
          <service name=”Service2”>
              <!--details for Services2-->
            </service>
            <module ref=”ModuleName”/>
            <parameter name=”serviceGroupParam1” locked=”false”>value1</parameter>
          </serviceGroup>
          注:name of the service is a compulsory attribute.
           
          1.2.3打包與部署
              這里不再詳述,參見《
          基于Tomcat5.0和Axis2開發(fā)Web Service應(yīng)用實(shí)例 》。
           
          2.使用Axis2底層APIs實(shí)現(xiàn)Web Service客戶端
          2.1ClientUtil
              創(chuàng)建一個(gè)客戶端通用的SOAP包裝Util文件。封裝"getEchoOMElement"和"getPingOMElement"分別對(duì)應(yīng)"echo"和"ping"這兩個(gè)operation。
          ClientUtil.java
          package userguide.clients;
          import org.apache.axiom.om.OMAbstractFactory;
          import org.apache.axiom.om.OMElement;
          import org.apache.axiom.om.OMFactory;
          import org.apache.axiom.om.OMNamespace;
          public class ClientUtil {
              public static OMElement getEchoOMElement() {
                  OMFactory fac = OMAbstractFactory.getOMFactory();
                  OMNamespace omNs = fac.createOMNamespace(
                          "
          http://example1.org/example1", "example1");
                  OMElement method = fac.createOMElement("echo", omNs);
                  OMElement value = fac.createOMElement("Text", omNs);
                  value.addChild(fac.createOMText(value, "Axis2 Echo String "));
                  method.addChild(value);
                  return method;
              }
              public static OMElement getPingOMElement() {
                  OMFactory fac = OMAbstractFactory.getOMFactory();
                  OMNamespace omNs = fac.createOMNamespace(
                          "
          http://example1.org/example1", "example1");
                  OMElement method = fac.createOMElement("ping", omNs);
                  OMElement value = fac.createOMElement("Text", omNs);
                  value.addChild(fac.createOMText(value, "Axis2 Ping String "));
                  method.addChild(value);
                  return method;
              }
          }
           
          2.2EchoBlockingClient
              Axis2向用戶提供了從blocking single channel調(diào)用到non-blocking dual channel調(diào)用的多種調(diào)用Web Service的模式。下面用最簡(jiǎn)單的blocking調(diào)用機(jī)制來實(shí)現(xiàn)”MyService”中的"echo" operation。
          EchoBlockingClient.java
          package userguide.clients;
          import org.apache.axiom.om.OMElement;
          import org.apache.axis2.AxisFault;
          import org.apache.axis2.addressing.EndpointReference;
          import org.apache.axis2.client.Options;
          import org.apache.axis2.client.ServiceClient;
          /**
           * Sample for synchronous single channel blocking service invocation.
           * Message Exchage Pattern IN-OUT
           */
          public class EchoBlockingClient {
          private static EndpointReference targetEPR =
           new EndpointReference("
          http://localhost:8080/axis2/services/MyService");
              public static void main(String[] args) {
          try {
                      OMElement payload = ClientUtil.getEchoOMElement();
                  
              Options options = new Options();
                      options.setTo(targetEPR); // this sets the location of MyService service
                      ServiceClient serviceClient = new ServiceClient();
                      serviceClient.setOptions(options);
                      OMElement result = sender.sendReceive(payload);
                      System.out.println(result);
          } catch (AxisFault axisFault) {
                   axisFault.printStackTrace();
          }
          }
              綠色部分顯示了為了調(diào)用一個(gè)Web Service而需要對(duì)operation作的設(shè)置。剩下的部分是用來創(chuàng)建OMElement,用來發(fā)送和顯示相應(yīng)的OMElement。
           
          結(jié)果:
          <example1:echo xmlns:example1="http://example1.org/example1"
          xmlns:tns="
          http://ws.apache.org/axis2">
          <example1:Text>
          Axis2 Echo String
          </example1:Text>
          </example1:echo>
           
          2.3 PingClient
              在”MyService”中,我們有一種IN-ONLY模式的名為"ping"的operation。應(yīng)用它的客戶端代碼如下:
          PingClient.java
          package userguide.clients;
          import org.apache.axiom.om.OMElement;
          import org.apache.axis2.AxisFault;
          import org.apache.axis2.addressing.EndpointReference;
          import org.apache.axis2.client.Options;
          import org.apache.axis2.client.ServiceClient;
          /**
           * Sample for fire-and-forget service invocation
           * Message Exchage Pattern IN-Only
           */
          public class PingClient {
          private static EndpointReference targetEPR =
           new EndpointReference("
          http://localhost:8080/axis2/services/MyService");
              public static void main(String[] args) {
          try {
                 OMElement payload = ClientUtil.getPingOMElement();
                 Options options = new Options();
                 options.setTo(targetEPR);
                 ServiceClient serviceClient = new ServiceClient();
                 serviceClient.setOptions(options);
                
          serviceClient.fireAndForget(payload);
                  /**
                   * We have to block this thread untill we send the request , the problem
                   * is if we go out of the main thread , then request wont send ,so
                   * you have to wait some time :)
                   */
                 Thread.sleep(500);
               }
          catch (AxisFault axisFault) {
                      axisFault.printStackTrace();
               }
          }
              由于我們?cè)谠L問一個(gè)IN-ONLY模式的operation,所以我們可以直接使用ServiceClient中的"fireAndForget()"方法來調(diào)用這個(gè)operation。而且那樣做的話,不會(huì)阻塞發(fā)起端,因此,它會(huì)立刻將控制權(quán)返回給客戶端。
           
          2.4 EchoNonBlockingClient
              在客戶端EchoBlockingClient,一旦調(diào)用"serviceClient.sendReceive(payload);",客戶端將會(huì)被阻 塞直到operation完成。這種方式在有很多Web Service需要在一個(gè)單一的客戶端應(yīng)用程序中啟動(dòng)時(shí)很不可取。一種解決方法是使用Non-Blocking API來調(diào)用這些Web Services。Axis2提供給用戶一種基于回叫機(jī)制的non-blocking API。
          EchoNonBlockingClient.java
          package userguide.clients;
          import org.apache.axiom.om.OMElement;
          import org.apache.axis2.AxisFault;
          import org.apache.axis2.addressing.EndpointReference;
          import org.apache.axis2.client.Options;
          import org.apache.axis2.client.ServiceClient;
          import org.apache.axis2.client.async.AsyncResult;
          import org.apache.axis2.client.async.Callback;
          /**
           * Sample for asynchronous single channel non-blocking service invocation.
           * Message Exchage Pattern IN-OUT
           */
          public class EchoNonBlockingClient {
          private static EndpointReference targetEPR =
           new EndpointReference("
          http://127.0.0.1:8080/axis2/services/MyService");
              public static void main(String[] args) {
                  ServiceClient sender = null;
                  try {
                      OMElement payload = ClientUtil.getEchoOMElement();
                      Options options = new Options();
                      options.setTo(targetEPR);
                      //Callback to handle the response
                     
          Callback callback = new Callback() {
                          public void onComplete(AsyncResult result) {
                              System.out.println(result.getResponseEnvelope());
                          }
                          public void onError(Exception e) {
                              e.printStackTrace();
                          }
                      };
                      //Non-Blocking Invocation
                      sender = new ServiceClient();
                      sender.setOptions(options);
                     
          sender.sendReceiveNonBlocking(payload, callback);
                      //Wait till the callback receives the response.
                      while (!callback.isComplete()) {
                          Thread.sleep(1000);
                      }
                  } catch (AxisFault axisFault) {
                      axisFault.printStackTrace();
                  } catch (Exception ex) {
                      ex.printStackTrace();
                  } finally {
                      try {
                          sender.finalizeInvoke();
                      } catch (AxisFault axisFault) { }
                  }
              }
          }
           
          結(jié)果:
          <?xml version='1.0' encoding='utf-8'?>
          <soapenv:Envelope xmlns:soapenv="
          http://schemas.xmlsoap.org/soap/envelope/">
          <soapenv:Header />
          <soapenv:Body>
          <example1:echo xmlns:example1="
          http://example1.org/example1"
          xmlns:tns="
          http://ws.apache.org/axis2">
          <example1:Text>
          Axis2 Echo String
          </example1:Text>
          </example1:echo>
          </soapenv:Body>
          </soapenv:Envelope>
              sender.sendReceiveNonBlocking(payload, callback);這個(gè)調(diào)用接受一個(gè)callback對(duì)象作為參數(shù)。Axis2客戶端API提供了一個(gè)抽象類CallBack,其中提供了方法:
          public abstract void onComplete(AsyncResult result);
          public abstract void onError(Exception e);
          public boolean isComplete() {}
              用戶需要重寫"onComplete " 和 "onError "方法。一旦客戶端收到Web Service的response,onComplete方法將會(huì)被調(diào)用,這樣將中止阻塞狀態(tài)。
           
          2.5EchoNonBlockingDualClient
              當(dāng)調(diào)用的Web Service需要很長(zhǎng)一段時(shí)間來完成時(shí),這種由Non-Blocking API提供的解決方式將有一定的局限性。這種局限性是由使用單一的傳輸連接來調(diào)用Web Service并接收response造成的。換句話說,客戶端提供一種沒有阻塞的調(diào)用機(jī)制,但request和response的傳輸使用單一的傳輸 (雙工方式)連接(如HTTP)。長(zhǎng)時(shí)間運(yùn)行的Web Service調(diào)用或Web Service調(diào)用使用單工傳輸方式(如SMTP)不能簡(jiǎn)單地利用一個(gè)沒有阻塞的調(diào)用。
              一種嘗試地解決方法是request和response各自使用單獨(dú)的傳輸連接(單工或雙工均可)。這種方式產(chǎn)生的問題是如何解決相關(guān)性(關(guān)聯(lián) request和response)。WS-Addressing提供了一種很好的解決方法,在頭中使用<wsa:MessageID> 和 <wsa:RelatesTo> 標(biāo)簽。Axis2對(duì)這種基于關(guān)聯(lián)機(jī)制的尋址方式提供了支持。
              用戶可以選擇Blocking 或Non-Blocking APIs的Web Service,并使用兩個(gè)傳輸連接。通過使用一個(gè)布爾標(biāo)記,同一個(gè)API可以調(diào)用多個(gè)在兩個(gè)傳輸連接上的Web Services(IN-OUT operations)。下例使用Non-Blocking API 以及兩個(gè)傳輸連接來實(shí)現(xiàn)上文中提到的"echo" operation。
          EchoNonBlockingDualClient.java
          package userguide.clients;
          import org.apache.axiom.om.OMElement;
          import org.apache.axis2.AxisFault;
          import org.apache.axis2.Constants;
          import org.apache.axis2.addressing.EndpointReference;
          import org.apache.axis2.client.Options;
          import org.apache.axis2.client.ServiceClient;
          import org.apache.axis2.client.async.AsyncResult;
          import org.apache.axis2.client.async.Callback;
          import javax.xml.namespace.QName;
          /**
           * Sample for asynchronous dual channel non-blocking service invocation.
           * Message Exchage Pattern IN-OUT
           * Ulitmate asynchronous service invocation sample.
           */
          public class EchoNonBlockingDualClient {
          private static EndpointReference targetEPR =
           new EndpointReference("
          http://127.0.0.1:8080/axis2/services/MyService");
              public static void main(String[] args) {
                  ServiceClient sender = null;
                  try {
                      OMElement payload = ClientUtil.getEchoOMElement();
                      Options options = new Options();
                      options.setTo(targetEPR);
                      options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
                   
             options.setUseSeparateListener(true);
                      options.setAction("urn:echo");  // this is the action mapping we put within the service.xml
                      //Callback to handle the response
                      Callback callback = new Callback() {
                          public void onComplete(AsyncResult result) {
                              System.out.println(result.getResponseEnvelope());
                          }
                          public void onError(Exception e) {
                              e.printStackTrace();
                          }
                      };
                      //Non-Blocking Invocation
                     ConfigurationContext sysContext = ConfigurationContextFactory
                      .createConfigurationContextFromFileSystem(
                       "D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);//見注解①
                      sender = new ServiceClient(sysContext, null);
                      sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
                      sender.setOptions(options);
                      sender.sendReceiveNonBlocking(payload, callback);
                      //Wait till the callback receives the response.
                      while (!callback.isComplete()) {
                          Thread.sleep(1000);
                      }
                      //Need to close the Client Side Listener.
                  } catch (AxisFault axisFault) {
                      axisFault.printStackTrace();
                  } catch (Exception ex) {
                      ex.printStackTrace();
                  } finally {
                      try {
                        
            sender.finalizeInvoke();
                      } catch (AxisFault axisFault) {
                          //have to ignore this
                      }
                  }
              }
          }
          注解①
          RE: [Axis2] 0.95 WS-Addressing web SERVICE-SIDE: module not found
              I now have managed to get EchoNonBlockingDualClient working. I still can't get the original code to work, where ever I put addressing-0.95.mar, but the ConfigurationContext works.
              The code I ended up with was:
           ConfigurationContext sysContext = ConfigurationContextFactory
                     .createConfigurationContextFromFileSystem(
                      "C:\\axis2", null);
            sender = new ServiceClient(sysContext, null);
              with no need, obviously, for the .engageModule method.
              I did discover though that the directory which the ConfigurationContext points to has to have two directories within it: "conf", which must contain the axis.xml configuration file, and the "modules" directory which contains addressing-0.95.mar.
              在方法"options.setUseSeparateListener(...)"中的布爾標(biāo)記通知通知Axis2引擎使用兩個(gè)不同的傳輸連接來分別處 理request和response。Finally中的 "serviceClient.finalizeInvoke()"方法通知Axis2引擎停用客戶端的用于接收response的listener。
              在我們運(yùn)行客戶端的例程之前,我們還有一件事情要做。如前面提到的,Axis2使用基于地址的關(guān)聯(lián)機(jī)制,因此我們必須在服務(wù)器端和客戶端“搭建”尋址模塊。

          結(jié)果:
          <?xml version='1.0' encoding='utf-8'?>
          <soapenv:Envelope xmlns:soapenv="
          http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
          <soapenv:Header>
          <wsa:To>http://59.14.131.187:6060/axis2/services/__ANONYMOUS_SERVICE__/__OPERATION_OUT_IN__
          </wsa:To>
          <wsa:ReplyTo>
          <wsa:Address>
          http://www.w3.org/2005/08/addressing/anonymous
          </wsa:Address>
          </wsa:ReplyTo>
          <wsa:From>
          <wsa:Address>
          http://127.0.0.1:8080/axis2/services/MyService
          </wsa:Address>
          </wsa:From>
          <wsa:FaultTo>
          <wsa:Address>
          http://127.0.0.1:8080/axis2/services/MyService
          </wsa:Address>
          </wsa:FaultTo>
          <wsa:MessageID>
          urn:uuid:B087CBB98F1B51A24711742241136206
          </wsa:MessageID>
          <wsa:Action>urn:echo</wsa:Action>
          <wsa:RelatesTo wsa:RelationshipType="wsa:Reply">
          urn:uuid:CA4B9513377E6E9E1511742241130391
          </wsa:RelatesTo>
          </soapenv:Header>
          <soapenv:Body>
          <example1:echo xmlns:example1="
          http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
          <example1:Text>
          Axis2 Echo String
          </example1:Text>
          </example1:echo>
          </soapenv:Body>
          </soapenv:Envelope>
          [SimpleHTTPServer] Stop called
           
          2.6 實(shí)現(xiàn)服務(wù)器端的尋址
              根據(jù)Axis2的結(jié)構(gòu),尋址模塊在"pre-dispatch"階段已經(jīng)給出它的句柄。因此,所謂的“搭建”僅僅是在”axis2.xml”(注意不是 services.xml)增加一個(gè)模塊的引用。現(xiàn)在將下面這行字加入到axis2.xml,該文件在"/webapps/axis2/WEB- INF/conf"目錄下。
          <module ref="addressing"/>
          注: 一旦你改變了axis2.xml,你必須重啟這個(gè)servlet容器,改變才能生效。
           
          2.7 實(shí)現(xiàn)客戶端的尋址
              有兩種方式。
              一種方法是在%Axis2_HOME%\axis2-std-1.0-bin\modules目錄下得到addressing-< version>.mar。并且在你的classpath中對(duì)其可見。(此種方法目前,我還沒有調(diào)試成功,具體見注解①。下面的第二種方法可用)
              另一種方法是創(chuàng)建一個(gè)ConfigurationContext,指定一個(gè)repository位置。Axis2支持repository的方式來保存服務(wù)和模塊。
              你可以使用二進(jìn)制distribution作為repository,只要它含有一個(gè)Axis2 repository認(rèn)可的repository結(jié)構(gòu)(其中應(yīng)包含services和modules目錄)。ConfigurationContext 中含有Axis2體系的運(yùn)行時(shí)的上下文信息。
              如果你解壓一個(gè)標(biāo)準(zhǔn)的二進(jìn)制distribution到目錄(譬如)$user_home/axis2/dist, 那么在 sender = new ServiceClient();之前加入(具體見EchoNonBlockingDualClient.java):
          new ServiceClient();之前加入(具體見EchoNonBlockingDualClient.java):
          ConfigurationContext configContext =
          ConfigurationContextFactory.createConfigurationContextFromFileSystem(< Axis2RepositoryLocation >, null);
              用"sender = new ServiceClient(configContext, null);" 替換 "sender = new ServiceClient();"
          這樣可以在客戶端和服務(wù)器端都實(shí)現(xiàn)尋址。
           
          2.8 EchoBlockingDualClient
              這又是一個(gè)兩路的傳輸?shù)膔equest/response客戶端,但這次,我們使用一個(gè)Blocking API。實(shí)現(xiàn)機(jī)制和EchoNonBlockingDualClient差不多,唯一的不同是,這里不需要使用一個(gè)callback對(duì)象來處理 response。
          EchoBlockingDualClient.java
          package userguide.clients;
          import org.apache.axiom.om.OMElement;
          import org.apache.axis2.AxisFault;
          import org.apache.axis2.Constants;
          import org.apache.axis2.addressing.EndpointReference;
          import org.apache.axis2.client.Options;
          import org.apache.axis2.client.ServiceClient;
          import javax.xml.namespace.QName;
          import javax.xml.stream.XMLOutputFactory;
          import java.io.StringWriter;
          /**
           * Sample for synchronous dual channel blocking service invocation.
           * Message Exchage Pattern IN-OUT
           */
          public class EchoBlockingDualClient {
          private static EndpointReference targetEPR =
           new EndpointReference("
          http://127.0.0.1:8080/axis2/services/MyService");
              public static void main(String[] args) {
                  ServiceClient sender = null;
                  try {
                      OMElement payload = ClientUtil.getEchoOMElement();
                      Options options = new Options();
                      options.setTo(targetEPR);
                      options.setAction("urn:echo");
                      //The boolean flag informs the axis2 engine to use two separate transport connection
                      //to retrieve the response.
                      options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
                      options.setUseSeparateListener(true);
                      //Blocking Invocation
                      ConfigurationContext sysContext = ConfigurationContextFactory
                      .createConfigurationContextFromFileSystem(
                       "D:\\Dvp\\Axis2\\axis2\\WEB-INF", null);
                      sender = new ServiceClient(sysContext, null);
                      sender.engageModule(new QName(Constants.MODULE_ADDRESSING));
                      sender.setOptions(options);
                      OMElement result = sender.sendReceive(payload);
                      StringWriter writer = new StringWriter();
                     result.serialize(XMLOutputFactory.newInstance().createXMLStreamWriter(writer));
                      writer.flush();
                      System.out.println(writer.toString());
                      //Need to close the Client Side Listener.
                  } catch (AxisFault axisFault) {
                      axisFault.printStackTrace();
                  } catch (Exception ex) {
                      ex.printStackTrace();
                  } finally{
                      try {
                          sender.finalizeInvoke();
                      } catch (AxisFault axisFault) {
                          //
                      }
                  }
              }
          }
          結(jié)果:
          <example1:echo xmlns:example1="
          http://example1.org/example1" xmlns:tns="http://ws.apache.org/axis2">
          <example1:Text>Axis2 Echo String </example1:Text>
          </example1:echo>
          [SimpleHTTPServer] Stop called
          posted on 2008-07-11 12:26 禮物 閱讀(1370) 評(píng)論(0)  編輯  收藏 所屬分類: web serviceAxis
          主站蜘蛛池模板: 垫江县| 清苑县| 云浮市| 称多县| 新宁县| 闵行区| 龙州县| 广南县| 德惠市| 南丰县| 崇州市| 永胜县| 甘德县| 石嘴山市| 聊城市| 夏津县| 博爱县| 灵川县| 临西县| 和林格尔县| 乌拉特后旗| 云龙县| 和田市| 九龙县| 泰和县| 嘉善县| 崇文区| 惠水县| 建宁县| 五家渠市| 湄潭县| 治县。| 高密市| 沁源县| 曲水县| 军事| 灵石县| 双牌县| 囊谦县| 达尔| 德兴市|