最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解如何使用Jersey客戶端請(qǐng)求Spring Boot(RESTFul)服務(wù)

 更新時(shí)間:2018年01月15日 11:09:27   作者:牛奮lch  
本篇文章主要介紹了詳解如何使用Jersey客戶端請(qǐng)求Spring Boot(RESTFul)服務(wù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

本文介紹了使用Jersey客戶端請(qǐng)求Spring Boot(RESTFul)服務(wù),分享給大家,具體如下:

Jersey客戶端獲取Client對(duì)象實(shí)例封裝:

@Service("jerseyPoolingClient") 
public class JerseyPoolingClientFactoryBean implements FactoryBean<Client>, InitializingBean, DisposableBean{ 
   
  /** 
   * Client接口是REST客戶端的基本接口,用于和REST服務(wù)器通信。Client被定義為一個(gè)重量級(jí)的對(duì)象,其內(nèi)部管理著 
   * 客戶端通信底層的各種對(duì)象,比如連接器,解析器等。因此,不推薦在應(yīng)用中產(chǎn)生大量的的Client實(shí)例,這一點(diǎn)在開(kāi)發(fā)中 
   * 需要特別小心,另外該接口要求其實(shí)例要有關(guān)閉連接的保障,否則會(huì)造成內(nèi)存泄露 
   */ 
  private Client client; 
   
  /** 
   * 一個(gè)Client最大的連接數(shù),默認(rèn)為2000 
   */ 
  private int maxTotal = 2000; 
   
  /** 
   * 每路由的默認(rèn)最大連接數(shù) 
   */ 
  private int defaultMaxPerRoute = 1000; 
   
  private ClientConfig clientConfig; 
   
  public JerseyPoolingClientFactoryBean() { 
  } 
   
  /** 
   * 帶配置的構(gòu)造函數(shù) 
   * @param clientConfig 
   */ 
  public JerseyPoolingClientFactoryBean(ClientConfig clientConfig) { 
    this.clientConfig = clientConfig; 
  } 
 
  public JerseyPoolingClientFactoryBean(int maxTotal, int defaultMaxPerRoute) { 
    this.maxTotal = maxTotal; 
    this.defaultMaxPerRoute = defaultMaxPerRoute; 
  } 
 
  /** 
   * attention: 
   * Details:容器銷(xiāo)毀時(shí),釋放Client資源 
   * @author chhliu 
   */ 
  @Override 
  public void destroy() throws Exception { 
    this.client.close(); 
  } 
 
  /** 
   * 
   * attention: 
   * Details:以連接池的形式,來(lái)初始化Client對(duì)象 
   * @author chhliu 
   */ 
  @Override 
  public void afterPropertiesSet() throws Exception { 
    // 如果沒(méi)有使用帶ClientConfig的構(gòu)造函數(shù),則該類(lèi)的實(shí)例為null,則使用默認(rèn)的配置初始化 
    if(this.clientConfig == null){ 
      final ClientConfig clientConfig = new ClientConfig(); 
      // 連接池管理實(shí)例,該類(lèi)是線程安全的,支持多并發(fā)操作 
      PoolingHttpClientConnectionManager pcm = new PoolingHttpClientConnectionManager(); 
      pcm.setMaxTotal(this.maxTotal); 
      pcm.setDefaultMaxPerRoute(this.defaultMaxPerRoute); 
       
      clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, pcm); 
      /* 
       * 在使用Jersey來(lái)請(qǐng)求Spring Boot服務(wù)時(shí),Spring Boot默認(rèn)使用Jackson來(lái)解析JSON 
       * 而Jersey默認(rèn)使用MOXy解析JSON,當(dāng)Jersey Client想Spring Boot服務(wù)請(qǐng)求資源時(shí), 
       * 這個(gè)差異會(huì)導(dǎo)致服務(wù)端和客戶端對(duì)POJO的轉(zhuǎn)換不同,造成反序列化的錯(cuò)誤 
       * 因此,此處需要在Client的Config實(shí)例中注冊(cè)Jackson特性 
       */ 
      clientConfig.register(JacksonFeature.class); 
      // 使用配置Apache連接器,默認(rèn)連接器為HttpUrlConnector 
      clientConfig.connectorProvider(new ApacheConnectorProvider()); 
      client = ClientBuilder.newClient(clientConfig); 
    }else{ 
      // 使用構(gòu)造函數(shù)中的ClientConfig來(lái)初始化Client對(duì)象 
      client = ClientBuilder.newClient(this.clientConfig); 
    } 
  } 
 
  /** 
   * attention: 
   * Details:返回Client對(duì)象,如果該對(duì)象為null,則創(chuàng)建一個(gè)默認(rèn)的Client 
   * @author chhliu 
   */ 
  @Override 
  public Client getObject() throws Exception { 
    if(null == this.client){ 
      return ClientBuilder.newClient(); 
    } 
    return this.client; 
  } 
 
  /** 
   * attention: 
   * Details:獲取Client對(duì)象的類(lèi)型 
   * @author chhliu 
   */ 
  @Override 
  public Class<?> getObjectType() { 
    return (this.client == null ? Client.class : this.client.getClass()); 
  } 
 
  /** 
   * attention: 
   * Details:Client對(duì)象是否為單例,默認(rèn)為單例 
   * @author chhliu 
   */ 
  @Override 
  public boolean isSingleton() { 
    return true; 
  } 
} 

