文章目录
  1. 1. 概述
  2. 2. 使用方法
    1. 2.1. RestTemplate配置类
    2. 2.2. 然后在需要访问url的类中注入RestTemplate
    3. 2.3. 使用RestTemplate发送get请求
    4. 2.4. 使用RestTemplate发送post请求
    5. 2.5. 设置请求头
  3. 3. 实战讲解–发送application/json
    1. 3.1. 设置Header,将contentType配置为application/json
    2. 3.2. 设置业务参数,这里使用Map作为参数容器
    3. 3.3. 配置HttpEntity
    4. 3.4. 发送请求
  4. 4. 详解
  5. 5. Get请求
    1. 5.1. 测试: getForEntity
    2. 5.2. 测试: getForObject
  6. 6. Post请求
    1. 6.1. 测试: postForEntity

我们在开发中对于http接口的调用习惯使用Httpclient或者okhttp等客户端的封装,然后在代码中进行调用。

在springboot中,可以使用RestTemplate模板进行Http服务的调用,整合容易,使用简便而且优雅。不废话,直接上代码。

借助 RestTemplate,Spring应用能够方便地使用REST资源
Spring的 RestTemplate访问使用了模版方法的设计模式.
模版方法将过程中与特定实现相关的部分委托给接口,而这个接口的不同实现定义了接口的不同行为.

概述

spring web 项目提供的RestTemplate,使java访问url更方便,更优雅。

它是spring提供的异步的客户端http访问的核心class,它提供非常简单的RESTful方式与http server端进行数据交互,根据所提动的URLs进行http访问,并处理返回结果。它是基于JDK HTTP connection建立的。因此他可以使用不同的HTTP库(apache,netty and OkHttp)来setRequestFactory。

它实现了以下6个主要的HTTP meshod:

HTTP method RestTemplate methods
DELETE delete
GET getForObject,getForEntity
HEAD headForHeaders
OPTIONS optionsForAllow
PUT put
any exchange,execute

使用方法

RestTemplate配置类

首先在代码中加入RestTemplate的配置类,确保能够纳入Spring的bean管理范围中。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
* RestTemplate配置类
*/
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory){
        return new RestTemplate(factory);
    }

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(5000);//单位为ms
        factory.setConnectTimeout(5000);//单位为ms
        return factory;
    }
}

然后在需要访问url的类中注入RestTemplate

@Autowired
private RestTemplate restTemplate;

使用RestTemplate发送get请求

//get json数据
JSONObject json = restTemplate.getForEntity(url, JSONObject.class).getBody();

使用RestTemplate发送post请求

//post json数据
JSONObject postData = new JSONObject();
postData.put("data", "request for post");
JSONObject json = restTemplate.postForEntity(url, postData, JSONObject.class).getBody();

设置请求头

//post json string data
//return string
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
JSONObject jsonObj = JSONObject.parseObject(paras);
HttpEntity<String> formEntity = new HttpEntity<String>(jsonObj.toString(), headers);
String result = restTemplate.postForObject(url, formEntity, String.class);

实战讲解–发送application/json

这里以发送application/json为例着重讲解一下完整的使用流程

设置Header,将contentType配置为application/json

// 2.请求开始,设置请求头,contentType=application/json
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

设置业务参数,这里使用Map作为参数容器

Map<String, Object> requestParam = new HashMap<>();
requestParam.put("param1", param1);
requestParam.put("param2", param2);

配置HttpEntity

HttpEntity<Map<String, Object>> httpEntity = 
        new HttpEntity<>(requestParam, headers);

发送请求

ResponseEntity<String> responseEntity = null;
try {
    // 2.1 发起请求
    responseEntity = restTemplate.postForEntity(requestUrl, httpEntity, String.class);
    // 2.2. 解析返回参数
    String responseBody = responseEntity.getBody();
    LOGGER.info("返回body:{}", responseBody);
    业务返回实体 response = JSON.parseObject(responseBody, 业务返回实体.class);
} catch (Exception e) {
    e.printStackTrace();
}

这里通过

public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request,
        Class<T> responseType, Object... uriVariables)

发起请求,将responseBody中的业务返回实体通过FastJSON等json库转换为业务实体进行业务操作即可。

详解

RestTemplate定义了36个与REST资源交互的方法,其中的大多数都对应于HTTP的方法。
其实,这里面只有11个独立的方法,其中有十个有三种重载形式,而第十一个则重载了六次,这样一共形成了36个方法。

  • delete() 在特定的URL上对资源执行HTTP DELETE操作
  • exchange()
    在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中
    映射得到的
  • execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
  • getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
  • getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象
  • postForEntity()
    POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得
    到的
  • postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象
  • headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
  • optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息
  • postForLocation() POST 数据到一个URL,返回新创建资源的URL
  • put() PUT 资源到特定的URL

Get请求

RestTemplate 的get方法有以上几个,可以分为两类: getForEntity() 和 getForObject()
首先看 getForEntity() 的返回值类型 ResponseEntity

<T> ResponseEntity<T> getForEntity()

ResponseEntity 继承了HttpEntity. 封装了返回的响应信息,包括 响应状态,响应头 和 响应体.

