zoukankan      html  css  js  c++  java
  • Spring

    21.9 Accessing RESTful services on the Client

    (见:Spring Doc - RestTemplate

    The RestTemplate is the core class for client-side access to RESTful services. It is conceptually similar to other template classes in Spring, such as JdbcTemplate and JmsTemplate and other template classes found in other Spring portfolio projects. RestTemplate's behavior is customized by providing callback methods and configuring the HttpMessageConverter used to marshal objects into the HTTP request body and to unmarshal any response back into an object. As it is common to use XML as a message format, Spring provides a MarshallingHttpMessageConverter that uses the Object-to-XML framework that is part of the org.springframework.oxm package. This gives you a wide range of choices of XML to Object mapping technologies to choose from.

    This section describes how to use the RestTemplate and its associated HttpMessageConverters.

    21.9.1 RestTemplate

    Invoking RESTful services in Java is typically done using a helper class such as Jakarta Commons HttpClient. For common REST operations this approach is too low level as shown below.

    String uri = "http://example.com/hotels/1/bookings";
    
    PostMethod post = new PostMethod(uri);
    String request = // create booking request content
    post.setRequestEntity(new StringRequestEntity(request));
    
    httpClient.executeMethod(post);
    
    if (HttpStatus.SC_CREATED == post.getStatusCode()) {
      Header location = post.getRequestHeader("Location");
      if (location != null) {
        System.out.println("Created new booking at :" + location.getValue());
      }
    }

    RestTemplate provides higher level methods that correspond to each of the six main HTTP methods that make invoking many RESTful services a one-liner and enforce REST best practices.

    Table 21.1. Overview of RestTemplate methods:

    HTTP Method RestTemplate Method
    DELETE delete
    GET getForObject
      getForEntity
    HEAD headForHeaders(String url, String… urlVariables)
    OPTIONS optionsForAllow(String url, String… urlVariables)
    POST postForLocation(String url, Object request, String… urlVariables)
      postForObject(String url, Object request, Class<T> responseType, String… uriVariables)
    PUT put(String url, Object request, String…urlVariables)

    The names of RestTemplate methods follow a naming convention, the first part indicates what HTTP method is being invoked and the second part indicates what is returned. For example, the method getForObject() will perform a GET, convert the HTTP response into an object type of your choice and return that object. The method postForLocation() will do a POST, converting the given object into a HTTP request and return the response HTTP Location header where the newly created object can be found. In case of an exception processing the HTTP request, an exception of the type RestClientException will be thrown; this behavior can be changed by plugging in another ResponseErrorHandler implementation into the RestTemplate.

    Objects passed to and returned from these methods are converted to and from HTTP messages by HttpMessageConverter instances. Converters for the main mime types are registered by default, but you can also write your own converter and register it via the messageConverters() bean property. The default converter instances registered with the template are ByteArrayHttpMessageConverterStringHttpMessageConverterFormHttpMessageConverter and SourceHttpMessageConverter. You can override these defaults using the messageConverters() bean property as would be required if using the MarshallingHttpMessageConverter or MappingJackson2HttpMessageConverter.

    Each method takes URI template arguments in two forms, either as a String variable length argument or a Map<String,String>. For example,

    String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}", String.class,"42", "21");

    using variable length arguments and

    Map<String, String> vars = Collections.singletonMap("hotel", "42");
    String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);

    using a Map<String,String>.

    To create an instance of RestTemplate you can simply call the default no-arg constructor. This will use standard Java classes from the java.net package as the underlying implementation to create HTTP requests. This can be overridden by specifying an implementation of ClientHttpRequestFactory. Spring provides the implementation HttpComponentsClientHttpRequestFactory that uses the Apache HttpComponents HttpClient to create requests. HttpComponentsClientHttpRequestFactory is configured using an instance of org.apache.http.client.HttpClient which can in turn be configured with credentials information or connection pooling functionality.

    [Tip]

    Note that the java.net implementation for HTTP requests may raise an exception when accessing the status of a response that represents an error (e.g. 401). If this is an issue, switch to HttpComponentsClientHttpRequestFactory instead.

    The previous example using Apache HttpComponents HttpClient directly rewritten to use the RestTemplate is shown below

    uri = "http://example.com/hotels/{id}/bookings";
    RestTemplate template
    = new RestTemplate();
    Booking booking
    = // create booking object
    URI location = template.postForLocation(uri, booking, "1");

    The general callback interface is RequestCallback and is called when the execute method is invoked.

    public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor, String... urlVariables)
    
    // also has an overload with urlVariables as a Map<String, String>.

    The RequestCallback interface is defined as

    public interface RequestCallback {
     void doWithRequest(ClientHttpRequest request) throws IOException;
    }

    and allows you to manipulate the request headers and write to the request body. When using the execute method you do not have to worry about any resource management, the template will always close the request and handle any errors. Refer to the API documentation for more information on using the execute method and the meaning of its other method arguments.

    Working with the URI

    For each of the main HTTP methods, the RestTemplate provides variants that either take a String URI or java.net.URI as the first argument.

    The String URI variants accept template arguments as a String variable length argument or as a Map<String,String>. They also assume the URL String is not encoded and needs to be encoded. For example the following:

    restTemplate.getForObject("http://example.com/hotel list", String.class);

    will perform a GET on http://example.com/hotel%20list. That means if the input URL String is already encoded, it will be encoded twice -- i.e. http://example.com/hotel%20list will become http://example.com/hotel%2520list. If this is not the intended effect, use the java.net.URI method variant, which assumes the URL is already encoded is also generally useful if you want to reuse a single (fully expanded) URI multiple times.

    The UriComponentsBuilder class can be used to build and encode the URI including support for URI templates. For example you can start with a URL String:

    UriComponents uriComponents =
            UriComponentsBuilder.fromUriString("http://example.com/hotels/{hotel}/bookings/{booking}").build()
                .expand("42", "21")
                .encode();
    
    URI uri = uriComponents.toUri();

    Or specify each URI component individually:

    UriComponents uriComponents =
            UriComponentsBuilder.newInstance()
                .scheme("http").host("example.com").path("/hotels/{hotel}/bookings/{booking}").build()
                .expand("42", "21")
                .encode();
    
    URI uri = uriComponents.toUri();

    Dealing with request and response headers

    Besides the methods described above, the RestTemplate also has the exchange() method, which can be used for arbitrary HTTP method execution based on the HttpEntity class.

    Perhaps most importantly, the exchange() method can be used to add request headers and read response headers. For example:

    HttpHeaders requestHeaders = new HttpHeaders();
    requestHeaders.set("MyRequestHeader", "MyValue");
    HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
    
    HttpEntity<String> response = template.exchange("http://example.com/hotels/{hotel}",
      HttpMethod.GET, requestEntity, String.class, "42");
    
    String responseHeader = response.getHeaders().getFirst("MyResponseHeader");
    String body = response.getBody();

    In the above example, we first prepare a request entity that contains the MyRequestHeader header. We then retrieve the response, and read the MyResponseHeader and body.

    21.9.2 HTTP Message Conversion

    Objects passed to and returned from the methods getForObject()postForLocation(), and put() are converted to HTTP requests and from HTTP responses by HttpMessageConverters. The HttpMessageConverter interface is shown below to give you a better feel for its functionality

    public interface HttpMessageConverter<T> {
    
          // Indicate whether the given class and media type can be read by this converter.
          boolean canRead(Class<?> clazz, MediaType mediaType);
    
          // Indicate whether the given class and media type can be written by this converter.
          boolean canWrite(Class<?> clazz, MediaType mediaType);
    
          // Return the list of MediaType objects supported by this converter.
          List<MediaType> getSupportedMediaTypes();
    
          // Read an object of the given type from the given input message, and returns it.
          T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
    
          // Write an given object to the given output message.
          void write(T t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
    
        }

    Concrete implementations for the main media (mime) types are provided in the framework and are registered by default with the RestTemplate on the client-side and with AnnotationMethodHandlerAdapter on the server-side.

    The implementations of HttpMessageConverters are described in the following sections. For all converters a default media type is used but can be overridden by setting the supportedMediaTypes bean property

    StringHttpMessageConverter

    An HttpMessageConverter implementation that can read and write Strings from the HTTP request and response. By default, this converter supports all text media types (text/*), and writes with a Content-Type of text/plain.

    FormHttpMessageConverter

    An HttpMessageConverter implementation that can read and write form data from the HTTP request and response. By default, this converter reads and writes the media type application/x-www-form-urlencoded. Form data is read from and written into a MultiValueMap<String, String>.

    ByteArrayHttpMessageConverter

    An HttpMessageConverter implementation that can read and write byte arrays from the HTTP request and response. By default, this converter supports all media types (*/*), and writes with a Content-Type of application/octet-stream. This can be overridden by setting the supportedMediaTypes property, and overriding getContentType(byte[]).

    MarshallingHttpMessageConverter

    An HttpMessageConverter implementation that can read and write XML using Spring's Marshaller and Unmarshaller abstractions from the org.springframework.oxm package. This converter requires a Marshaller and Unmarshaller before it can be used. These can be injected via constructor or bean properties. By default this converter supports (text/xml) and (application/xml).

    MappingJackson2HttpMessageConverter (or MappingJacksonHttpMessageConverter with Jackson 1.x)

    An HttpMessageConverter implementation that can read and write JSON using Jackson's ObjectMapper. JSON mapping can be customized as needed through the use of Jackson's provided annotations. When further control is needed, a custom ObjectMapper can be injected through the ObjectMapper property for cases where custom JSON serializers/deserializers need to be provided for specific types. By default this converter supports (application/json).

    SourceHttpMessageConverter

    An HttpMessageConverter implementation that can read and write javax.xml.transform.Source from the HTTP request and response. Only DOMSourceSAXSource, and StreamSource are supported. By default, this converter supports (text/xml) and (application/xml).

    BufferedImageHttpMessageConverter

    An HttpMessageConverter implementation that can read and write java.awt.image.BufferedImage from the HTTP request and response. This converter reads and writes the media type supported by the Java I/O API.

     以下内容转载于:RestTemplate实践(及遇到的问题)

    零、RestTemplate简述?

    spring boot内嵌了专门的单元测试模块——RestTemplate,避免了自己写JDK原生的URLConnection、或Apache的Http Client方法,保证了程序员可以对自己的代码进行及时的测试。

    RestTemplate可以用GET方法来获取资源,或者用POST方法来创建资源。

    一、什么是RestTemplate?

    RestTemplate是Spring提供的用于访问Rest服务的客户端(springboot依赖于spring)。

    RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

    调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用java.net包下的实现创建HTTP 请求。

    可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式。ClientHttpRequestFactory接口主要提供了两种实现方式:

    1、一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接。

    2、一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。

    二、常用的方法:

    1.getForEntity方法的返回值是一个ResponseEntity<T>ResponseEntity<T>是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。

    2.getForObject函数实际上是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时可以使用getForObject

    3.postForEntity 和getForEntity类似

    4.postForObject 如果只关注,返回的消息体,可以直接使用postForObject。用法和getForObject一致

    5.postForLocation也是提交新资源,提交成功之后,返回新资源的URI,postForLocation的参数和前面两种的参数一致,只不过返回值为Uri,只需要服务提供者返回一个Uri即可,该Uri表示新资源的位置。

    6.其他的还有put(),delete()都不怎么常用

    RestTemplate的核心之一 Http Client。

    目前通过RestTemplate 的源码可知,RestTemplate 可支持多种 Http Client的http的访问,如下所示:

    基于 JDK HttpURLConnection 的 SimpleClientHttpRequestFactory,默认。

    基于 Apache HttpComponents Client 的 HttpComponentsClientHttpRequestFactory

    基于 OkHttp3的OkHttpClientHttpRequestFactory。

    基于 Netty4 的 Netty4ClientHttpRequestFactory。

    其中HttpURLConnection 和 HttpClient 为原生的网络访问类,OkHttp3采用了 OkHttp3的框架,Netty4 采用了Netty框架。

    具体参见:RestTemplate实践(及遇到的问题)



    http://blog.csdn.net/qwe6112071/article/details/51042634

    https://blog.csdn.net/qwe6112071/article/details/51039511

    https://blog.csdn.net/lycz_tpself/article/details/76825162

    https://www.cnblogs.com/chenligeng/p/10784584.html

    https://www.cnblogs.com/daimajun/p/7152970.html

    https://blog.csdn.net/apache_ant/article/details/103653658

    https://blog.csdn.net/qq_29569183/article/details/80540618

    https://blog.csdn.net/weixin_30668887/article/details/99488906

    https://blog.csdn.net/showadwalker/article/details/88238451

     参考文献:

    1.Spring Doc - RestTemplate

    2.Spring - RestTemplate postForObject方法详解

    3.简单记录下RestTemplate 中postForObject调用例子

    4.初探RestTemplate--postForObject方法直接传递对象

    5.spring boot单元测试之RestTemplate(一)

    6.The Guide to RestTemplate

    7.RestTemplate实践(及遇到的问题)

  • 相关阅读:
    JS 检查是否在微信浏览器
    php如何判断文件是否存在,包括本地和远程文件
    SQL 截取字段空格之前的数据
    JS 上拉加载
    struts2项目需要加入的jar包
    eclipse+maven+jetty环境下修改了文件需要重启才能修改成功
    根据父节点查询出所有的子节点
    oracle中,行转列函数wm_concat()结果有长度限制,重写该函数解决
    乱码!Eclipse 的控制台console必须用GBK编码。
    webpack 入门和常用插件的使用
  • 原文地址:https://www.cnblogs.com/HarryVan/p/13791856.html
Copyright © 2011-2022 走看看