RestTemplate-創(chuàng)新互聯(lián)

RestTemplate

General 1920x1080 Gordon Zuchhold (Artstation) digital art science fiction pixel art city cyberpunk animation futuristic city ArtStation artwork futuristic

成都創(chuàng)新互聯(lián)專業(yè)IDC數(shù)據(jù)服務(wù)器托管提供商,專業(yè)提供成都服務(wù)器托管,服務(wù)器租用,川西大數(shù)據(jù)中心川西大數(shù)據(jù)中心,成都多線服務(wù)器托管等服務(wù)器托管服務(wù)。簡(jiǎn)介
  • RestTemplate是由Spring框架提供的一個(gè)可用于應(yīng)用中調(diào)用rest服務(wù)的類它簡(jiǎn)化了與http服務(wù)的通信方式,統(tǒng)一了RESTFul的標(biāo)準(zhǔn),封裝了http連接,我們只需要傳入url及其返回值類型即可。相較于之前常用的HttpClient,RestTemplate是一種更為優(yōu)雅的調(diào)用RESTFul服務(wù)的方式。
  • Spring應(yīng)用程序中訪問(wèn)第三方REST服務(wù)與使用Spring RestTemplate類有關(guān)。RestTemplate類的設(shè)計(jì)原則與許多其他Spring的模板類(例如JdbcTemplate)相同,為執(zhí)行復(fù)雜任務(wù)提供了一種具有默認(rèn)行為的簡(jiǎn)化方法。
  • RestTemplate默認(rèn)依賴JDK提供了http連接的能力(HttpURLConnection),如果有需要的話也可以通過(guò)setRequestFactory方法替換為例如Apache HttpCompoent、Netty或OKHttp等其他Http libaray
  • 考慮到了RestTemplate類是為了調(diào)用REST服務(wù)而設(shè)計(jì)的,因此它的主要方法與REST的基礎(chǔ)緊密相連就不足為奇了,后者時(shí)HTTP協(xié)議的方法:HEAD、GET、POST、PUT、DELETE、OPTIONS例如,RestTemplate類具有headForHeaders()、getForObject()、putForObject(),put()和delete()等方法。
創(chuàng)建RestTemplate

? 因?yàn)?code>RestTemplate是Spirng框架提供的所以只要是一個(gè)Springboot項(xiàng)目就不用考慮導(dǎo)包的問(wèn)題,這些都是提供好的。

? 但是Spring并沒(méi)有將其加入SpringBean容器中,需要我們手動(dòng)加入,因?yàn)槲覀兪紫葎?chuàng)建一個(gè)Springboot配置類,再在配置類中將我們的RestTemlate注冊(cè)到Bean容器中

方法一

? 使用Springboot提供的RestTemplateBuilder構(gòu)造類來(lái)構(gòu)造一個(gè)RestTemplate,可以自定義一些連接參數(shù),如:連接超時(shí)時(shí)間,讀取超時(shí)時(shí)間,還有認(rèn)證信息等

image-20220415202710768

@Configuration
public class WebConfiguration {@Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){return builder
                //設(shè)置連接超時(shí)時(shí)間
                .setConnectTimeout(Duration.ofSeconds(5000))
                //設(shè)置讀取超時(shí)時(shí)間
                .setReadTimeout(Duration.ofSeconds(5000))
                //設(shè)置認(rèn)證信息
                .basicAuthentication("username","password")
                //設(shè)置根路徑
                .rootUri("https://api.test.com/")
                //構(gòu)建
                .build();
    }
}
添加自定義的攔截器

? 自定義攔截器示例

@Slf4j
public class CustomClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {@Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {//打印請(qǐng)求明細(xì)
        logRequestDetails(request,body);
        ClientHttpResponse response = execution.execute(request, body);
        //打印響應(yīng)明細(xì)
        logResponseDetails(response);
        
        return response;
    }

    private void logRequestDetails(HttpRequest request, byte[] body){log.debug("Headers:{}",request.getHeaders());
        log.debug("body:{}",new String(body, StandardCharsets.UTF_8));
        log.debug("{}:{}",request.getMethod(),request.getMethodValue());
    }

