Springcloud如何使用Ribbon進(jìn)行Restful請(qǐng)求

這篇文章主要介紹了Spring cloud如何使用Ribbon進(jìn)行Restful請(qǐng)求,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)是少有的成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、營(yíng)銷型企業(yè)網(wǎng)站、微信小程序、手機(jī)APP,開發(fā)、制作、設(shè)計(jì)、賣鏈接、推廣優(yōu)化一站式服務(wù)網(wǎng)絡(luò)公司,2013年開創(chuàng)至今,堅(jiān)持透明化,價(jià)格低,無套路經(jīng)營(yíng)理念。讓網(wǎng)頁驚喜每一位訪客多年來深受用戶好評(píng)

前提

  1. 一個(gè)可用的Eureka注冊(cè)中心(文中以之前博客中雙節(jié)點(diǎn)注冊(cè)中心,不重要)

  2. 一個(gè)連接到這個(gè)注冊(cè)中心的服務(wù)提供者

  3. 一個(gè)ribbon的消費(fèi)者

注意:文中使用@GetMapping、@PostMapping、@PutMapping、@DeleteMapping等注解需要升級(jí) spring-boot-starter-parent版本到1.5.9.REALEASE以上(1.3.7.RELEASE版本沒有這些注解)

建議:每個(gè)微服務(wù)應(yīng)用都有自己的spring-boot-maven-plugin和maven-compiler-plugin并指定jdk編譯版本為1.8 ,指定方式如下,pom.xml中添加

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

測(cè)試項(xiàng)目構(gòu)建

Eureka注冊(cè)中心:參考注冊(cè)中心的搭建 
 服務(wù)提供者:參考注冊(cè)服務(wù)提供者
ribbon消費(fèi)者:參考服務(wù)發(fā)現(xiàn)與消費(fèi)

項(xiàng)目搭建完后,記得按照這幾個(gè)教程中提到的配置hosts文件

為了防止項(xiàng)目中的RequestMapping相同,這里就刪除所有的controller類(服務(wù)提供者和消費(fèi)者),接下來我會(huì)將每個(gè)restful方法都封裝成一個(gè)類,方便大家查看

Get請(qǐng)求

getForEntity:此方法有三種重載形式,分別為:

  1. getForEntity(String url, Class<T> responseType)

  2. getForEntity(String url, Class<T> responseType, Object... uriVariables)

  3. getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)

  4. getForEntity(URI url, Class<T> responseType)

注意:此方法返回的是一個(gè)包裝對(duì)象ResponseEntity<T>其中T為responseType傳入類型,想拿到返回類型需要使用這個(gè)包裝類對(duì)象的getBody()方法

getForObject:此方法也有三種重載形式,這點(diǎn)與getForEntity方法相同:

  1. getForObject(String url, Class<T> responseType)

  2. getForObject(String url, Class<T> responseType, Object... uriVariables)

  3. getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)

  4. getForObject(URI url, Class<T> responseType)

注意:此方法返回的對(duì)象類型為responseType傳入類型

為了方便測(cè)試,這里分別在服務(wù)提供者和服務(wù)消費(fèi)者中提供相同的User類,用于方便測(cè)試

package com.cnblogs.hellxz;

/**
 * 用于測(cè)試的pojo
 */
public class User {

  private String name;
  private String sex;
  private String phone;
  public User(){}
  public User(String name, String sex, String phone) {
    this.name = name;
    this.sex = sex;
    this.phone = phone;
  }

  public String toString(){
    return "user:{"
        +"name: " + name + ", "
        +"sex: " + sex + ", "
        +"phone: " + phone
        +" }";
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getSex() {
    return sex;
  }

  public void setSex(String sex) {
    this.sex = sex;
  }

  public String getPhone() {
    return phone;
  }

  public void setPhone(String phone) {
    this.phone = phone;
  }
}

下邊我們?cè)诜?wù)提供者處創(chuàng)建一個(gè)GetRequestController

