前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 Spring RestTemplate 访问 Rest 服务

使用 Spring RestTemplate 访问 Rest 服务

作者头像
佛系贲八拉
修改2021-08-26 17:35:51
9540
修改2021-08-26 17:35:51
举报
文章被收录于专栏:学技术学技术

RestTemplate简介

Spring's central class for synchronous client-side HTTP access.undefinedIt simplifies communication with HTTP servers, and enforces RESTful principles.

It handles HTTP connections, leaving application code to provide URLs(with possible template variables) and extract results.

  上面这段是RestTemplate类中的简单介绍,RestTemplate是Spring3.0后开始提供的用于访问 Rest 服务的轻量级客户端,相较于传统的HttpURLConnection、Apache HttpClient、OkHttp等框架,RestTemplate大大简化了发起HTTP请求以及处理响应的过程。本文关注RestTemplate是如何使用的,暂不涉及内部的实现原理。

  RestTemplate支持多种的请求方式,具体参考下表:

HTTP method

RestTemplate methods

GET

getForObject、getForEntity

POST

postForObject、postForEntity、postForLocation

PUT

put

DELETE

delete

HEAD

headForHeaders

OPTIONS

optionsForAllow

PATCH

patchForObject

any

exchange、execute

引入RestTemplate

  • 方式一,使用无参构造器直接new一个对象
代码语言:txt
复制
	private RestTemplate restTemplate = new RestTemplate();
  • 方式二,先注册成Spring的Bean对象,之后使用的时候直接注入 @Bean public RestTemplate restTemplate(){ return new RestTemplate(); }
代码语言:txt
复制
    @Autowired
    private RestTemplate restTemplate;

测试准备

  新建User对象,用于下面不同请求方式的测试。

代码语言:txt
复制
@Data
public class User {

    /**
     * id
     */
    private Long id;

    /**
     * 用户名
     */
    private String username;

    /**
     * 年龄
     */
    private Integer age;
    
}

GET请求

  GET请求对应两个方法,getForObject()和getForEntity(),每个方法又对应有具体的三个重载方法。这两者的区别在于getForObject()返回的是一个简单的对象,而getForEntity()响应的数据中,还额外包含有与HTTP相关的信息,如响应码、响应头等。

undefined

代码语言:txt
复制
    /**
     * GET资源 (发送一个HTTP GET请求,返回的请求体将映射为一个对象)
     * <p>
     * 1. 执行根据URL检索资源的GET请求
     * 2. 根据responseType参数匹配为一定的类型
     * 3. getForObject()只返回所请求类型的对象信息
     */
    @Test
    public void getForObject() {
        long id = 0;
        //URL中的{id}占位符最终将会用方法的id参数来填充
        String url = "http://localhost:9000/user/{id}";


        //重载1:最后一个参数是大小可变的参数列表,每个参数都会按出现顺序插入到指定URL的占位符中
        User user = restTemplate.getForObject(url, User.class, id);
        System.out.println("user = " + user);

        //重载2:将id参数放到Map中,并以id作为key,然后将这个Map作为最后一个参数
        Map<String, String> urlParams = new HashMap<>(1);
        urlParams.put("id", String.valueOf(id));
        User user2 = restTemplate.getForObject(url, User.class, urlParams);
        System.out.println("user2 = " + user2);

        //重载3:构造URL对象,要在url上进行字符串拼接,不推荐使用
        url = "http://localhost:9000/user/" + id;
        User user3 = restTemplate.getForObject(URI.create(url), User.class);
        System.out.println("user3 = " + user3);
    }

undefined