    private void logResponseDetails(ClientHttpResponse response) throws IOException {log.debug("Status code : {}",response.getStatusCode());
        log.debug("Status text : {}",response.getStatusText());
        log.debug("Headers : {}",response.getHeaders());
        log.debug("Response body: {}", StreamUtils.copyToString(response.getBody(),StandardCharsets.UTF_8));
    }
}

? 使用RestTemplateBuilder構(gòu)造類,添加自定義攔截器,構(gòu)造帶有自定義攔截器的RestTemplate實(shí)例

@Configuration
public class WebConfiguration {@Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){return builder
                .additionalInterceptors(new CustomClientHttpRequestInterceptor())
                //構(gòu)建
                .build();
    }    
}

? 測(cè)試請(qǐng)求確實(shí)經(jīng)過(guò)了攔截器,注冊(cè)成功(注意請(qǐng)求和響應(yīng)的流只會(huì)被讀取一次,這里我們讀取了response后返回的response就讀取不到剛剛讀過(guò)的內(nèi)容了)

?image-20220415204816204


方法二

? 使用RestTemplate構(gòu)造方法構(gòu)造一個(gè)RestTemlate,雖然不能像RestTemplate構(gòu)造類那樣更詳細(xì)、更多樣的配置參數(shù),但是RestTemplate構(gòu)造方法在一般情況是夠用的。

image-20220415195208601

  • 無(wú)參構(gòu)造 全部參數(shù)默認(rèn)
  • 指定ClientHttpRequestFactory的構(gòu)造方法可以指定自己實(shí)現(xiàn)的ClientHttpRequestFactory(客戶端http請(qǐng)求工廠)其他的與無(wú)參構(gòu)造相同。
    • ClientHttpRequestFactory
  • 指定List>的構(gòu)造方法可以指定自己是實(shí)現(xiàn)的HttpMessageConverterHttp消息轉(zhuǎn)換器)傳入其他與無(wú)參構(gòu)造相同。
@Configuration
public class WebConfiguration {@Bean
    public RestTemplate restTemplate(){return new RestTemplate();
    }
    
}

? 兩者方法都可使用,前者提供了多樣的自定義參數(shù)的選擇,可以將RestTemplate配置的更為完善,后者則簡(jiǎn)化了配置雖然配置多樣性不如前者,但是日常使用調(diào)用些API還是足以使用

RestTemplate API使用

? 在使用RestTemplate前先讓我們看看RestTemplate有哪些API

image-20220415205801633image-20220415205831801

? 相信大家看到這么多方法,一定很頭大,但是我們仔細(xì)看上述的方法,我們可以提取出主要的幾種方法是(這里只討論Http請(qǐng)求的):

  • GET
  • POST
  • PUT
  • DELETE
  • HEAD
  • OPTIONS
  • EXCHANGE
  • EXECUTE

? 這里我給大家安利一個(gè)一個(gè)網(wǎng)站,它提供免費(fèi)的RESTFul api的樣例測(cè)試。httpbin A simple HTTP Request & Response Service.


GET

? 通過(guò)上圖我們可以發(fā)現(xiàn)RestTemlate發(fā)送GET請(qǐng)求的方法有兩種

  • publicT getForObject(...)
  • publicResponseEntitygetForEntity(...)
getForEntity()

? 后綴帶有Entity的方法都代表返回一個(gè)ResponseEntity,ResponseEntity是Spring對(duì)HTTP請(qǐng)求響應(yīng)的封裝,包括了幾個(gè)重要的元素,如響應(yīng)碼,contentType、contentLength、響應(yīng)消息體等

image-20220415211830207

? 通過(guò)它繼承父類(HttpEntity)的getHeader()方法我們可以獲取contentType、contentLength、響應(yīng)消息體等。比如下面這個(gè)例子。

