Spring - RestTemplate postForObject方法详解

简介

RestTemplate是Spring的模板类,在客户端上可以使用该类调用Web服务器端的服务,它支持REST风格的URL。在Spring中有许多类似功能的类,如JdbcTemplate, JmsTemplate等。
RestTemplate可以用GET方法来获取资源,或者用POST方法来创建资源。

postForObject

1. post HttpEntity

postForObject本质上是将对象放入HttpEntity中,然后将对象POST给一个url,下面代码中所示的使用方法是最典型的一种:

ClientHttpRequestFactory requestFactory = getClientHttpRequestFactory();
RestTemplate restTemplate = new RestTemplate(requestFactory);
 
HttpEntity request = new HttpEntity<>(new Foo("bar"));//将对象装入HttpEntity中
Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class);
2. post JavaObject

实际上,如果不人为的将对象放入HttpEntity中,也可以直接使用RestTemplate去POST一个对象:

Foo foo = new Foo("bar");
Foo foo = restTemplate.postForObject(fooResourceUrl, foo, Foo.class);

可以这么做的原因是,在RestTemplate的代码中,专门有一部分进行了POST对象的类型检测和转换 :

            if (requestBody instanceof HttpEntity) {
                this.requestEntity = (HttpEntity) requestBody;
            }
            else if (requestBody != null) {
                this.requestEntity = new HttpEntity(requestBody);
            }
            else {
                this.requestEntity = HttpEntity.EMPTY;
            }
 
 
3. post JSON

如果需要post的对象是以JSON形式存储,则需要手动将JSON字符串转化成HttpEntity,具体做法如下:

String jsonString = "{\"id\":10,\"name\":\"test\"}";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
HttpEntity strEntity = new HttpEntity(jsonString,headers);

RestTemplate restTemplate = new RestTemplate();
Foo foo = restTemplate.postForObject(url,strEntity,Foo.class);
System.out.println(jo2);

URI编码注意事项

无论是GET还是POST,RestTemplate的方法的第一个参数是String URI或java.net.URI类型,需要注意的是:

1. 编码(encode)

URI涉及到编码问题,是因为有些字符会引起歧义。比如参数中的key=value键值对,当value里含有= & ? 等,就会造成 URL 服务器的解析错误。所以必须将引起歧义的符号进行转义,也就是对其进行编码。

如果使用String URI,那么其默认是不编码的,例如:

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

RestTemplate会将URI转化成http://example.com/hotel%20list,而如果画蛇添足的向RestTemplate方法中传入一个encode的String URI:

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

那么该URI将会被加密两次,成为http://example.com/hotel%2520list,而java.net.URI默认是编码的,RestTemplate默认是不编码的。

2. java.net.URI的使用

因为java.net.URI提供了多种常用的URI加工方法,如果要多次使用同一个url,最好将其转化成java.net.URI

参考文献:
The Guide to RestTemplate
Java测试-RestTemplate-@requestBody
Spring Doc - RestTemplate

你可能感兴趣的:(Spring - RestTemplate postForObject方法详解)