package com.cnblogs.hellxz;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

/**
 * @Author : Hellxz
 * @Description: 服務(wù)提供者
 * @Date : 2018/4/18 11:36
 */
@RestController
public class GetRequestController {

  @Autowired
  private DiscoveryClient client; //注入發(fā)現(xiàn)客戶端

  private final Logger logger = Logger.getLogger(GetRequestController.class);

  /**
   * go straight test
   */
  @GetMapping(value = "/hello")
  public String hello(){
    //獲取服務(wù)實(shí)例,作用為之后console顯示效果
    ServiceInstance serviceInstance = client.getLocalServiceInstance();
    logger.info("/hello host:"+serviceInstance.getHost()+" service_id:" +serviceInstance.getServiceId());
    return "hello";
  }

  /**
   * parameter test
   */
  @GetMapping(value = "/greet/{dd}")
  public String greet(@PathVariable String dd){
    ServiceInstance serviceInstance = client.getLocalServiceInstance();
    logger.info("/hello host:"+serviceInstance.getHost()+" service_id:" +serviceInstance.getServiceId());
    return "hello "+dd;
  }

  /**
   * 返回測(cè)試對(duì)象
   */
  @GetMapping("/user")
  public User getUser(){
    ServiceInstance serviceInstance = client.getLocalServiceInstance();
    logger.info("/user "+serviceInstance.getHost()+" port:"+serviceInstance.getPort()+" serviceInstanceid:"+serviceInstance.getServiceId());
    return new User("hellxz","male", "123456789");
  }

  /**
   * 根據(jù)名稱返回對(duì)象,這里模擬查數(shù)據(jù)庫操作
   */
  @GetMapping("/user/{name}")
  public User getUserSelect(@PathVariable String name){
    ServiceInstance serviceInstance = client.getLocalServiceInstance();
    logger.info("/user "+serviceInstance.getHost()+" port:"+serviceInstance.getPort()+" serviceInstanceid:"+serviceInstance.getServiceId());
    if(name.isEmpty()){
      return new User();
    }else if(name.equals("hellxz")){
      return new User("hellxz","male", "123456789");
    }else{
      return new User("隨機(jī)用戶","male", "987654321");
    }
  }
}

接下來我們?cè)诜?wù)消費(fèi)者項(xiàng)目中創(chuàng)建GetRequestController

package com.cnblogs.hellxz;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author : Hellxz
 * @Description: ribbon消費(fèi)者應(yīng)用Controller,get請(qǐng)求
 * @Date : 2018/4/16 15:54
 */
@RestController
public class GetRequestController {

  private Logger logger = Logger.getLogger(GetRequestController.class);

  @Autowired
  //注入restTemplate
  private RestTemplate restTemplate;

  /**
   * ResponseEntity<T> getForEntity(String url, Class<T> responseType)
   * T getBody() 以下此方法相同
   */
  @GetMapping(value="/entity/noparam")
  public String noParamGetForEntity(){
    //這里注釋掉,因?yàn)橹跋氘?dāng)然使用了直鏈訪問服務(wù)提供者的接口,這樣是不會(huì)返回結(jié)果的,而且會(huì)報(bào)錯(cuò)
    //return restTemplate.getForEntity("http://localhost:8080/hello",String.class).getBody();
    //使用restTemplate調(diào)用微服務(wù)接口
    return restTemplate.getForEntity("http://hello-service/hello", String.class).getBody();

  }

  /**
   * ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
   */
  @GetMapping("/entity/type")
  public User getForEntityIdentifyByType(){
    //不傳參返回指定類型結(jié)果
    ResponseEntity<User> entity = restTemplate.getForEntity("http://hello-service/user", User.class);
    User body = entity.getBody();
    logger.info("user:"+body);
    return body;
    //以上可簡(jiǎn)寫為
//    return restTemplate.getForEntity("http://hello-service/user", User.class).getBody();
  }