public void queryWeather() {ResponseEntityforEntity = restTemplate.getForEntity("https://restapi.amap.com/v3/weather/weatherInfo?city=510100&key=e7a5fa943f706602033b6b329c49fbc6", Object.class);
        System.out.println("狀態(tài)碼:"+forEntity.getStatusCode());
        System.out.println("狀態(tài)碼內(nèi)容:"+forEntity.getStatusCodeValue());
        HttpHeaders headers = forEntity.getHeaders();
        System.out.println("響應(yīng)頭:"+headers);
        Object body = forEntity.getBody();
        System.out.println("響應(yīng)內(nèi)容:"+body);
    }

? 該例子中getForEntity()方法的第一個(gè)參數(shù)為我要調(diào)用服務(wù)的URL,第二個(gè)參數(shù)則為響應(yīng)內(nèi)容的類的類型(Java嘛 萬(wàn)物皆對(duì)象)還可以添加第三個(gè)參數(shù),第三個(gè)參數(shù)為一個(gè)可變參數(shù) 代表著調(diào)用服務(wù)時(shí)的傳參。

image-20220415212800839第三個(gè)參數(shù)可以使用key-value的map來(lái)傳入?yún)?shù)

? get請(qǐng)求也可通過(guò)向在url上添加查詢參數(shù)來(lái)發(fā)送帶有請(qǐng)求的參數(shù)


getForObject()

? 相比于前者getForEntity()該方法則是,更偏向于直接獲取響應(yīng)內(nèi)容的,因?yàn)樗苯臃祷仨憫?yīng)實(shí)體的body(響應(yīng)內(nèi)容),。比如下面這個(gè)例子

public void queryWeather() {
        Object body = restTemplate.getForObject("https://restapi.amap.com/v3/weather/weatherInfo?city=510100&key=e7a5fa943f706602033b6b329c49fbc6", Object.class);
        System.out.println(body);
    }
方法參數(shù)簽名與`getForEntity()`基本一致。

? 當(dāng)你只需要返回的響應(yīng)內(nèi)容時(shí),使用getForObject()是一個(gè)很好的選擇,但當(dāng)你需要獲得更詳細(xì)的響應(yīng)信息,如響應(yīng)頭中的信息,你就只能選擇getForEntity()了。


POST

?POST請(qǐng)求有如下三種方法

  • public URI postForLocation(...)
  • publicT postForObject(...)
  • publicResponseEntitypostForEntity(...)

? 后兩種用法與GET基本一致不做詳細(xì)介紹,這里著重介紹postForLocation()


postForEntity()

? 該方法有三個(gè)參數(shù),第一個(gè)為調(diào)用服務(wù)的地址(URL)

? 第二個(gè)參數(shù)表示上傳的參數(shù)(json格式提交)

? 第三個(gè)表示返回響應(yīng)內(nèi)容的具體類型

? 第四個(gè)參數(shù)也用于指定參數(shù)(在URL中添加)

@Override
    public void queryWeather() {User user = new User();
        user.setName("魯大師");
        ResponseEntityobjectResponseEntity = restTemplate.postForEntity("https://restapi.amap.com/v3/weather/weatherInfo?city=510100&key=e7a5fa943f706602033b6b329c49fbc6", user, Object.class);
        System.out.println("消息響應(yīng)內(nèi)容:"+objectResponseEntity.getBody());
    }
postForObject()

? 使用方法與getForObject類似只是多了一個(gè)傳入對(duì)象參數(shù)(傳入方式與postForEntity()相同)

public void queryWeather() {User user = new User();
        user.setName("魯大師");
        ResponseEntityobjectResponseEntity = restTemplate.postForEntity("https://httpbin.org/post", user, Object.class);
        MediaType contentType = objectResponseEntity.getHeaders().getContentType();
        System.out.println(contentType);
        System.out.println("消息響應(yīng)內(nèi)容:"+objectResponseEntity.getBody());
    }
postForLocation()

?postForLocation傳參用法與前兩者一致,只不過(guò)返回從實(shí)體變成了一個(gè)URL,因此它不需要指定返回響應(yīng)內(nèi)容的類型。

public void queryWeather() {User user = new User();
        user.setName("魯大師");
        URI uri = restTemplate.postForLocation("https://httpbin.org/post", user);
        System.out.println(uri);
    }

