关注「Java视界」公众号,获取更多技术干货

玩转 RestTemplate

一、RestTemplate 简介

RestTemplate是Spring提供的用来访问Rest服务的客户端或者说是一个 HTTP 请求工具。

这么说可能有些抽象,那就设想一下:现在有A、B两个服务,两个服务都注册在eureka中,那A服务要调用B服务怎么办?你可以使用Java 自带的 HttpUrlConnection 或者经典的网络访问框架 HttpClient 来实现。但是这些请求工具都是比较原生态的,在使用时开发者还要自己完成部分逻辑,使用起来比较复杂。

Spring给我们提供了RestTemplate,spring采用模板模式对httpClient的再封装,遵循Restful原则。RestTmplate提供了很多便捷的方法,可以大大提供开发效率,在微服务中可以方便地进行接口调用。

二、RestTemplate 有哪些API?

RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOperations 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。RestTemplate 提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。

三、RestTemplate的配置

正常在spring boot项目中,一般都有xml和注解两种配置方式,这里使用注解形式完成配置:

@Configuration
public class RestTemplateConfig {

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

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(50000);//ms
        factory.setConnectTimeout(150000);//ms
        return factory;
    }
}

四、RestTemplate 的使用

在说明使用方式前先准备一个服务,简单实现几个功能:

@RestController
@RequestMapping("/dept")
public class DeptController {

    @Autowired
    private DeptService deptService;

    @PostMapping("/add")
    public boolean add(@RequestBody Dept dept){
        return deptService.addDept(dept);
    }

    @GetMapping("/getById/{deptno}")
    public Dept getById(@PathVariable("deptno") Long deptno){
        return deptService.queryById(deptno);
    }

    @GetMapping("/getAll")
    public List<Dept> getAll(){
        return deptService.queryAll();
    }
}

 

4.1 Get 请求

4.1.1 不带参数

RestTemplate 的get方法有以上几个,可以分为两类: getForEntity() 和 getForObject()

@RestController
@Slf4j
@RequestMapping("/rest-template")
public class RestTemplateTestController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/getForEntityList")
    public List<Dept> getAllDept() {
        String url = "http://localhost:8001/dept/getAll";
        ResponseEntity<List> responseEntity = restTemplate.getForEntity(url, List.class);
        log.info("headers:{}", responseEntity.getHeaders());
        log.info("statusCode:{}", responseEntity.getStatusCode());
        log.info("statusCodeValue1:{}", responseEntity.getStatusCodeValue());
        log.info("statusCodeValue2:{}", responseEntity.getStatusCode().value());
        List<Dept> list = responseEntity.getBody();
        log.info("list:{}", list);
        return list;
    }
}
   

    @GetMapping("/getForObjectList")
    public List<Dept> getForObjectList() {
        String url = "http://localhost:8001/dept/getAll";
        List<Dept> forObject = restTemplate.getForObject(url, List.class);
        log.info("list:{}", forObject);
        return forObject;
    }

 4.1.2 带参数

    @GetMapping("/getForEntity/{id}")
    public Dept getDeptById(@PathVariable("id") Long id) {
        String url = "http://localhost:8001/dept/getById/{deptno}";
        ResponseEntity<Dept> responseEntity = restTemplate.getForEntity(url, Dept.class, id);
        log.info("headers:{}", responseEntity.getHeaders());
        log.info("statusCode:{}", responseEntity.getStatusCode());
        log.info("statusCodeValue1:{}", responseEntity.getStatusCodeValue());
        log.info("statusCodeValue2:{}", responseEntity.getStatusCode().value());
        Dept dept = responseEntity.getBody();
        log.info("dept:{}", dept);
        return dept;
    }

    @GetMapping("/getForObject/{id}")
    public Dept getForObject(@PathVariable("id") Long id) {
        String url = "http://localhost:8001/dept/getById/{deptno}";
        Dept dept = restTemplate.getForObject(url, Dept.class, id);
        log.info("dept:{}", dept);
        return dept;
    }

  4.1.3 map为参数

    @GetMapping("/getForEntityWithMap/{id}")
    public Dept getForEntityWithMap(@PathVariable("id") Long id) {
        String url = "http://localhost:8001/dept/getById/{deptno}";
        HashMap<String, Long> map = new HashMap();
        map.put("deptno",id);
        ResponseEntity<Dept> responseEntity = restTemplate.getForEntity(url, Dept.class, map);
        Dept dept = responseEntity.getBody();
        log.info("dept:{}", dept);
        return dept;
    }

    @GetMapping("/getForObjectWithMap/{id}")
    public Dept getForObjectWithMap(@PathVariable("id") Long id) {
        String url = "http://localhost:8001/dept/getById/{deptno}";
        HashMap<String, Long> map = new HashMap();
        map.put("deptno",id);
        Dept dept = restTemplate.getForObject(url, Dept.class, map);
        log.info("dept:{}", dept);
        return dept;
    }

4.2 Post 请求

    @PostMapping("/save-dept")
    public String saveDept(Dept dept) {
        String url = "http://localhost:8001/dept/add";
        ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(url, dept, String.class);
        log.info("stringResponseEntity:{}", stringResponseEntity);
        return stringResponseEntity.getBody();
    }
    @PostMapping("/save-dept-object")
    public String saveDeptObject(Dept dept) {
        String url = "http://localhost:8001/dept/add";
        String postForObject = restTemplate.postForObject(url, dept, String.class);
        log.info("stringResponseEntity:{}", postForObject);
        return postForObject;
    }

4.3 exchange 请求

    @PostMapping("/save-dept-exchange")
    public String saveDeptWithExchange(Dept dept) {
        String url = "http://localhost:8001/dept/add";
        HttpEntity<Dept> entity = new HttpEntity<Dept>(dept);
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        log.info("exchange:{}", exchange);
        return exchange.getBody();
    }

五、总结

 RestTemplate作为一款非常不错的rest请求工具,屏蔽了复杂的HttpClient的实现细节,向外暴露出简单、易于使用的接口,使得我们的开发工作越来越简单、高效。在微服务中的调用中它也有很重要的位置,因此,掌握其原理及用法还是很必要的。

然而,RestTemplate虽然实现了服务调用,但是并没有实现负载均衡,要实现负载均衡还要使用@LoadBalenced注解结合Ribbon来实现或者Feign来实现。

(以上代码纯手打~)

posted @ 2022-06-25 14:02  沙滩de流沙  阅读(60)  评论(0编辑  收藏  举报

关注「Java视界」公众号,获取更多技术干货