  /**
   * ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
   * 使用占位符對(duì)參數(shù)進(jìn)行替換,內(nèi)部使用String.format方法實(shí)現(xiàn)
   */
  @GetMapping(value="/entity")
  //如果接收的參數(shù)是使用參數(shù)沒有使用?有則使用@PathVariable,否則用@RequestParam
  public String getForEntityByQuestionMarkParam(@RequestParam("name") String name){
    //主要測(cè)試getEntity方法,這里測(cè)試直接傳參
    return restTemplate.getForEntity("http://hello-service/greet/{1}", String.class, name).getBody();
  }

  /**
   * getForEntity方法內(nèi)部會(huì)提取map中,以占位符為key的值作為參數(shù)回填入url中
   * ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
   */
  @GetMapping(value="/entity/map/{name}")
  //如果接收的參數(shù)是使用參數(shù)沒有使用?有則使用@PathVariable,否則用@RequestParam
  public String getForEntityByMap(@PathVariable("name") String name){
    //主要測(cè)試getEntity方法,這里測(cè)試map傳參
    Map<String, String> reqMap = new HashMap();
    reqMap.put("name",name);
    return restTemplate.getForEntity("http://hello-service/greet/{name}", String.class,reqMap).getBody();
  }

  /**
   * ResponseEntity<T> getForObject(URI url, Class<T> responseType)
   */
  @GetMapping("/entity/uri")
  public String getForEntityByURI(){
    //使用uri進(jìn)行傳參并訪問
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://hello-service/greet/{name}").build().expand("laozhang").encode();
    URI uri = uriComponents.toUri();
    return restTemplate.getForEntity(uri, String.class).getBody();

  }
  /**
   * T getForObject(String url, Class<T> responseType)
   */
  @GetMapping("/object")
  public User getForObjectWithNoParam(){
    //相比getForEntity方法,獲取對(duì)象可以省去調(diào)用getBody
    return restTemplate.getForObject("http://hello-service/user", User.class);
  }

  /**
   * T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
   */
  @GetMapping("/object/map")
  public User getForObjectByMap(){
    //使用map傳參
    Map<String, String> paramMap = new HashMap<>();
    paramMap.put("name","hellxz");
    return restTemplate.getForObject("http://hello-service/user", User.class, paramMap);
  }

  /**
   * T getForObject(String url, Class<T> responseType, Object... uriVariables)
   */
  @GetMapping("/object/param/{name}")
  public User getForObjectByParam(@PathVariable String name){
    return restTemplate.getForObject("http://hello-service/user/{name}",User.class, name);
  }

  /**
   * T getForObject(URI url, Class<T> responseType)
   */
  @GetMapping("/object/uri/{name}")
  public User getForObjectByURI(@PathVariable String name){
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://hello-service/user/{name}")
                                        .build().expand(name).encode();
    URI uri = uriComponents.toUri();
    return restTemplate.getForObject(uri,User.class);
  }
}

先啟動(dòng)注冊(cè)中心,然后通過訪問消費(fèi)者對(duì)外提供的接口進(jìn)行測(cè)試,這些都是本人實(shí)際操作過的了,這里就不寫測(cè)試了

Post請(qǐng)求

post請(qǐng)求和get請(qǐng)求都有*ForEntity和*ForObject方法,其中參數(shù)列表有些不同,除了這兩個(gè)方法外,還有一個(gè)postForLocation方法,其中postForLocation以post請(qǐng)求提交資源,并返回新資源的URI

postForEntity:此方法有三種重載形式,分別為:

  1. postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)

  2. postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)

  3. postForEntity(URI url, Object request, Class<T> responseType)

注意:此方法返回的是一個(gè)包裝對(duì)象ResponseEntity<T>其中T為responseType傳入類型,想拿到返回類型需要使用這個(gè)包裝類對(duì)象的getBody()方法