在测试之前我们首先 创建一个Rest服务,模拟提供Rest数据,这里给出Controller层代码,

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "getAll")
    public List<UserEntity> getUser() {
        List<UserEntity> list = userService.getAll();
        return list;
    }

    @RequestMapping("get/{id}")
    public UserEntity getById(@PathVariable(name = "id") String id) {
        return userService.getById(id);
    }


    @RequestMapping(value = "save")
    public String save(UserEntity userEntity) {
        return "保存成功";
    }


    @RequestMapping(value = "saveByType/{type}")
    public String saveByType(UserEntity userEntity,@PathVariable("type")String type) {

        return "保存成功,type="+type;
    }
}

测试: getForEntity

  1. 无参数的 getForEntity 方法

    @RequestMapping(“getForEntity”)

    public List<UserEntity> getAll2() {
        ResponseEntity<List> responseEntity = restTemplate.getForEntity("http://localhost/getAll", List.class);
        HttpHeaders headers = responseEntity.getHeaders();
        HttpStatus statusCode = responseEntity.getStatusCode();
        int code = statusCode.value();
    
        List<UserEntity> list = responseEntity.getBody();
    
        System.out.println(list.toString());
        return list;
    
    }
    
  2. 有参数的 getForEntity 请求,参数列表,可以使用 {} 进行url路径占位符

    //有参数的 getForEntity 请求,参数列表
    @RequestMapping("getForEntity/{id}")
    public UserEntity getById2(@PathVariable(name = "id") String id) {
    
        ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", UserEntity.class, id);
        UserEntity userEntity = responseEntity.getBody();
        return userEntity;
    }
    
  3. 有参数的 get 请求,使用map封装参数

    //有参数的 get 请求,使用map封装参数
    @RequestMapping("getForEntity/{id}")
    public UserEntity getById4(@PathVariable(name = "id") String id) {
        HashMap<String, String> map = new HashMap<>();
        map.put("id",id);
    
        ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", 
        UserEntity.class, map);
        UserEntity userEntity = responseEntity.getBody();
    
        return userEntity;
    }
    

通常情况下我们并不想要Http请求的全部信息,只需要相应体即可.对于这种情况,RestTemplate提供了 getForObject() 方法用来只获取 响应体信息.
getForObject 和 getForEntity 用法几乎相同,指示返回值返回的是 响应体,省去了我们 再去 getBody() 。

测试: getForObject

  1. 无参数的 getForObject 请求

    //无参数的 getForObject 请求
    @RequestMapping("getAll2")
    public List<UserEntity> getAll() {
        List<UserEntity> list = restTemplate.getForObject("http://localhost/getAll", List.class);
    
    System.out.println(list.toString());
    return list;

} 
  1. 有参数的 getForObject 请求,使用参数列表

    //有参数的 getForObject 请求
    @RequestMapping("get2/{id}")
    public UserEntity getById(@PathVariable(name = "id") String id) {
    
        UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, id);
    
        return userEntity;
    }
    
  2. 有参数的 get 请求,使用map封装请求参数

    //有参数的 get 请求,使用map封装请求参数
    @RequestMapping("get3/{id}")
    public UserEntity getById3(@PathVariable(name = "id") String id) {
        HashMap<String, String> map = new HashMap<>();
        map.put("id",id);
    
        UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, map);
    
        return userEntity;
    }
    

    Post请求

POST请求方法主要如下

<T> T postForObject(String url, Object request, Class<T> responseType, Object... uriVariables)
        throws RestClientException;
<T> T postForObject(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
        throws RestClientException;
<T> T postForObject(URI url, Object request, Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
        throws RestClientException;
<T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
        throws RestClientException;
<T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;

测试: postForEntity

  1. post 请求,保存 UserEntity 对像

    //post 请求,提交 UserEntity 对像
    @RequestMapping("saveUser")
    public String save(UserEntity userEntity) {
    
        ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/save", userEntity, String.class);
        String body = responseEntity.getBody();
    
        return body;
    
    }
    
  2. 有参数的 postForEntity 请求

    // 有参数的 postForEntity 请求
    @RequestMapping("saveUserByType/{type}")
    public String save2(UserEntity userEntity,@PathVariable("type")String type) {
    
        ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", userEntity, String.class, type);
        String body = responseEntity.getBody();
    
        return body;
    
    }
    
    // 有参数的 postForEntity 请求,使用map封装
    @RequestMapping("saveUserByType2/{type}")
    public String save3(UserEntity userEntity,@PathVariable("type")String type) {
        HashMap<String, String> map = new HashMap<>();
        map.put("type", type);
    
    ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", userEntity, String.class,map);
    String body = responseEntity.getBody();

    return body;

}
文章目录
  1. 1. 概述
  2. 2. 使用方法
    1. 2.1. RestTemplate配置类
    2. 2.2. 然后在需要访问url的类中注入RestTemplate
    3. 2.3. 使用RestTemplate发送get请求
    4. 2.4. 使用RestTemplate发送post请求
    5. 2.5. 设置请求头
  3. 3. 实战讲解–发送application/json
    1. 3.1. 设置Header,将contentType配置为application/json
    2. 3.2. 设置业务参数,这里使用Map作为参数容器
    3. 3.3. 配置HttpEntity
    4. 3.4. 发送请求
  4. 4. 详解
  5. 5. Get请求
    1. 5.1. 测试: getForEntity
    2. 5.2. 测试: getForObject
  6. 6. Post请求
    1. 6.1. 测试: postForEntity
Fork me on GitHub