6、SpringCloud之Rest请求模板类

服务消费端去调用服务提供者的服务的时候,使用了RestTemplate。RestTemplate通过getForEntity方法发起请求调用服务端的数据,并通过@LoadBanlaced注解开启客户端负载均衡。

RestTemplate中常见请求方法的使用

GET
POST
PUT
DELETE

通过注解指定通过什么请求方式进行访问,如下:

 @Autowired
    private RestTemplate restTemplate;

//  通过@GetMapping注解就能够指定请求方式
    @GetMapping("/web/hello")
    public String hello(){

//        Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
        return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class).getBody();

    }

RestTemplate 的 GET请求

Get请求可以有两种方式

第一种:getForEntity

该方法返回一个ResponseEntity对象,ResponseEntity是Spring对HTTP请求响应的封装,包括了几个重要的元素,比如响应吗、contentType、contentLength、响应消息体等;

 @Autowired
    private RestTemplate restTemplate;

//    @RequestMapping("/web/hello")
    @GetMapping("/web/hello")
    public String hello(){

        //这里泛型之所以是String类型,是因为方法的第二参数指定了返回类型为String
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class);
        int statusCodeValue = responseEntity.getStatusCodeValue();
        HttpStatus statusCode = responseEntity.getStatusCode();
        HttpHeaders headers = responseEntity.getHeaders();
        String body = responseEntity.getBody();

        System.out.println(statusCodeValue);
        System.out.println(statusCode);
        System.out.println(headers);
        System.out.println(body);

//        Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
        return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class).getBody();

    }

getForEntity方法第二个参数String.class 表示希望返回的body类型是String类型,如果希望返回一个对象,也是可以的,比如User对象;

给两个服务提供者端,提供实体类User

package com.example.springcloud.model;

public class User {

    private Integer id;
    private String name;
    private String phone;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
}

并提供返回值为User的Controller方法

    @RequestMapping("/service/user")
    public User user(){
        User user = new User();
        user.setId(12);
        user.setName("小黑");
        user.setPhone("12345678978");

        return user;
    }

此时,由于服务调用者调用此方法返回数据将数据绑定到实体类User对象上,所以也需要创建User实体类;
当多个工程都需要同一个实体类时,可以选择构建父工程,用Maven进行模块化管理。

此外,服务调用端需要提供一个方法来调用服务提供端

      @GetMapping("/web/user")
    public String user(){
        //这里泛型之所以是String类型,是因为方法的第二参数指定了返回类型为String
        ResponseEntity<User> responseEntity = restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/user", User.class);
        int statusCodeValue = responseEntity.getStatusCodeValue();
        HttpStatus statusCode = responseEntity.getStatusCode();
        HttpHeaders headers = responseEntity.getHeaders();
        User body = responseEntity.getBody();

        System.out.println(statusCodeValue);
        System.out.println(statusCode);
        System.out.println(headers);
        System.out.println(body.getId()+","+body.getName()+","+body.getPhone());

//        Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
        return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class).getBody();

    }

完成之后,启动服务注册中心工程,服务提供端,以及服务调用端进行测试

getForEntity 常用的重载方法

服务提供端 接收请求参数并进行返回

    //通过@RequestParam进行参数绑定
    @RequestMapping("/service/user")
    public User getUser(@RequestParam("id") Integer id,
                         @RequestParam("name") String name,
                         @RequestParam("phone") String phone){
        System.out.println("服务提供者1");

        User user = new User();
        user.setId(id);
        user.setName(name);
        user.setPhone(phone);

        return user;
    }

服务消费端
下面以两种方式。通过数组和Map对url请求地址进行参数绑定

    /**
     * getForEntity()以数组的方式将参数绑定到URL参数中
     * 通过 {下标} 占位符的方式进行绑定
     * 返回数据的封装类型为User类型(返回值类型也可以是String)
     * @return
     */
    @GetMapping("/web/ArrayParamGetUser")
    public String getUser(){
        String[] strArray = {"105", "小红", "12345678989"};

//        Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
        return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/getUser?id={1}&name={2}&phone={3}", User.class, strArray).getBody().toString();

    }

    /**
     * getForEntity()以数组的方式将参数绑定到URL参数中
     * 通过 {key} 占位符的方式进行绑定
     * 返回值类型是String类型
     * @return
     */
    @GetMapping("/web/MapParamgetUser")
    public String getUser2(){
        Map<String, Object> paramMap = new ConcurrentHashMap<>();
        paramMap.put("id",1);
        paramMap.put("name","小诚");
        paramMap.put("phone", "1546879166");

//        Eureka + Ribbon的调用服务的方式(这种方式不再需要ip地址和端口号了)
        return restTemplate.getForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/getUser?id={id}&name={name}&phone={phone}", String.class, paramMap).getBody();

    }

第二种:getForObject()

共同点
getForObject()方法是getForEntity()方法的封装;
getForEntity方法重载的,getForObject方法也有,使用方式也类似;