postForObject:此方法也有三種重載形式,這點(diǎn)與postForEntity方法相同:

  1. postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)

  2. postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)

  3. postForObject(URI url, Object request, Class<T> responseType)

注意:此方法返回的對(duì)象類型為responseType傳入類型

postForLocation:此方法中同樣有三種重載形式,分別為:

  1. postForLocation(String url, Object request, Object... uriVariables)

  2. postForLocation(String url, Object request, Map<String, ?> uriVariables)

  3. postForLocation(URI url, Object request)

注意:此方法返回的是新資源的URI,相比getForEntity、getForObject、postForEntity、postForObject方法不同的是這個(gè)方法中無需指定返回類型,因?yàn)榉祷仡愋途褪荱RI,通過Object... uriVariables、Map<String, ?> uriVariables進(jìn)行傳參依舊需要占位符,參看postForEntity部分代碼

按照之前的方式,我們分別在提供服務(wù)者和消費(fèi)者的項(xiàng)目中分別創(chuàng)建PostRequestController

如下服務(wù)者PostRequestController代碼如下:

package com.shunneng.springcloudhelloworld;
import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
/**
 * @Author : Hellxz
 * @Description:
 * @Date : 2018/4/18 10:21
 */
@RestController
public class PostRequestController {
  private Logger logger = Logger.getLogger(PostRequestController.class);

  /**
   * 接收一個(gè)對(duì)象再返回回去,postForEntity/postForObject方法通用
   */
  @PostMapping("/user")
  public User returnUserByPost(@RequestBody User user){
    logger.info("/use接口 "+user);
    if(user == null) return new User("這是一個(gè)空對(duì)象","","");
    return user;
  }

  /**
   * 測(cè)試PostForEntity方法的參數(shù),可以直接看輸出判斷結(jié)果了
   */
  @PostMapping("/user/{str}")
  public User returnUserByPost(@PathVariable String str, @RequestBody User user){
    logger.info("/user/someparam 接口傳參 name:"+str +" "+user);
    if(user == null) return new User("這是一個(gè)空對(duì)象","","");
    return user;
  }

  /**
   * 為postForLocation方法返回URI
   */
  @PostMapping("/location")
  public URI returnURI(@RequestBody User user){
    //這里模擬一個(gè)url,真實(shí)資源位置不一定是這里
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://hello-service/location")
                                                .build().expand(user).encode();
    URI toUri = uriComponents.toUri();
    //這里不知道是什么問題,明明生成uri了,返回之后好像并沒有被獲取到
    logger.info("/location uri:"+toUri);
    return toUri;
  }
}

消費(fèi)端PostRequestController代碼:

package com.cnblogs.hellxz;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
/**
 * @Author : Hellxz
 * @Description: Ribbon消費(fèi)者post請(qǐng)求controller
 * @Date : 2018/4/18 9:47
 */
@RestController
public class PostRequestController {
  private Logger logger = Logger.getLogger(PostRequestController.class);
  @Autowired
  private RestTemplate restTemplate;