代码语言:txt
复制
   /**
     * GET资源 (发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象)
     * <p>
     * 1. 执行根据URL检索资源的GET请求
     * 2. 根据responseType参数匹配为一定的类型
     * 3. getForEntity()方法会返回请求的对象以及响应相关的额外信息
     */
    @Test
    public void getForEntity() {
        long id = 1;
        //URL中的{id}占位符最终将会用方法的id参数来填充
        String url = "http://localhost:9000/user/{id}";

        //重载1:同getForObject(),只不过返回的类型是ResponseEntity
        ResponseEntity<User> userResponseEntity = restTemplate.getForEntity(url, User.class, id);
        User user = userResponseEntity.getBody();
        HttpStatus statusCode = userResponseEntity.getStatusCode();
        int statusCodeValue = userResponseEntity.getStatusCodeValue();
        HttpHeaders headers = userResponseEntity.getHeaders();
        System.out.println("user = " + user + "; statusCode = " + statusCode + "; statusCodeValue = " + statusCodeValue + "; headers = " + headers);

        //重载1:同getForObject(),只不过返回的类型是ResponseEntity
        Map<String, String> urlParams = new HashMap<>(1);
        urlParams.put("id", String.valueOf(id));
        ResponseEntity<User> userResponseEntity2 = restTemplate.getForEntity(url, User.class, urlParams);
        System.out.println("userResponseEntity2 = " + userResponseEntity2);

        //重载3:同getForObject(),只不过返回的类型是ResponseEntity
        url = "http://localhost:9000/user/" + id;
        ResponseEntity<User> userResponseEntity3 = restTemplate.getForEntity(URI.create(url), User.class);
        System.out.println("userResponseEntity3 = " + userResponseEntity3);
    }

POST请求

  POST请求对应三个方法,postForObject()、postForEntity()和postForLocation(),每个方法同样对应有三个具体的重载方法。postForObject()、postForEntity()类似于getForObject()和postForEntity(),postForLocation()返回的是一个URI对象。

undefined

代码语言:txt
复制
    /**
     * POST资源 (POST数据到一个URL,返回根据响应体匹配形成的对象)
     */
    @Test
    public void postForObject() {
        String url = "http://localhost:9000/user";

        //重载1 & 重载2
        User user1 = new User();
        user1.setAge(20);
        user1.setUsername("张三");
        //第4个参数可以是Object... uriVariables 或者 Map<String, ?> uriVariables
        User u1 = restTemplate.postForObject(url, user1, User.class);
        System.out.println("user1 = " + u1);

        //重载3
        User user2 = new User();
        user2.setAge(30);
        user2.setUsername("李四");
        User u2 = restTemplate.postForObject(URI.create(url), user2, User.class);
        System.out.println("user2 = " + u2);
    }

undefined

代码语言:txt
复制
    /**
     * POST资源 (POST数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的)
     */
    @Test
    public void postForEntity() {
        String url = "http://localhost:9000/user";

        // 重载1 & 重载2
        User user3 = new User();
        user3.setAge(25);
        user3.setUsername("王五");
        // 第4个参数可以是Object... uriVariables 或者 Map<String, ?> uriVariables
        ResponseEntity<User> userResponseEntity = restTemplate.postForEntity(url, user3, User.class);
        User userBody = userResponseEntity.getBody();
        HttpStatus statusCode = userResponseEntity.getStatusCode();
        int statusCodeValue = userResponseEntity.getStatusCodeValue();
        HttpHeaders headers = userResponseEntity.getHeaders();
        System.out.println("user = " + userBody + "; statusCode = " + statusCode + "; statusCodeValue = " + statusCodeValue + "; headers = " + headers);


        // 重载3
        User user4 = new User();
        user4.setAge(35);
        user4.setUsername("陆六");
        ResponseEntity<User> userResponseEntity2 = restTemplate.postForEntity(URI.create(url), user4, User.class);
        System.out.println("userResponseEntity2 = " + userResponseEntity2);
    }

undefined

代码语言:txt
复制
    /**
     * POST资源 (POST数据到一个URL)
     * 如果服务端在响应的Location头信息中返回新资源的URL,接下来postForLocation()会以String的格式返回该URL
     */
    @Test
    public void postForLocation() {
        String url = "http://localhost:9000/user";
        User user = new User();
        user.setAge(28);
        user.setUsername("七七");

        // 重载1 & 重载2
        // 第3个参数可以是Object... uriVariables 或者 Map<String, ?> uriVariables
        URI uri = restTemplate.postForLocation(url, user);
        if (Objects.nonNull(uri)) {
            String location = uri.toString();
            System.out.println("location = " + location);
        }


        // 重载3
        URI uri1 = restTemplate.postForLocation(URI.create(url), user);
        if (Objects.nonNull(uri1)) {
            String location = uri1.toString();
            System.out.println("location = " + location);
        }
    }