這個(gè)只需要服務(wù)提供者返回一個(gè) URI 即可,該URI返回值體現(xiàn)的是:用于提交完成數(shù)據(jù)之后的頁(yè)面跳轉(zhuǎn),或數(shù)據(jù)提交完成之后的下一步數(shù)據(jù)操作URI

使用POST以表單方式提交

? 這里我們著重說(shuō)一下,如何自己封裝一個(gè)請(qǐng)求體。

? 我們需要用到如下幾個(gè)類

  • HttpHeaders
  • MultiValueMap
  • HttpEntity
HttpHeaders

? 故名思意,就是用來(lái)封裝Http請(qǐng)求的請(qǐng)求頭的,這里我們要設(shè)置他的ContentType為**MediaType.APPLICATION_FORM_URLENCODED**以使得我們提交的參數(shù)是以Form(表單)的形式提交。

//設(shè)置請(qǐng)求頭, x-www-form-urlencoded格式的數(shù)據(jù)
        HttpHeaders httpHeaders = new HttpHeaders();
        //這里指定參數(shù)以UTF-8編碼格式傳輸
        MediaType mediaType = new MediaType(MediaType.APPLICATION_FORM_URLENCODED, UTF_8);
        httpHeaders.setContentType(mediaType);
        //提交參數(shù)設(shè)置
        MultiValueMapmap = new LinkedMultiValueMap<>();
        map.add("name","魯大師");

MultiValueMap

? 該類是用來(lái)封裝請(qǐng)求參數(shù)的,是以key-value的形式封裝但是以單個(gè)key對(duì)應(yīng)多個(gè)value的格式傳輸(也就是是以單個(gè)key:[value...]的格式傳輸?shù)?。

//提交參數(shù)設(shè)置
        MultiValueMapmap = new LinkedMultiValueMap<>();
        map.add("name","魯大師");

? 如果像傳輸單個(gè)key對(duì)應(yīng)單個(gè)value使用普通的Map傳參即可


HttpEntity

? 該類是用來(lái)封裝請(qǐng)求的,主要作用就是將請(qǐng)求頭和請(qǐng)求體封裝在一起成為一個(gè)請(qǐng)求實(shí)體 T用來(lái)指定用來(lái)封裝參數(shù)的容器的類型。

//組裝請(qǐng)求體
        HttpEntity>request = new HttpEntity<>(map, httpHeaders);

測(cè)試

通過(guò)上述介紹后,我們就可以自己封裝一個(gè)以form形式提交參數(shù)的POST請(qǐng)求了。

@Test
    void contextLoads() {//請(qǐng)求地址
        String url = "https://httpbin.org/post";

        //設(shè)置請(qǐng)求頭, x-www-form-urlencoded格式的數(shù)據(jù)
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        //提交參數(shù)設(shè)置
        MultiValueMapmap = new LinkedMultiValueMap<>();
        map.add("name","魯大師");

        //組裝請(qǐng)求體
        HttpEntity>request = new HttpEntity<>(map, httpHeaders);


        //發(fā)送post請(qǐng)求并打印結(jié)果 以String類型接收響應(yīng)結(jié)果JSON字符串
        String s = restTemplate.postForObject(url, request, String.class);
        System.out.println(s);
    }

image-20220416124128856

? 通過(guò)攔截器攔截了請(qǐng)求并對(duì)請(qǐng)求頭進(jìn)行拆包,可以發(fā)現(xiàn)ContentType已經(jīng)被修改成了x-www-form-urlencoded格式了。

PUT

?PUT請(qǐng)求的方法只有一類

  • void put()
PUT()

? 使用方法與postForEntity()參數(shù)基本一致,只是put方法沒(méi)有返回值(也就不必去設(shè)置響應(yīng)內(nèi)容的類型了)。

@Test
    void contextLoads() {//請(qǐng)求地址
        String url = "http://httpbin.org/put";
        User user = new User();
        user.setName("魯大師");
        restTemplate.put(url,user);
    }

DELETE