請(qǐng)求Spring Boot服務(wù)的封裝:

@Component("jerseyClient") 
public class JerseyClient { 
   
  @Resource(name="jerseyPoolingClient") 
  private Client client; 
   
  /** 
   * attention: 
   * Details:通過(guò)id來(lái)查詢對(duì)象 
   * @author chhliu 
   */ 
  public ResultMsg<GitHubEntity> getResponseById(final String id) throws JsonProcessingException, IOException{ 
    WebTarget webTarget = client.target("http://localhost:8080").path("/github/get/user/"+id); 
    Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); 
    GenericType<ResultMsg<GitHubEntity>> genericType = new GenericType<ResultMsg<GitHubEntity>>(){}; 
    Response response = invocationBuilder.get(); 
    if(response.getStatus() == 200){ 
      /* 
       * 當(dāng)調(diào)用readEntity方法時(shí),程序會(huì)自動(dòng)的釋放連接 
       * 即使沒(méi)有調(diào)用readEntity方法,直接返回泛型類(lèi)型的對(duì)象,底層仍然會(huì)釋放連接 
       */ 
      return response.readEntity(genericType); 
    }else{ 
      ResultMsg<GitHubEntity> res = new ResultMsg<GitHubEntity>(); 
      res.setErrorCode(String.valueOf(response.getStatus())); 
      res.setErrorMsg(response.getStatusInfo().toString()); 
      res.setOK(false); 
      return res; 
    } 
  } 
   
  /** 
   * attention: 
   * Details:分頁(yè)查詢 
   * @author chhliu 
   */ 
  public ResultMsg<Pager<GitHubEntity>> getGithubWithPager(final Integer pageOffset, final Integer pageSize, final String orderColumn){ 
    WebTarget webTarget = client.target("http://localhost:8080").path("/github/get/users/page") 
        .queryParam("pageOffset", pageOffset) 
        .queryParam("pageSize", pageSize) 
        .queryParam("orderColumn", orderColumn); 
        // 注意,如果此處的媒體類(lèi)型為MediaType.APPLICATION_JSON,那么對(duì)應(yīng)的服務(wù)中的參數(shù)前需加上@RequestBody 
        Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); 
    GenericType<ResultMsg<Pager<GitHubEntity>>> genericType = new GenericType<ResultMsg<Pager<GitHubEntity>>>(){}; 
    Response response = invocationBuilder.get(); 
    if(response.getStatus() == 200){ 
      return response.readEntity(genericType); 
    }else{ 
      ResultMsg<Pager<GitHubEntity>> res = new ResultMsg<Pager<GitHubEntity>>(); 
      res.setErrorCode(String.valueOf(response.getStatus())); 
      res.setErrorMsg(response.getStatusInfo().toString()); 
      res.setOK(false); 
      return res; 
    } 
     
  } 
   
  /** 
   * attention: 
   * Details:根據(jù)用戶名來(lái)查詢 
   * @author chhliu 
   */ 
  public ResultMsg<List<GitHubEntity>> getResponseByUsername(final String username) throws JsonProcessingException, IOException{ 
    WebTarget webTarget = client.target("http://localhost:8080").path("/github/get/users/"+username); 
    Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); 
    GenericType<ResultMsg<List<GitHubEntity>>> genericType = new GenericType<ResultMsg<List<GitHubEntity>>>(){}; 
    Response response = invocationBuilder.get(); 
    if(response.getStatus() == 200){ 
      return response.readEntity(genericType); 
    }else{ 
      ResultMsg<List<GitHubEntity>> res = new ResultMsg<List<GitHubEntity>>(); 
      res.setErrorCode(String.valueOf(response.getStatus())); 
      res.setErrorMsg(response.getStatusInfo().toString()); 
      res.setOK(false); 
      return res; 
    } 
  } 
   
  /** 
   * attention: 
   * Details:根據(jù)id來(lái)刪除一個(gè)記錄 
   * @author chhliu 
   */ 
  public ResultMsg<GitHubEntity> deleteById(final String id) throws JsonProcessingException, IOException{ 
    WebTarget target = client.target("http://localhost:8080").path("/github/delete/"+id); 
    GenericType<ResultMsg<GitHubEntity>> genericType = new GenericType<ResultMsg<GitHubEntity>>(){}; 
    Response response = target.request().delete(); 
    if(response.getStatus() == 200){ 
      return response.readEntity(genericType); 
    }else{ 
      ResultMsg<GitHubEntity> res = new ResultMsg<GitHubEntity>(); 
      res.setErrorCode(String.valueOf(response.getStatus())); 
      res.setErrorMsg(response.getStatusInfo().toString()); 
      res.setOK(false); 
      return res; 
    } 
  } 
   
  /** 
   * attention: 
   * Details:更新一條記錄 
   * @author chhliu 
   */ 
  public ResultMsg<GitHubEntity> update(final GitHubEntity entity) throws JsonProcessingException, IOException{ 
    WebTarget target = client.target("http://localhost:8080").path("/github/put"); 
    GenericType<ResultMsg<GitHubEntity>> genericType = new GenericType<ResultMsg<GitHubEntity>>(){}; 
    Response response = target.request().buildPut(Entity.entity(entity, MediaType.APPLICATION_JSON)).invoke(); 
    if(response.getStatus() == 200){ 
      return response.readEntity(genericType); 
    }else{ 
      ResultMsg<GitHubEntity> res = new ResultMsg<GitHubEntity>(); 
      res.setErrorCode(String.valueOf(response.getStatus())); 
      res.setErrorMsg(response.getStatusInfo().toString()); 
      res.setOK(false); 
      return res; 
    } 
  } 
   
  /** 
   * attention: 
   * Details:插入一條記錄 
   * @author chhliu 
   */ 
  public ResultMsg<GitHubEntity> save(final GitHubEntity entity) throws JsonProcessingException, IOException{  
     WebTarget target = client.target("http://localhost:8080").path("/github/post"); 
     GenericType<ResultMsg<GitHubEntity>> genericType = new GenericType<ResultMsg<GitHubEntity>>(){}; 
     Response response = target.request().buildPost(Entity.entity(entity, MediaType.APPLICATION_JSON)).invoke(); 
     if(response.getStatus() == 200){ 
       return response.readEntity(genericType); 
     }else{ 
      ResultMsg<GitHubEntity> res = new ResultMsg<GitHubEntity>(); 
      res.setErrorCode(String.valueOf(response.getStatus())); 
      res.setErrorMsg(response.getStatusInfo().toString()); 
      res.setOK(false); 
      return res; 
     } 
  } 
} 