PUT请求

  PUT请求只有一个方法:put(),对应三个具体的重载方法,put请求返回值为void

undefined

代码语言:txt
复制
    /**
     * PUT资源 (PUT资源到特定的URL)
     */
    @Test
    public void put() {
        long id = 1;
        //URL中的{id}占位符最终将会用方法的id参数来填充
        String url = "http://localhost:9000/user/{id}";

        User user = new User();
        user.setId(id);
        user.setUsername("update 张三");
        user.setAge(99);

        //重载1
        restTemplate.put(url, user, id);

        //重载2
        Map<String, String> urlParams = new HashMap<>(1);
        urlParams.put("id", String.valueOf(id));
        restTemplate.put(url, user, urlParams);

        //重载3
        restTemplate.put(URI.create("http://localhost:9000/user/" + id), user);
    }

DELETE请求

  DELETE请求同样只有一个方法:delete(),对应有三个具体的重载方法,delete请求返回值为void

undefined

代码语言:txt
复制
    /**
     * DELETE资源 (在特定的URL上对资源执行HTTP DELETE操作)
     */
    @Test
    public void delete() {
        long id = 1;
        //URL中的{id}占位符最终将会用方法的id参数来填充
        String url = "http://localhost:9000/user/{id}";

        //重载1
        restTemplate.delete(url, id);

        //重载2
        Map<String, String> urlParams = new HashMap<>(1);
        urlParams.put("id", String.valueOf(id));
        restTemplate.delete(url, urlParams);

        //重载3
        restTemplate.delete(URI.create("http://localhost:9000/user/" + id));
    }

HEAD & OPTIONS & PATCH 请求

  这几种请求方式比较少见和少用,这里就不再说明了。

any(通用)请求

  通用的请求主要是指execute()和exchange()方法,这两个方法又分别对应有三个和八个具体的重载方法。

undefined

代码语言:txt
复制
    /**
     * 交换资源 (在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的)
     * 允许在发送给服务端的请求中设置头信息
     * 支持GET、POST、PUT、DELETE...
     */
    @Test
    public void exchange() {
        long id = 1;
        String url = "http://localhost:9000/user/{id}";

        //GET资源
        //参数3是请求头部分;参数4是响应数据要转成对象;最后一个参数用于替换URL中的占位符
        ResponseEntity<User> userResponseEntity = restTemplate.exchange(url, HttpMethod.GET, null, User.class, id);
        System.out.println("exchange = " + userResponseEntity + "; response body = " + userResponseEntity.getBody());

        //POST资源
        String url2 = "http://localhost:9000/user";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        String jsonParams = "{\"username\":\"123\",\"age\":23}";
        HttpEntity<User> httpEntity = new HttpEntity(jsonParams, headers);
        ResponseEntity<User> responseEntity = restTemplate.exchange(url2, HttpMethod.POST, httpEntity, User.class);
        System.out.println("exchange = " + responseEntity + "; response body = " + responseEntity.getBody());

        //PUT and DELETE忽请自行测试
    }

undefined

  execute()的操作相对而言会比较麻烦,建议大家多使用exchange(),这里就不再贴代码进行说明了。

补充说明

  以上测试代码可以在我的GitHub仓库中找到。

undefined

undefined

undefined

undefined

undefined

undefined

undefined

undefined

undefined

文章已授权转载,原文链接:使用 Spring RestTemplate 访问 Rest 服务

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RestTemplate简介
  • 引入RestTemplate
  • 测试准备
  • GET请求
  • POST请求
  • PUT请求
  • DELETE请求
  • HEAD & OPTIONS & PATCH 请求
  • any(通用)请求
  • 补充说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档