? 與PUT一樣,DELETE方法只有一類

  • void delete()
delete()

?delete()可以指定url中的中的參數(shù),但是RestTemplatedelete()方法是不支持上傳requestBody的。

void contextLoads() {//請(qǐng)求地址
    String url = "http://httpbin.org/delete";
    restTemplate.delete(url);
}

HEADER

?HEADER也只有一類方法

  • public HttpHeaders headForHeaders()

? 主要用來(lái)發(fā)送請(qǐng)求獲取響應(yīng)頭部信息,但是像DELETE、PUT這類沒(méi)有響應(yīng)的方法,是不能使用該方法的(因?yàn)闆](méi)有響應(yīng)也就沒(méi)有響應(yīng)頭了)。

@Test
    void contextLoads() {//請(qǐng)求地址
        String url = "http://httpbin.org/get";
        HttpHeaders httpHeaders = restTemplate.headForHeaders(url);
        System.out.println(httpHeaders);
    }

image-20220416151836372


OPTIONS
  • public SetoptionsForAllow()

? 該方法的主要用來(lái)判斷該服務(wù)地址,能夠使用那種方法去執(zhí)行

@Test
    void contextLoads() {//請(qǐng)求地址
        String url = "http://httpbin.org/get";
        SethttpMethods = restTemplate.optionsForAllow(url);
        System.out.println(httpMethods);
    }

image-20220416152755753


EXCHANGE
  • ResponseEntityexchange()

? 該接口與其他接口不同

  • 該方法允許用戶指定請(qǐng)求的方法(get,post,put等)
  • 可以在請(qǐng)求中增加body以及頭信息,其內(nèi)容通過(guò)參數(shù)HttpEntityrequestEntity描述
  • exchange支持’含參數(shù)的類型(即泛型)'作為返回類型,該特性通過(guò)ParameterizedTypeReferenceresponseType描述

? 該方法支持五個(gè)參數(shù)

  • 第一個(gè)是服務(wù)地址
  • 第二個(gè)是請(qǐng)求方法
  • 第三個(gè)是寫(xiě)入的請(qǐng)求實(shí)體
  • 第四個(gè)是響應(yīng)內(nèi)容的類型
  • 第五個(gè)是擴(kuò)展模板的變量或包含URI模板變量的映射
@Test
void contextLoads() {//請(qǐng)求地址
    String url = "http://httpbin.org/post";
    User user = new User();
    user.setName("彭于晏");
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    HttpEntityuserHttpEntity = new HttpEntity<>(user, httpHeaders);
    ResponseEntityexchange = restTemplate.exchange(url, HttpMethod.POST, userHttpEntity, Object.class);
    System.out.println(exchange);
}

? 上述代碼模擬了一個(gè)簡(jiǎn)單的POST請(qǐng)求 可以理解為可以動(dòng)態(tài)的指定請(qǐng)求方法和請(qǐng)求實(shí)體的一個(gè)方法。

響應(yīng)實(shí)體

image-20220416154441113


EXECUTE
  • T execute()

? 該方法就是執(zhí)行請(qǐng)求的方法,我們可以發(fā)現(xiàn)上述的所有方法的最后執(zhí)行都是調(diào)用的該方法執(zhí)行,所以他在RestTemplate中十分重要

? 該方法有五個(gè)參數(shù)

  • 服務(wù)地址
  • 請(qǐng)求的方法
  • 準(zhǔn)備請(qǐng)求的對(duì)象(requestCallback
  • 從響應(yīng)中提取返回值的對(duì)象
  • 擴(kuò)展模板的變量或包含URI模板變量的映射

execute()

@Override
	@Nullable
	publicT execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
			@Nullable ResponseExtractorresponseExtractor, Object... uriVariables) throws RestClientException {URI expanded = getUriTemplateHandler().expand(url, uriVariables);
		return doExecute(expanded, method, requestCallback, responseExtractor);
	}

? 通過(guò)上述源碼我們可以發(fā)現(xiàn)execute()方法只是將我們傳入的String類型的URL轉(zhuǎn)換為了URL類型,最后執(zhí)行請(qǐng)求是由doExecute()方法


