美文网首页
SpringCloud学习(五)之RestTemplate几种请

SpringCloud学习(五)之RestTemplate几种请

作者: 程序员小杰 | 来源:发表于2020-11-29 17:04 被阅读0次
        @Bean
        @LoadBalanced    //开启负载均衡
        RestTemplate restTemplateBean() {
            return new RestTemplate();
        }
    
        @Autowired
        @Qualifier("restTemplateBean")
        RestTemplate restTemplate;
    

    1、GET

    image.png

    根据上图可以看出GET请求方式一共提供了两个函数 getForObject、getForEntity。每个函数都有三个重载方法。下面就分别来介绍一下:

    getForEntity

    该方法返回的是 ResponseEntity, 该对象是 Spring对 HTTP 请求响应的封装, 其中主要存储了 HTTP 的几个重要元素, 比如 HTTP 请求状态码的枚举对象 HttpStatus (也就是我们常说的 404、 500 这些错误码)、 在它的父类HttpEntity中还存储着HTTP 请求的头信息对象 HttpHeaders 以及泛型类型的请求体对象。

    • public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
      url为请求的地址, responseType为请求响应体 body 的包装类型, urlVariables为url中的参数绑定。
    ResponseEntity<String> entity = restTemplate.getForEntity("http://appUser/api/user/getName?name={1}", String.class, "哈哈哈哈");
    

    其中第三个参数哈哈哈哈会替换 url 中的{1} 占位符。 这里需要注意的是, 由于urlVariables 参数是一个可变参数,最终会将它转换为一个Iterator, 所以它的顺序会对应 url 中 占位符定义的数字顺序

    • public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
      该方法提供的参数中, 只有 urlVariables 的参数类型与上面的方法不同。 这里使用了 Map 类型, 所以使用该方法进行参数绑定时,需要在占位符中指定Map 中参数的 key 值,比如 url定义为 http://appUser/api/user/getName?name={name),在Map 类型的 urlVariables 中, 我们就需要 put 一个 key为 userName 的参数来绑定url 中 {name} 占位符的值, 比如:
    HashMap<String , String > map = new HashMap<>();
    map.put("name","嘿哈嘿哈");
    entity = restTemplate.getForEntity("http://appUser/api/user/getName?name={1}", String.class,map);
    
    • public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
      该方法使用URI 对象来替代之前的 url 和 urlVariables 参数来指定访问地址和参数绑定。 URI 是JDK java.net 包下的一个类,它表示一个统一资源标识符(Uniform Resource Identifier)引用。
    //如果是中文记得转码
            String url = "http://appUser/api/user/getName?name=" + URLEncoder.encode("红红火火恍恍惚惚","UTF-8");
            URI uri = URI.create(url);
            entity =  restTemplate.getForEntity(uri,String.class);
    

    getForObject

    该方法可以理解为对 getForEntity 的进一步封装,
    它通过 HttpMessageConverterExtractor 对 HTTP 的请求响应体 body内容进行对象转换, 实现请求直接返回包装好的对象内容

    • public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
      String rest = restTemplate.getForObject("http://appUser/api/user/getName?name={1}", String.class,name);
    
    • public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
            HashMap<String, Object> map = new HashMap<String,Object>();
            map.put("name",name);
            rest = restTemplate.getForObject("http://appUser/api/user/getName?name={name}", String.class,map);
    
    • public <T> T getForObject(URI url, Class<T> responseType)
            //如果是中文记得转码
            String url = "http://appUser/api/user/getName?name=" + URLEncoder.encode(name,"UTF-8");
            URI uri = URI.create(url);
            rest = restTemplate.getForObject(uri,String.class);
    

    2、POST

    服务提供者appUser增加两个接口

        @PostMapping("/addUser")
        public User addUser(User user){
            return user;
        }
    
        @PostMapping("/addUserJson")
        public User addUserJson(@RequestBody User user){
            return user;
        }
    

    两个方法代表了不同的传参方式,一个是key/value格式,一个是json格式。


    image.png

    根据上图可以看出POST请求方式一共提供了两个函数 postForEntity、postForObject、postForLocation。每个函数都有三个重载方法。下面就分别来介绍一下:

    postForEntity

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

    这些函数中的参数用法大部分与getForEntity一致。 这里需要注意的是新增加的
    request参数, 该参数可以是一个普通对象, 也可以是一个HttpEntity对象。 如果是
    一个普通对象, 而非HttpEntity对象的时候, RestTemplate会将请求对象转换为一
    个HttpEntity对象来处理, 其中Object就是 request 的类型, request内容会被视
    作完整的body来处理;而如果 request 是一个HttpEntity对象, 那么就会被当作一
    个完成的HTTP请求对象来处理, 这个 request 中不仅包含了body的内容, 也包含了
    header的内容。


    image.png

    示例:

    //调用addUser方法
     MultiValueMap map = new LinkedMultiValueMap();
     map.add("id","1");
     map.add("name","gongj");
     ResponseEntity<User> userResponseEntity = restTemplate.postForEntity("http://appUser/api/user/addUser", map, User.class);
    
    //调用addUserJson方法
    User user = new User();
    user.setId("87777");
    user.setName("哈哈哈哈哈");
    userResponseEntity = restTemplate.postForEntity("http://appUser/api/user/addUserJson", user, User.class);
    

    注:需要使用 LinkedMultiValueMap ,不能使用HashMap。使用FormHttpMessageConverter进行解析。
    可能有小伙伴可能会疑问了。RestTemplate中默认提供的转换器没有FormHttpMessageConverter啊?但是默认提供的AllEncompassingFormHttpMessageConverter继承了FormHttpMessageConverter。

    image.png
    image.png

    传递类型为HashMap,可以发现被解析成了json字符串。用的是MappingJackson2HttpMessageConverter进行解析。


    image.png

    postForObject

    • public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
    • public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
    • public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType)
      该方法跟getForObject方法类似, 它的作用是简化postForEntity的后续处理。 通过直接将请求响应的body内容包装成对象来返回使用。requesta参数参考postForEntity的解释说明。

    示例:

    MultiValueMap map = new LinkedMultiValueMap();
    map.add("id","1");
    map.add("name","gongj");
    User user = restTemplate.postForObject("http://appUser/api/user/addUser", map, User.class);
    
    user.setId("99");
    user.setName("高兴哈哈哈");
    user = restTemplate.postForObject("http://appUser/api/user/addUserJson", user, User.class);
    

    POST参数到底是key/value还是json,主要看第二个参数,如果第二个参数是MultiValueMap,则是以key/value形式传递。如果第二个参数是一个普通对象,则是以json形式传递。

    postForLocation

    • public URI postForLocation(String url, @Nullable Object request, Object... uriVariables)
    • public URI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables)
    • public URI postForLocation(URI url, @Nullable Object request)

    由于 postForLocation 函数会返回新资源的URI, 该URI就相当于指定了返回类
    型,所以此方法实现的POST请求不需要像postForEntity和postForObject那样指
    定responseType。 其他的参数用法相同。

    服务提供者appUser增加方法

    @PostMapping("/register")
        public String register(User user){
            return "redirect:http://appUser/loginPage?name=" + user.getName();
        }
    
        @GetMapping("/loginPage")
        @ResponseBody
        public String loginPage(String name){
            return "loginPage:" + name;
        }
    

    服务消费者appPay

      @GetMapping("/register")
        public void register(){
            MultiValueMap map = new LinkedMultiValueMap();
            map.add("id","1");
            map.add("name","gongj"); 
    //调用register
            URI uri = restTemplate.postForLocation("http://appUser/register", map);
            System.out.println(uri);
    //调用uri 
            String s = restTemplate.getForObject(uri, String.class);
            System.out.println(s);
        }
    

    3、PUT请求

    • public void put(String url, @Nullable Object request, Object... uriVariables)
    • public void put(String url, @Nullable Object request, Map<String, ?> uriVariables)
    • public void put(URI url, @Nullable Object request)

    PUT请求可以通过put方法调用,put方法的参数和前面介绍的postForObject方法的参数基本一致,只是put方法没有返回值而已。
    示例:
    服务提供者appUser增加接口

    @PutMapping("/put/{id}")
        public User put(@PathVariable Integer id,@RequestBody User user){
            System.out.println(id + "=="+user);
            return user;
        }
    

    服务消费者appPayr调用

     @RequestMapping("/put")
        public void put() {
            User user = new User();
            user.setId("99");
            user.setName("高兴哈哈哈");
            restTemplate.put("http://appUser/api/user/put/{1}", user,55);
        }
    

    user 对象是我要提交的参数,最后的55用来替换前面的占位符{1}

    4、DELETE请求

    • public void delete(String url, Object... uriVariables)
    • public void delete(String url, Map<String, ?> uriVariables)
    • public void delete(URI url)

    delete请求可以通过delete方法调用来实现,如下例子:

    服务提供者appUser增加接口

    @DeleteMapping("/del/{id}")
        public void del(@PathVariable("id") String id){
            System.out.println(id);
        }
    

    服务消费者appPayr调用

    @RequestMapping("/delete")
    public void delete() {
        restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100);
    }
    
    

    相关文章

      网友评论

          本文标题:SpringCloud学习(五)之RestTemplate几种请

          本文链接:https://www.haomeiwen.com/subject/ciwsphtx.html