Jersey客戶端接口詳解

1 Client接口

創(chuàng)建一個(gè)Client實(shí)例是通過(guò)ClientBuilder構(gòu)造的,通常使用一個(gè)ClientConfig實(shí)例作為參數(shù),如果我們使用Client client = ClientBuilder.newClient()的方式來(lái)創(chuàng)建Client實(shí)例的時(shí)候,每次都會(huì)創(chuàng)建一個(gè)Client實(shí)例,但該實(shí)例是一個(gè)重量級(jí)的對(duì)象,所以,建議使用HTTP連接池的方式來(lái)管理連接,而不是每次請(qǐng)求都去創(chuàng)建一個(gè)Client對(duì)象,具體的連接池管理方式見(jiàn)上面的代碼示例。

2 WebTarget接口

WebTarget接口是為REST客戶端實(shí)現(xiàn)資源定位的接口,通過(guò)WebTarget接口,我們可以定義請(qǐng)求資源的具體地址,查詢參數(shù)和媒體類(lèi)型信息等。我們可以通過(guò)方法鏈的方式完成對(duì)一個(gè)WebTarget實(shí)例的配置,但是需要注意的是,雖然WebTarget的使用方式和StringBuffer的方法鏈方式非常類(lèi)似,但實(shí)質(zhì)是不一樣的,WebTarget的方法鏈必須設(shè)置方法的返回值,作為后續(xù)流程的句柄,這個(gè)是什么意思了,看下面的幾個(gè)示例:

示例1:StringBuffer的方法鏈?zhǔn)纠?/p>

StringBuffer sb = new StringBuffer("lch"); 
     sb.append("hello"); 
     sb.append("world"); 
     sb.append("hello").append("world"); // 這種方式和上面的兩行代碼實(shí)現(xiàn)的效果是一樣的。 

示例2:WebTarget的方法鏈?zhǔn)纠?/p>

// 使用一行代碼的方法鏈來(lái)實(shí)例化WebTarget 
WebTarget webTarget = client.target("http://localhost:8080"); 
webTarget.path("/github/get/users/page") 
  .queryParam("pageOffset", pageOffset) 
  .queryParam("pageSize", pageSize) 
  .queryParam("orderColumn", orderColumn); 
// 下面是分開(kāi)使用方法鏈來(lái)實(shí)例化WebTarget 
webTarget.path("/github/get/users/page"); 
webTarget.queryParam("pageOffset", pageOffset); 
webTarget.queryParam("pageSize", pageSize); 
// 上面兩種實(shí)例化的方式最后產(chǎn)生的結(jié)果大相徑庭,上面的實(shí)例化方式是OK的,沒(méi)有問(wèn)題,下面的實(shí)例化方式卻有問(wèn)題,下面的實(shí)例化方式中,每一行都會(huì)生成一個(gè) 
// 新的WebTarget對(duì)象,原來(lái)的WebTarget并沒(méi)有起任何作用,畢竟每一行的實(shí)例都不一樣,如果我們想要分多行實(shí)例化了,就必須為每個(gè)方法的返回提供一個(gè)句柄,方式如下: 
 
WebTarget target = client.target("http://localhost:8080"); 
WebTarget pathTarget = target.path("/github/get/users/page"); 
WebTarget paramTarget = pathTarget.queryParam("pageOffset", pageOffset); 
 
// 最后使用的時(shí)候,用最后一個(gè)WebTarget實(shí)例對(duì)象即可 

3 Invocation接口

Invocation接口是在完成資源定位配置后,向REST服務(wù)端發(fā)起請(qǐng)求的接口,請(qǐng)求包括同步和異步兩種方式,由Invocation接口內(nèi)部的Builder接口定義,Builder接口繼承了同步接口SyncInvoker,異步調(diào)用的使用示例如下:

Future<ResultMsg<List<GitHubEntity>>> response = invocationBuilder.async().get(genericType); 
 
    if(response.isDone()){ 
      return response.get(); 
    } 