doExecute()

? 這里需要了解兩個(gè)類:RequestCallbackResPonseExtractor

?RequestCallback: 用于操作請(qǐng)求頭和body,在請(qǐng)求發(fā)出前執(zhí)行。不需要關(guān)心關(guān)閉請(qǐng)求或處理錯(cuò)誤:這都將由RestTemplate處理。

? 該接口有兩個(gè)實(shí)現(xiàn)類:

?img

?ResPonseExtractor: 解析HTTP響應(yīng)的數(shù)據(jù),而且不需要擔(dān)心異常和資源的關(guān)閉。

? 該接口在RestTemplate中同樣有兩個(gè)實(shí)現(xiàn)類:

HeadersExtractor提取響應(yīng)HttpHeaders的響應(yīng)提取器。直接提取響應(yīng)體中的響應(yīng)頭
ResponseEntityResponseExtractorHttpEntity的響應(yīng)提取器??梢垣@取響應(yīng)實(shí)體里面包括響應(yīng)頭,響應(yīng)體等。具體請(qǐng)查看HttpEntity
@Test
void contextLoads() {//請(qǐng)求地址
    String url = "http://httpbin.org/post";
    User user = new User();
    user.setName("彭于晏");
    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    HttpEntityuserHttpEntity = new HttpEntity<>(user, httpHeaders);
    ResponseEntityexecute = restTemplate.execute(url, HttpMethod.POST, restTemplate.httpEntityCallback(userHttpEntity), restTemplate.responseEntityExtractor(Object.class));
    System.out.println(execute);
}

image-20220416161653708


解惑
  • 前面我們介紹方法的時(shí)候發(fā)現(xiàn)有個(gè)一個(gè)可變參數(shù),那個(gè)參數(shù)被描述成了擴(kuò)展模板的變量或是包含URI模板變量的映射

我們來(lái)簡(jiǎn)單看一下這個(gè)參數(shù),我們知道請(qǐng)求傳參可以通過(guò)url拼接參數(shù)的方式傳參,拼接參數(shù)也分為兩種:

  • 路徑中嵌入占位的格式(http://httpbin.org/{1}/post)也叫模板映射
  • 末尾添加Key-value格式(http://httpbin.org/post?name="彭于晏")即擴(kuò)展模板的變量
  • 當(dāng)我們最后一參數(shù)傳入map時(shí)會(huì)以key-value的格式拼接在URL后(通俗的說(shuō)就是這樣設(shè)置的變量會(huì)跟著URL路徑后面)

?http://httpbin.org/post?name="彭于晏"

@Test
void contextLoads() {//請(qǐng)求地址
    String url = "http://httpbin.org/get";
    HashMapmap = new HashMap<>();
    map.put("name","彭于晏");
    Object forObject = restTemplate.getForObject(url, Object.class, map);
    System.out.println(forObject);
}
  • 當(dāng)我們傳入簡(jiǎn)單的對(duì)象如String,Integer時(shí)且路徑中有嵌入的占位符時(shí)就會(huì)代替調(diào)用URL中占位符
@Test
void contextLoads() {//請(qǐng)求地址
    String url = "http://httpbin.org/{2}/get";
    HashMapmap = new HashMap<>();
    Object forObject = restTemplate.getForObject(url, Object.class, 99);
    System.out.println(forObject);
}

image-20220416163605771


參考

spring cloud 做微服務(wù)時(shí)關(guān)于RestTemplate中的各種請(qǐng)求方法的使用總結(jié)_DWT_CCFK的博客-博客

RestTemplate 詳解 - 知乎 (zhihu.com)

RestTemplate使用教程 - 簡(jiǎn)書(shū) (jianshu.com)


-End-

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁(yè)名稱:RestTemplate-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)源:http://bm7419.com/article22/gegcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、自適應(yīng)網(wǎng)站定制開(kāi)發(fā)、網(wǎng)站策劃建站公司網(wǎng)站制作

廣告

聲明:本網(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í)需注明來(lái)源: 創(chuàng)新互聯(lián)