  /**
   * ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType)
   * 其中參數(shù)url不多說,Object request如果是不是一個(gè)HttpEntity對(duì)象,會(huì)自動(dòng)轉(zhuǎn)換為HttpEntity對(duì)象,視作完整的body來處理;
   * 如果是HttpEntity對(duì)象,那么會(huì)被直接當(dāng)做body處理并且包含header內(nèi)容。
   * 以下對(duì)于重寫的方法就不多說了,使用方法大體同getForEntity,如果僅是簡(jiǎn)單post對(duì)象,那么使用不帶Object...variables或Map variables的方法即可。
   * postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
   * postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
   *
   * 這里詳細(xì)說下我遇到的坑:
   * 1、其他幾個(gè)重載方法的最后邊的Object...variables和Map variables都是對(duì)之前的url進(jìn)行操作的,
   *   也就是說,在post請(qǐng)求的url中使用占位符進(jìn)行傳參,而如果在url中沒有使用占位符,那么這些最后傳的參數(shù)是無效的!
   * 2、方法中Object request這個(gè)對(duì)象如果和服務(wù)提供者的接收參數(shù)類型相同,那么服務(wù)提供者僅需使用@RequestBody接收參數(shù)即可。
   * 3、如果二者都使用了,這就比較有趣了,需要一邊通過@PathVariable注解接收uri中的參數(shù),一邊還需要@RequestBody接收對(duì)象或RequestParam按字段接收參數(shù)!
   * 4、如果報(bào)錯(cuò)了,請(qǐng)仔細(xì)看看我上邊寫的三條,并注意服務(wù)提供者的參數(shù)接收注解的使用等。
   */
  @PostMapping("/entity")
  public User postForEntity(){
    User user = new User("hellxz1","1","678912345");
    ResponseEntity<User> entity = restTemplate.postForEntity("http://hello-service/user/{str}", user, User.class, "測(cè)試參數(shù)");
    User body = entity.getBody(); //所有restTemplate.*ForEntity方法都是包裝類,body為返回類型對(duì)象
    return body;
  }

  /**
   * 使用URI傳參,測(cè)試結(jié)果會(huì)顯示在服務(wù)提供者的終端中
   * ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType)
   */
  @PostMapping("/entity/uri")
  public User postForEntityByURI(){
    User user = new User("老張","1","678912345");
    //這里只是將url轉(zhuǎn)成URI,并沒有添加參數(shù)
    UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://hello-service/user")
                                        .build().encode();
    URI toUri = uriComponents.toUri();
    //使用user傳參
    User object = restTemplate.postForObject(toUri, user, User.class);
    return object;
  }

  /**
   * 這里測(cè)試postForObject方法,需要注意的參數(shù)如上述方法的描述,區(qū)別只是不需要getBody了,這里就不再累述了
   * postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
   * postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
   */
  @PostMapping("/object")
  public User postForObject(){
    User user = new User("hellxz2","1","123654987");
    //這里url傳1是為了調(diào)用服務(wù)者項(xiàng)目中的一個(gè)接口
    User responseBody = restTemplate.postForObject("http://hello-service/user/1", user, User.class);
    return responseBody;
  }

  /**
   * post請(qǐng)求還有一種:postForLocation,這里也同樣有三種重載,除了無需指定返回類型外,用法相同,返回類型均為URI,也就不累述了
   * postForLocation(String url, Object request, Object... uriVariables)
   * postForLocation(String url, Object request, Map<String, ?> uriVariables)
   * postForLocation(URI url, Object request)
   */
  @PostMapping("/location")
  public URI postForLocation(){
    User user = new User("hellxz3","1","987654321");
    URI uri = restTemplate.postForLocation("http://hello-service/location", user);
    //不知道為什么返回來是空,這個(gè)方法僅供參考吧,如果知道是什么情況,我會(huì)回來改的
    logger.info("/location uri:"+uri);
    return uri;
  }
}

Put請(qǐng)求&&Delete請(qǐng)求

put請(qǐng)求相對(duì)于get和post請(qǐng)求方法來的更為簡(jiǎn)單,其中無需指定put請(qǐng)求的返回類型,當(dāng)然也沒有返回值,也是三種重載,和之前寫的基本一致,這里就不想多說了,delete請(qǐng)求和put請(qǐng)求都是沒有返回值的,這里再特地重復(fù)寫也沒什么意思,這里先分別列出這兩個(gè)請(qǐng)求的方法,代碼寫在一個(gè)類中了

put請(qǐng)求方法如下:

  1. put(String url, Object request, Object... uriVariables)

  2. put(String url, Object request, Map<String, ?> uriVariables)

  3. put(URI url, Object request)

delete請(qǐng)求方法如下:

  1. delete(String url, Object... uriVariables)

  2. delete(String url, Map<String, ?> uriVariables)

  3. delete(URI url)