不同点
getForEntity方法可以拿到返回的数据,同时也可以拿到头部信息状态码等;
getForObject方法只能用于获取返回的body信息;

    /**
     * getForEntity()以Map的方式将参数绑定到URL参数中
     * @return
     */
    @GetMapping("/web/getUserByGetForObject")
    public String getUserByGetForObject(){

        Map<String, Object> paramMap = new ConcurrentHashMap<>();
        paramMap.put("id",1);
        paramMap.put("name","小诚");
        paramMap.put("phone", "1546879166");
        //用请求模板类RestTemplate的getForObject方法,传入一个Map对象通过{key}占位符绑定url请求参数,返回值类型为String类型
        String body = restTemplate.getForObject("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/getUser?id={id}&name={name}&phone={phone}", String.class, paramMap);
        System.out.println(body);

        String[] strArray = {"105", "小红", "12345678989"};
        //用请求模板类RestTemplate的getForObject方法,传入一个Map对象通过{index}占位符绑定url请求参数,返回值类型为User对象类型
        User user2 = restTemplate.getForObject("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/getUser?id={id}&name={name}&phone={phone}", User.class, strArray);
        System.out.println(user2);
        
        
        return restTemplate.getForObject("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/hello", String.class);
    }

RestTemplate 的 POST 请求

POST 与 Get 请求 非常类似

restTemplate.postForObject()
restTemplate.postForEntity()
restTemplate.postForLocation()

服务提供者添加支持Post请求的方法

//  @RequestMapping(value="/service/addUser", method = RequestMethod.POST)
    @PostMapping("/service/addUser")
    public User addUser(@RequestParam("id") Integer id,
                        @RequestParam("name") String name,
                        @RequestParam("phone") String phone){
        System.out.println("服务提供者1");

        User user = new User();
        user.setId(id);
        user.setName(name);
        user.setPhone(phone);

        //将user对象插入数据库(暂时省略)
        return user;
    }

服务消费者添加调用Post请求的方法

    /**
     * 消费者调用 -addUser方法
     * @return
     */
    @RequestMapping("/web/addUser")
    public String addUser(){
        //注意post请求传递参数只能用MultiValueMap
        MultiValueMap<String, Object> dataMap = new LinkedMultiValueMap();
        dataMap.add("id",1);
        dataMap.add("name","小诚");
        dataMap.add("phone", "1546879166");


        ResponseEntity<User> responseEntity = restTemplate.postForEntity("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/addUser", dataMap, User.class);
        System.out.println(responseEntity.getStatusCodeValue());
        System.out.println(responseEntity.getStatusCode());
        System.out.println(responseEntity.getHeaders());
        System.out.println(responseEntity.getBody());


        User user = restTemplate.postForObject("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/addUser", dataMap, User.class);
        System.out.println(user);

        return "请求成功";
    }

RestTemplate 的 PUT 请求

服务提供者添加支持Put请求的方法

//    @RequestMapping(value="/service/updateUser", method = RequestMethod.PUT)
    @PutMapping("/service/updateUser")
    public User updateUser(@RequestParam("id") Integer id,
                        @RequestParam("name") String name,
                        @RequestParam("phone") String phone){

        User user = new User();
        user.setId(id);
        user.setName(name);
        user.setPhone(phone);

        System.out.println("服务提供者1");
        System.out.println(user);

        //将user对象插入数据库(暂时省略)
        return user;
    }

服务消费者添加调用Put请求的方法

    /**
     * 消费者调用 -updateUser方法
     * @return
     */
    @RequestMapping("/web/updateUser")
    public String updateUser(){

        MultiValueMap<String, Object> dataMap = new LinkedMultiValueMap();
        dataMap.add("id",1);
        dataMap.add("name","小诚");
        dataMap.add("phone", "1546879166");

        //put请求没有返回值
        restTemplate.put("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/updateUser",dataMap);

        return "请求成功";
    }

RestTemplate 的 DELETE 请求

服务提供者添加支持Put请求的方法

//    @RequestMapping(value="/service/addUser", method = RequestMethod.PUT)
    @DeleteMapping("/service/deleteUser")
    public User deleteUser(@RequestParam("id") Integer id,
                           @RequestParam("name") String name,
                           @RequestParam("phone") String phone){

        User user = new User();
        user.setId(id);
        user.setName(name);
        user.setPhone(phone);

        System.out.println("服务提供者2");
        System.out.println(user);

        //将user对象插入数据库(暂时省略)
        return user;
    }

服务消费者添加调用Delete请求的方法

    /**
     * 消费者调用 -deleteUser方法
     * @return
     */
    @RequestMapping("/web/deleteUser")
    public String deleteUser(){
        String[] strArray = {"105", "小红", "12345678989"};

        restTemplate.delete("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/deleteUser?id={0}&name={1}&phone={2}", strArray);

        Map<String, Object> paramMap = new ConcurrentHashMap<>();
        paramMap.put("id",1);
        paramMap.put("name","小诚");
        paramMap.put("phone", "1546879166");

        restTemplate.delete("http://01-SPRINGCLOUD-SERVICE-PROVIDER/service/deleteUser?id={id}&name={name}&phone={phone}", paramMap);


        return "请求成功";
    }

总结:
Get 和 Delete 写法相似
Post 和 Put 写法相似

posted @ 2020-09-10 11:51  lawrence林  阅读(257)  评论(0编辑  收藏  举报