REST(四)使用RestTemplate

版权声明:From Lay https://blog.csdn.net/Sadlay/article/details/84383242

REST(四)使用RestTemplate

在当今微服务中,会将一个大系统拆分为多个微服务系统。按微服务应用的建议,每个微服务系统都会暴露Rest风格的URI请求给别的微服务系统所调用。为了方便完成系统之间的相互调用,spring还给予了模板类RestTemplate,通过它可以很方便地对Rest请求进行系统之间的调用,完成系统之间的数据集成。

使用RestTemplate请求后端

RestTemplate的底层是通过类HttpURLConnection实现的。

使用RestTemplate请求后端存在多种方法,这里只讲几种常用的。

控制器

/**
 * @Description:RestTemplate
 * @Author: lay
 * @Date: Created in 1:02 2018/11/18
 * @Modified By:IntelliJ IDEA
 */
@RestController
public class RestTemplateController {

    private RestTemplate restTemplate=new RestTemplate();
    
    //具体方法如下.....
}

HTTP GET请求

    //使用REST Template进行HTTP get请求
    @GetMapping("/user/byId")
    public UserVo getUser(){
        Long id=1L;
        //消费服务,第一个参数为url,第二个参数是返回类型,第三个是uri路径参数
        UserVo userVo=restTemplate.getForObject("http://localhost:8080/user/{id}",UserVo.class,id);
        System.out.println(userVo.getUserName());
        return userVo;
    }

这里的getForObject方法是需要关注的核心方法

第一个参数URI标明请求服务器什么资源,而{id}则代表参数。

第二个参数声明为UserVo.class,表示请求将返回UserVo类的结果,但是实际上服务器只会返回JSON类型的数据给我们,只是RestTemplate内部会将其转换为Java对象。

第二个参数后面则是URI中对应的参数,只是这里只有一个参数,所以就只有一个id。实际上它是一个可变长的参数,如果URI有多个参数,只需要按照顺序写就可以了。

但是如果请求参数很多,显然可读性就不是那么好了,spring已经考虑了这个问题。下面对于用户进行查询,这里设计用户名称(userName) ,备注(note),开始行数(start)和限制记录数(limit)4个参数,实现代码如下。

    //Rest Template使用多参数的HTTP get请求
    @GetMapping("/users/select")
    @ResponseBody
    public List<UserVo> findUsers() {
        //使用map封装多个参数,提高可读性
        Map<String,Object> params=new HashMap<>();
        params.put("userName","user");
        params.put("note","note");
        params.put("start",2);
        params.put("limit",8);
        //Map中的key和URI中的参数一一对应
        String url="http://localhost:8080/users/{userName}/{note}/{start}/{limit}";
        //请求后端
        ResponseEntity<List> responseEntity = restTemplate.getForEntity(url, List.class, params);
        List<UserVo> userVos=responseEntity.getBody();
        return userVos;
    }

这里返回值是个List对象。

HTTP POST请求

新增用户场景,因为新增用户时字段比较多,所以往往采用爨地请求体(Body)的方式。

    //通过POST 请求传递JSON 请求体(BODY)
    @GetMapping("/user/insert")
    public User insertUser(){
        UserVo userVo=new UserVo();
        userVo.setUserName("蜡笔小新");
        userVo.setSexCode(1);
        userVo.setNote("喜欢吃冰淇淋");
        String url="http://localhost:8080/user";
        //请求头
        HttpHeaders headers=new HttpHeaders();
        //设置请求内容为JSON类型
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        //创建请求实体对象
        HttpEntity<UserVo> request=new HttpEntity<>(userVo,headers);
        User user = restTemplate.postForObject("http://localhost:8080/user", request, User.class);
        //User user=restTemplate.postForObject(url,userVo,User.class);
        System.out.println(user.getId());
        return user;
    }

HTTP DELETE请求

    //restTemplate 执行DELETE请求
    @GetMapping("/user/delete")
    public void deleteUser(){
        Long id=1L;
        restTemplate.delete("http://localhost:8080/user{id}",id);
    }

获取响应头和状态码

上面只是讨论了成功获取资源的情况,有时候请求并不能够成功的获取资源。例如,给出一个用户的id,但是这个用户在数据库中并不存在,又如插入数据库时发生了异常,这时报错的信息就可以存放在响应头中,并且服务器也会返回错误的状态码。在这样的长兴下获取响应头和HTTP状态码就可以辨别请求是否成功,如果是发生了错误,它还可以给出信息反馈错误原因。

这里假设一种情况,在插入用户后需要它将响应头和响应码返回给客户端,这时可以通过服务器的响应头或者响应码判断请求是否成功。如下代码

    //获取服务器响应头属性和HTTP状态码
    @GetMapping("/user/userEntity")
    public Map<String,Object> insertUserEntity(){
        UserVo userVo=new UserVo();
        userVo.setUserName("蜡笔小新");
        userVo.setSexCode(1);
        userVo.setNote("喜欢吃冰淇淋");
        String url="http://localhost:8080/user";
        //请求头
        HttpHeaders headers=new HttpHeaders();
        //设置请求内容为JSON类型
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        //创建请求实体对象
        HttpEntity<UserVo> request=new HttpEntity<>(userVo,headers);
        ResponseEntity<User> responseEntity = restTemplate.postForEntity("http://localhost:8080/user2/entity", request, User.class);
        //获取响应体
        User user=responseEntity.getBody();
        HttpHeaders respHeaders=responseEntity.getHeaders();
        //获取响应属性
        List<String> success=respHeaders.get("success");
        //响应的HTTP状态码
        int status=responseEntity.getStatusCodeValue();
        System.out.println(user.getId());
        Map<String,Object> resultMap=new HashMap<>();
        resultMap.put("body",user);
        resultMap.put("responseHeaders",respHeaders);
        resultMap.put("success",success);
        resultMap.put("status",status);
        return resultMap;
    }

这里可以看到RestTemplate的postForEntity方法,它将返回一个ResponseEntity对象。这个对象包含了服务器返回的响应体(Body)、状态码(status)和响应头。在请求不到资源时,往往服务器会通过这些内容给与客户端提示。

github源码

猜你喜欢

转载自blog.csdn.net/Sadlay/article/details/84383242