zoukankan      html  css  js  c++  java
  • Spring之在客户端访问RESTful业务

    Spring之在客户端访问RESTful业务 

    RestTemplate 是客户端访问RESTful业务的核心类。在概念上与Spring其他的模板类相似,比如JdbcTemplate和JmsTemplate。RestTemplate的行为是可以定制的,通过提供回调方法和配置HttpMessageConverter(用于将对象打包到HTTP请求体中并从返回的响应中解压为一个对象)。由于一般使用XML作为消息格式,Spring提供了MarshallingHttpMessageConverter 使用对象到XML的框架,这是org.springframework.oxm包的一部分。这个给你了将XML映射为对象,提供了宽泛的选择。

    这节描述了如何使用RestTemplate和其关联的HttpMessageConverters。

    21.10.1 RestTemplate

    Java中调用RESTful业务,一般使用一个辅助类,比如Apache的HttpComponents  HttpClient。对于普通的REST操作,这种方式是非常低级的。

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. String uri = "http://example.com/hotels/1/bookings";  
    2.   
    3. PostMethod post = new PostMethod(uri);  
    4. String request = // create booking request content  
    5. post.setRequestEntity(new StringRequestEntity(request));  
    6.   
    7. httpClient.executeMethod(post);  
    8.   
    9. if (HttpStatus.SC_CREATED == post.getStatusCode()) {  
    10.     Header location = post.getRequestHeader("Location");  
    11.     if (location != null) {  
    12.         System.out.println("Created new booking at :" + location.getValue());  
    13.     }  
    14. }  

    RestTemplate提供了高级方法,对应着六个主要的HTTP方法,使得在一行中调用RESTful业务并执行REST最好的实践。

    注意:RestTemplate还有一个异步部分。

    RestTemplate 方法回顾表

    HTTP方法         RestTemplate方法

    DELETE           delete

    GET              getForObjectgetForEntity

    HEAD             headForHeaders(String url,String。。。urlVariables)

    OPTIONS          optionsForAllow(String url,String。。。urlVariables)

    POST             postForLocation(String url,Object request,String。。。urlVariables)  postForObeject(String url,Object    request,Class<T> responseType,String...uriVariables)

    PUT              put(String url,Object reuqest,String...urlVariables)

    PATCH and others  exchange execute

    RestTemplate方法的名字遵循一个命名规范,第一部分指定了调用什么HTTP方法,第二部分指明了返回值。例如,getForObject()方法执行一个GET,并将HTTP响应转为你想要的对象类型并返回这个对象。postForLocation()方法执行一个POST操作,将给定的对象转为一个HTTP请求并返回HTTP响应的location头,这里可以找到最新的对象。在处理HTTP请求的异常情形下,将抛出RestClientException异常类型;可以通过将ResponseErrorHandler实现插入到RestTemplate可以改变这种异常处理的行为。

    exchange和execute方法是上述列表指定的方法的泛化版本并且支持其他的结合和方法,比如HTTP PATCH。然而,底层的HTTP也必须支持想得到的联合。JDK的HttpURLConnection 不支持PATCH方法,但是了Apache HttpComponents HttpClient的4.2版本或者后面的会支持。它们也使得RestTemplate读HTTP响应到一个一般的类型(比如List<Account>)),使用一个ParameterizedTypeReference,这是一个新类用来抓取和传递一般类型信息。

    传递给这些方法的对象和从这些方法返回的对象由HttpMessageConverter实例转化和从消息转化。主要类型的转换器是默认注册的,但是了你也可以封装你自己的转换器并使用messageConverters()的bean属性注册。与这个模板注册的默认转换器实例是ByteArrayHttpMessageConverter,StringHttpMessageConverter,FormHttpMessageConverter和SourceHttpMessageConverter。你可以使用messageConverters()bean属性重写这些默认的,尤其是当使用MarshallingHttpMessageConverter或MappingJackson2HttpMessageConverter时重写就是必须的了。

    每个方法传递URI模板参数,用两种方式,要不String变量长度参数,要不Map<String,String>. 例如:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. String result = restTemplate.getForObject(  
    2.         "http://example.com/hotels/{hotel}/bookings/{booking}", String.class,"42", "21");  

    上述使用的变量长度参数,

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. Map<String, String> vars = Collections.singletonMap("hotel", "42");  
    2. String result = restTemplate.getForObject(  
    3.         "http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);  

    这使用的是Map<String,String>.

    为创建一个RestTemplate实例,你可以仅调用缺省的构造器。这将使用来自java.net包中的标准Java类,做实现HTTP请求的底层实现。这个可以通过指定ClientHttpRequestFactory实现来重写。Spring提供了HttpComponentsClientHttpRequestFactory 工厂类,使用Apache HttpComponents HttpClient  创建请求。HttpComponentsClientHttpRequestFactory使用org.apache.http.client.HttpClient的实例配置,反过来使用证书信息或者连接池功能配置。

    注意:

        java.net实现HTTP请求时,可能产生一个异常,当访问响应状态时,这代表了一个错误。如果这是一个问题,转为使用HttpComponentsClientHttpRequestFactory  

    前面的例子使用Apache HttpComponents HttpClient直接重写,并使用下面显示的RestTemplate:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. uri = "http://example.com/hotels/{id}/bookings";  
    2.   
    3. RestTemplate template = new RestTemplate();  
    4.   
    5. Booking booking = // create booking object  
    6.   
    7. URI location = template.postForLocation(uri, booking, "1");  


    为使用Apache HttpComponents 而不是本地的java.net功能,构造如下的RestTemplate :

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());  


    注意:Apache HttpClient支持gzip编码。为使用它,构造了HttpComponentsClientHttpRequestFactory工厂类,如下所示:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. HttpClient httpClient = HttpClientBuilder.create().build();  
    2. ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);  
    3. RestTemplate restTemplate = new RestTemplate(requestFactory);  


    一般的回调接口是RequestCallback 并当调用执行方法时调用

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,  
    2.         ResponseExtractor<T> responseExtractor, String... urlVariables)  
    3.   
    4. // also has an overload with urlVariables as a Map<String, String>.  


    RequestCallback接口定义如下:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. public interface RequestCallback {  
    2.  void doWithRequest(ClientHttpRequest request) throws IOException;  
    3. }  

    允许你操作请求头并写到请求体中。当使用execute方法时,你不必担心任何资源管理,模板将总是关闭请求并处理任何错误。

     

    使用URI working with URI

    对于每个主要的HTTP方法,RestTemplate提供了String类型的URI或者java.net.URI实例的变量作为第一个参数。

    String URI变量接受模板参数作为一个String变量长度参数或者作为一个Map<String,String>。它们也假设URL String类型是不编码的并且需要编码。例子如下:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. restTemplate.getForObject("http://example.com/hotel list", String.class);  

    将在http://example.com/hotel%20list上执行一个GET请求。这意味着如果你输入String类型的已经编码的URL,其将再编码一次。即http://example.com/hotel%20list将被变为http://example.com/hotel%2520list。如果这不是我们想要的结果,使用java.net.URI方法变量,其假设已经编码的url是有用的,如果你想多次使用一个单一的URI。

     

    UriComponentsBuilder这个类能用于构建和编码URI,包括支持URI模板。例如,你可以以一个String类型的url开始。

     

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. UriComponents uriComponents = UriComponentsBuilder.fromUriString(  
    2.         "http://example.com/hotels/{hotel}/bookings/{booking}").build()  
    3.         .expand("42", "21")  
    4.         .encode();  
    5.   
    6. URI uri = uriComponents.toUri();  

    或者分别指定每个URI组件:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. UriComponents uriComponents = UriComponentsBuilder.newInstance()  
    2.         .scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build()  
    3.         .expand("42", "21")  
    4.         .encode();  
    5.   
    6. URI uri = uriComponents.toUri();  

    请求和响应头的处理

    除了上述的方法外,RestTemplate也有exchange()方法,能用于基于HttpEntity类的任何HTTP方法的执行。

    也许更加重要的是,exchange()这个方法可以用于添加请求和响应头。例如:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. HttpHeaders requestHeaders = new HttpHeaders();  
    2. requestHeaders.set("MyRequestHeader", "MyValue");  
    3. HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);  
    4.   
    5. HttpEntity<String> response = template.exchange(  
    6.         "http://example.com/hotels/{hotel}",  
    7.         HttpMethod.GET, requestEntity, String.class, "42");  
    8.   
    9. String responseHeader = response.getHeaders().getFirst("MyResponseHeader");  
    10. String body = response.getBody();  


    在上述的例子中,我们首先准备了一个请求,其包含了MyRequestHeader头信息。稍后我们检索了对应的响应,并读了MyResponseHeader和消息体。

    Jackson JSON 视图支持

    可能指定一个Jackson JSON View序列化对象属性子集。例如:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. JacksonSerializationValue jsv = new JacksonSerializationValue(new User("eric", "7!jd#h23"),  
    2.     User.WithoutPasswordView.class);  
    3. HttpEntity<JacksonSerializationValue> entity = new HttpEntity<JacksonSerializationValue>(jsv);  
    4. String s = template.postForObject("http://example.com/user", entity, String.class);  

    本文转自:http://blog.csdn.net/luccs624061082/article/details/40893963

  • 相关阅读:
    Python脚本传參和Python中调用mysqldump
    金蝶K3管理软件PDA条码解决方式,盘点机与金蝶K3无缝对接
    android设置中的Preferencescreen使用方法介绍与分析
    设计模式之6大原则(3)-依赖倒置原则
    C# DataTable的詳細使用方法
    C++学习笔记13-类继承
    hdu1023
    Haskell 差点儿无痛苦上手指南
    三角形、长方形、正方形、梯形、圆等的周长计算公式和面积计算公式
    (黑客游戏)HackTheGame1.21 过关攻略
  • 原文地址:https://www.cnblogs.com/Rozdy/p/4630916.html
Copyright © 2011-2022 走看看