"Spring-web" resttemplate Source Learning

Source: Internet
Author: User

2016-12-22 by quiet snowy days http://www.cnblogs.com/quiet-snowy-day/p/6210288.htmlIn the Web development work, a part of the development task is not to write Web pages. For example, when a local service integrates some third-party functionality (access to other restful resources), the response is obtained by forwarding a URL request to a third-party service. These responses do not need to be rendered to the screen, but are returned to the client (app or other web app). A local service is a client for a third-party service, and for a whole system it is like a transit point.
This development in addition to the business logic, the rest of the basic is the routine code, and spring from the 3.0 version, provides us with the encapsulated good access to HTTP template code resttemplate. look at the company's several sets of service code, are their own package of Httpclient\httprequest\httpresponse, packaged code and there is nothing special, do not understand why not use the framework provided by the class. Moreover, basically every project has a duplicate implementation of the package code, I asked the manager is not to make a jar package reference more convenient, the manager said he did not like to refer to the jar. ? Is you just kidding me?
Would also like to put forward some suggestions for improvement, but now the system can run smoothly, consider or forget. Hehe ———— Although these services are gradually added with the business, it is not possible to design so perfect at the outset, but I really can't help but want to vomit groove. In comparison with the previous company, we really feel that we need to strengthen the Code specification and technical management. Practice using a resttemplate, by the way learn spring source code. Let's take a look at Java Doc
/*** <strong>spring ' s Central class for synchronous client-side HTTP access.</strong> * It simplifies commun Ication with HTTP servers, and enforces RESTful principles. * It handles HTTP connections, leaving application code to provide URLs * (with possible template variables) and extract R Esults. * * <p><strong>Note:</strong> By default the Resttemplate relies in the JDK * facilities to Establi SH HTTP connections. You can switch to use a different * HTTP library such as Apache httpcomponents, Netty, and OkHttp through the * {@link#setRequestFactory} property.  * * <p>the Main entry points of this template is the methods named after the six main HTTP methods: * <table> * <tr><th>http method</th><th>resttemplate methods</th></tr> * <TR><TD >delete</td><td>{@link#delete}</td></tr> * <tr><td>get</td><td>{@link#getForObject}</td></tr> * <tr><td></td><td>{@link#getForEntity}</td></tr> * <tr><td>head</td><td>{@link#headForHeaders}</td></tr> * <tr><td>options</td><td>{@link#optionsForAllow}</td></tr> * <tr><td>post</td><td>{@link#postForLocation}</td></tr> * <tr><td></td><td>{@link#postForObject}</td></tr> * <tr><td>put</td><td>{@link#put}</td></tr> * <tr><td>any</td><td>{@link#exchange}</td></tr> * <tr><td></td><td>{@link#execute}</td></tr> </table> * * <p>in addition the {@codeExchange} and {@codeExecute} Methods is generalized versions of * The above methods and can be used to support additional, less frequent combinations (e.g. * http PATCH, HTTP PUT with response body, etc.). Note however the underlying HTTP * library used must also support the desired combination.  * * <p>for Each HTTP method there is three variants:two accept a URI template string * and URI variables (array or MAP) While a third accepts a {@linkURI}. * Note that for URI templates it was assumed encoding is necessary, e.g. *@codeResttemplate.getforobject ("Http://example.com/hotellist ")} becomes * {@code "http://example.com/hotel%20list"}. This also means if the URI template * or URI variables is already encoded, double encoding would occur, e.g. * {@code http://example.com/hotel%20list} becomes * {@code http://example.com/hotel%2520list}). To avoid this use a {@codeURI} Method * Variant to provide (or re-use) a previously encoded URI. To prepare such a URI * with Full control over encoding, consider using * {@linkOrg.springframework.web.util.UriComponentsBuilder}. * * <p>internally the template uses {@linkHttpmessageconverter} instances to * Convert HTTP messages to and from POJOs. Converters for the main MIME types * is registered by default but can also register additional converters * via {@link#setMessageConverters}. * * <p>this template uses a * {@linkOrg.springframework.http.client.SimpleClientHttpRequestFactory} and a * {@linkDefaultresponseerrorhandler} As default strategies for creating HTTP * connections or handling HTTP errors, Respectiv Ely. These defaults can be overridden * through {@link#setRequestFactory} and {@link#setErrorHandler} respectively. * * @authorArjen Poutsma *@authorBrian Clozel *@authorRoy Clarkson *@authorJuergen Hoeller *@since3.0 *@seeHttpmessageconverter *@seeRequestcallback *@seeResponseextractor *@seeResponseerrorhandler *@seeasyncresttemplate*/
Java DocTry translating as follows: Resttemplate is The core class for client synchronous access to HTTP in spring. It simplifies communication with the HTTP server and executes the restful principle. It can handle HTTP links, delegate application code (using appropriate template variables) to assemble URLs, and extract response information. Note:By default, Resttemplate relies on standard JDK tools to create HTTP links. By setting the (Httpaccessor.setrequestfactory) property, you can instead use an HTTP library such as Apache Httpcomponents, Netty, and Okhttp. The main entry point for this template class is the following methods (and corresponding to the six main methods of HTTP): In addition, the Exchange and execute methods provide a generic version of the above methods to support additional, infrequently used combinations such as HTTP patches, HTTP PUT with the body of the message, And so on). Note that no matter how you use the underlying HTTP library, you must support the necessary combinations. There are 3 variants for each HTTP method: two of which receive parameters are URI pattern strings and URI variables (array or map), and the third receive parameter is Java.net.URI. Note that the encoding format needs to be assumed for the URI pattern string, such as: Resttemplate.getforobject ("Http://example.com/hotel List") becomes"Http://example.com/hotel%20list"。 This also means that if the URI pattern string or URI variable is encoded, duplicate encoding is generated, such as:"Http://example.com/hotel%20list"Become a"Http://example.com/hotel%2520list"。 To avoid using URI method variants to provide (or reuse) a pre-encoded URI, consider using Uricomponentsbuilder to develop a URI that can fully control the encoding. Use Httpmessageconverter instances inside the template to convert HTTP messages to and from the Pojo class. The main MIME-type converters are already registered by default, and you can also register additional converters with the Setmessageconverters (list

How do you choose to overload 3 methods? It is recommended that you choose the two method with the URL parameter type string. Because when this parameter is a non-URI format, a conversion is required, and the Uri constructor throws a check exception urisyntaxexception, which must be caught. The other two overloaded methods avoid catching exceptions, so the first parameter of the recommended method in the table above is a string type.

Wrote two test methods, bloggers like to use JUnit ?
 PackageCom.practice;ImportJava.net.URLEncoder;ImportJava.util.HashMap;ImportJava.util.Map;Importjunit.framework.TestCase;ImportNet.sf.json.JSONObject;ImportOrg.junit.Before;Importorg.junit.Test;Importorg.springframework.http.HttpEntity;Importorg.springframework.http.ResponseEntity;ImportOrg.springframework.util.LinkedMultiValueMap;ImportOrg.springframework.util.MultiValueMap;Importorg.springframework.web.client.RestTemplate; Public classResttemplatetestextendsTestCase {resttemplate resttpl; @Before Public voidsetUp () {RESTTPL=Newresttemplate (); } @Test Public voidTestget () {Map<string, object> paramsmap =NewHashmap<string, object>(); Paramsmap.put ("Citycode", "xxxxxxxxxx"); Paramsmap.put ("Key", "xxxxxxxxxxxxxxxxxxxxx"); String URL= "Http://xxx.xxx.xxx.xxx:8080/xxx/xxxx?xxxx&config=xxx&citycode={citycode}&key={key}"; String Respstr= Resttpl.getforobject (URL, String.class, Paramsmap);        System.out.println (RESPSTR); Jsonobject Respjson= Resttpl.getforobject (URL, jsonobject.class, Paramsmap);    System.out.println (Respjson); } @Test Public voidTestpost ()throwsException {String PostURL= "Http://xxx.xxx.xxx.xxx:8080/xxxx/xxxx/xxxxx"; Jsonobject metadata=NewJsonobject (); Metadata.put ("DDDDDD", "xxxxx"); Metadata.put ("Ssssss", "xxxxxx"); Metadata.put ("Flag",true); Jsonobject Paramsjson=NewJsonobject (); Paramsjson.put ("Mmmmm", "MMM"); Paramsjson.put ("NNNNN", "nnn"); Paramsjson.put ("Password", "xxxxxxxxxxx"); Paramsjson.put ("Metadata", metadata); String params= "requestjson=" + Urlencoder.encode (paramsjson.tostring (), "Utf-8"); Multivaluemap<string, string> headers =NewLinkedmultivaluemap<string, string>(); Headers.add ("Content-type", "application/x-www-form-urlencoded; Charset=utf-8 "); Httpentity<Object> hpentity =NewHttpentity<object>(params, headers); Responseentity<String> respentity = resttpl.postforentity (PostURL, hpentity, String.class);    System.out.println (respentity); }}
View Code

However, it is just a few lines of code that are constantly making mistakes ~~~~~~~

Before the second parameter of the Postforentity method (the type of the request message body) used the Jsonobject object directly, the following error occurred, the Spring-web source was viewed, Find the version of the Jackson-databind package referenced in the source project is 2.8.1. After changing the jar package version, you can continue running. However, again wrong, see. This time is because the request information is incomplete, the test service side to the post message body format has the request, but I did not set Content-type, the request header information onlyAcceptAndContent-length TwoItem Create the Map object and set the header information, use Httpentity as the sending object, and finally successfully executed.

So, how does the resttemplate handle the request header information?

Take the Get method as an example, the Getforobject () method has such a sentence "Requestcallback requestcallback = Acceptheaderrequestcallback (Responsetype);" The Acceptheaderrequestcallback method returns an instance of the Acceptheaderrequestcallback class. Acceptheaderrequestcallback is an internal class of resttemplate that implements the Requestcallback interface, which has only one method Dowithrequest. Acceptheaderrequestcallback implements the Dowithrequest method: Traverse all the message converters according to the response entity type Responsetype, find the appropriate, and then find all the supported media types from these converters. Finally, all supported media types are set to the request header accept. Looking again at the Post method, there is "requestcallback requestcallback = httpentitycallback (Request, Responsetype) in the Postforentity () method; The Httpentitycallback method returns an instance of the Httpentityrequestcallback class. Httpentityrequestcallback is also the inner class of Resttemplate, which inherits the Acceptheaderrequestcallback class, Rewrite the Dowithrequest method: First call the parent class Dowithrequest method, complete the request header setting, then, according to the response entity type, through the traversal to find the appropriate message converter, and finally through the message converter to write the post message body into the request entity.

Why do we use internal classes here? Review the role of the inner class.

1. The implementation details are hidden. Acceptheaderrequestcallback and Httpentityrequestcallback are restricted to private; In addition, interfaces are implemented in the inner class, not by the Resttemplate class implement Multiple interfaces, it avoids exposing the dowithrequest method to external callers and its implementation. 2. The inner class can access all the elements of the containing class. The member variable messageconverters of the Resttemplate class is accessed in the Dowithrequest method of the inner class, which is a list of all message converters. 3. Multiple inheritance, here is an inheritance relationship between the inner classes, but also indirect multiple inheritance? The Resttemplate class inherits the Interceptinghttpaccessor class and implements the Restoperations interface. 4. Avoid unnecessary modifications due to the parent class and the method that implements the duplicate name in the interface. This is not obvious, Resttemplate inheritance class and two interfaces do not have the same name method. How are request and response message parsing resolved? Is there a design pattern in use? Resttemplate is sending a synchronous request, how is the asynchronous request handled? It feels like the pit is digging deeper, it takes time to take a good look ... Don't worry blog no content to write: P

"Spring-web" resttemplate Source Learning

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.