Invocation.Builder接口實(shí)例分別執(zhí)行了GET和POST請(qǐng)求來(lái)提交查詢和創(chuàng)建,默認(rèn)情況下,HTTP方法調(diào)用的返回類(lèi)型是Response類(lèi)型,同時(shí)也支持泛型類(lèi)型的返回值,在上面的示例中,我們使用了大量的泛型,這里就不做過(guò)多的解釋了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java Calendar日歷類(lèi)原理及使用方法

    Java Calendar日歷類(lèi)原理及使用方法

    這篇文章主要介紹了Java Calendar日歷類(lèi)原理及使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java編程接口詳細(xì)

    Java編程接口詳細(xì)

    這篇文章主要小編主要給大家講解的是Java編程中的接口,文章會(huì)從抽象類(lèi)和抽象方法開(kāi)始展開(kāi)內(nèi)容,感興趣的小伙伴可以參考下面文章的具體內(nèi)容
    2021-10-10
  • springboot默認(rèn)掃描的路徑方式

    springboot默認(rèn)掃描的路徑方式

    這篇文章主要介紹了springboot默認(rèn)掃描的路徑方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java高并發(fā)的volatile與Java內(nèi)存模型詳解

    java高并發(fā)的volatile與Java內(nèi)存模型詳解

    這篇文章主要介紹了java高并發(fā)的volatile與Java內(nèi)存模型,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-10-10
  • java集合List快速實(shí)現(xiàn)重復(fù)判斷的方法小結(jié)

    java集合List快速實(shí)現(xiàn)重復(fù)判斷的方法小結(jié)

    在java編寫(xiě)代碼中經(jīng)常會(huì)遇到某些重復(fù)判定或者去重的操作,本文主要為大家介紹了幾個(gè)常用方法,感興趣的小伙伴可以跟隨不想一起學(xué)習(xí)一下
    2024-12-12
  • 用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的布隆過(guò)濾器

    用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的布隆過(guò)濾器

    這篇文章主要介紹了用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的布隆過(guò)濾器,布隆過(guò)濾器是1970年由布隆提出的,它實(shí)際上是一個(gè)很長(zhǎng)的二進(jìn)制向量和一系列隨機(jī)映射函數(shù),布隆過(guò)濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中,需要的朋友可以參考下
    2023-12-12
  • SpringBoot如何使用@Cacheable進(jìn)行緩存與取值

    SpringBoot如何使用@Cacheable進(jìn)行緩存與取值

    這篇文章主要介紹了SpringBoot如何使用@Cacheable進(jìn)行緩存與取值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • idea 有時(shí)提示找不到類(lèi)或者符號(hào)的解決

    idea 有時(shí)提示找不到類(lèi)或者符號(hào)的解決

    這篇文章主要介紹了idea 有時(shí)提示找不到類(lèi)或者符號(hào)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • springboot動(dòng)態(tài)注入配置與docker設(shè)置環(huán)境變量的方法

    springboot動(dòng)態(tài)注入配置與docker設(shè)置環(huán)境變量的方法

    這篇文章主要介紹了springboot動(dòng)態(tài)注入配置與docker設(shè)置環(huán)境變量的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • Java實(shí)現(xiàn)短信驗(yàn)證碼和國(guó)際短信群發(fā)功能的示例

    Java實(shí)現(xiàn)短信驗(yàn)證碼和國(guó)際短信群發(fā)功能的示例

    本篇文章主要介紹了Java實(shí)現(xiàn)短信驗(yàn)證碼和國(guó)際短信群發(fā)功能的示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-02-02

最新評(píng)論

望奎县| 新丰县| 阿拉善盟| 五常市| 宜黄县| 海晏县| 奉贤区| 宁陵县| 新昌县| 敦煌市| 汝州市| 兰西县| 嘉峪关市| 虞城县| 化德县| 九龙县| 山东省| 东至县| 和龙市| 三穗县| 文成县| 浏阳市| 舒城县| 荆州市| 邹城市| 蓬溪县| 嵊州市| 正安县| 梨树县| 绥德县| 张家界市| 咸丰县| 句容市| 松潘县| 阿尔山市| 大港区| 十堰市| 中山市| 宜兰市| 佛学| 石屏县|