在提供服務(wù)者項(xiàng)目中添加PutAndDeleteRequestController,代碼如下

package com.cnblogs.hellxz;

import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.*;


/**
 * @Author : Hellxz
 * @Description: 服務(wù)提供者 put&delete請(qǐng)求controller
 * @Date : 2018/4/19 14:11
 */
@RestController
public class PutAndDeleteRequestController {

  private Logger logger = Logger.getLogger(PutAndDeleteRequestController.class);

  @PutMapping("/put")
  public void put(@RequestBody User user){
    logger.info("/put "+user);
  }

  @DeleteMapping("/delete/{id}")
  public void delete(@PathVariable Long id){
    logger.info("/delete id:"+id);
  }
}

在提供服務(wù)者項(xiàng)目中添加PutAndDeleteRequestController,代碼如下

package com.cnblogs.hellxz;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * @Author : Hellxz
 * @Description: put請(qǐng)求、delete請(qǐng)求,重載的參數(shù)與上述demo基本相同,不予列出
 * @Date : 2018/4/19 13:43
 */
@RestController
public class PutRequestController {

  private Logger logger = Logger.getLogger(PostRequestController.class);
  @Autowired
  private RestTemplate restTemplate;

  /**
   * put請(qǐng)求示例,一般put請(qǐng)求多用作修改
   */
  @PutMapping("/put")
  public void put(@RequestBody User user){
    restTemplate.put("http://hello-service/put",user);
  }

  /**
   * delete請(qǐng)求示例
   */
  @DeleteMapping("/del/{id}")
  public void delete(@PathVariable Long id){
    restTemplate.delete("http://hello-service/delete/{1}", id);
  }
}

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Spring cloud如何使用Ribbon進(jìn)行Restful請(qǐng)求”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

本文標(biāo)題:Springcloud如何使用Ribbon進(jìn)行Restful請(qǐng)求
網(wǎng)站網(wǎng)址:http://m.kartarina.com/article4/pgosie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作自適應(yīng)網(wǎng)站關(guān)鍵詞優(yōu)化網(wǎng)站排名手機(jī)網(wǎng)站建設(shè)小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
主站蜘蛛池模板: 蜜臀亚洲AV无码精品国产午夜. | 台湾无码AV一区二区三区| 无码精品久久久天天影视| 无码国产精品一区二区免费虚拟VR| 久久久g0g0午夜无码精品| 永久免费无码网站在线观看个| 国产拍拍拍无码视频免费| 亚洲aⅴ天堂av天堂无码麻豆| 国产精品多人p群无码| 最新无码人妻在线不卡| 中文精品无码中文字幕无码专区| 一本色道无码道DVD在线观看 | 亚洲成AV人在线播放无码| 成人麻豆日韩在无码视频| 久热中文字幕无码视频| 永久无码精品三区在线4| 少妇爆乳无码专区| 久久亚洲AV成人无码软件| 中文无码vs无码人妻| 真人无码作爱免费视频| 亚洲av无码偷拍在线观看| 98久久人妻无码精品系列蜜桃| 亚洲中久无码永久在线观看同| 亚洲最大av资源站无码av网址 | 色窝窝无码一区二区三区色欲| 国产成人亚洲综合无码| 免费无码午夜福利片| 亚洲AV无码资源在线观看| 无码Aⅴ在线观看| 亚洲中文字幕无码mv| 久久久久亚洲AV片无码下载蜜桃| 亚洲AV人无码综合在线观看 | 韩国无码AV片在线观看网站| 亚洲毛片无码专区亚洲乱| 亚洲av永久无码精品天堂久久| 亚洲AV无码乱码国产麻豆穿越 | 亚洲午夜无码片在线观看影院猛| 亚洲国产成人精品无码区在线秒播| 亚洲精品无码永久在线观看你懂的| 人妻系列AV无码专区| 国产av永久无码天堂影院|