restTemplate的使用

目录

一、概述?

二、使用步骤

1.引入依赖

2.创建RestTemplate对象,交由spring容器进行管理

3.使用方法

3.1 GET请求

 3.2 POST请求

4 exchange

5.带有basicAuth的请求示例

6.总结


一、概述?

RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

二、使用步骤

1.引入依赖


    org.springframework.boot
    spring-boot-starter-web

2.创建RestTemplate对象,交由spring容器进行管理

 列举常见的创建方式

1.启动类中注入RestTemplate对象

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class DemoApplication {

    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

 2.创建配置类,注入RestTemplate的对象

package com.czxy.ssm.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * RestTemplate工具类,主要用来提供RestTemplate对象
 */
@Configuration//加上这个注解作用,可以被Spring扫描
public class RestTemplateConfig {
    /**
     * 创建RestTemplate对象,将RestTemplate对象的生命周期的管理交给Spring
     */
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

 3.创建配置类,注入RestTemplate的对象,并设置连接和请求的时间

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * RestTemplate工具类,主要用来提供RestTemplate对象
 */
@Configuration//加上这个注解作用,可以被Spring扫描
public class RestTemplateConfig {

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

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(500000);//单位为ms
        factory.setConnectTimeout(500000);//单位为ms
        return factory;
    }
}

3.使用方法

3.1 GET请求

     3.1.1  getForEntity(String url, Class responseType, Object... uriVariables)
解析: url为请求地址,responseType为请求响应体body的包装类型,uriVariables为url中的参数绑定。uriVariables是一个数组,所以他的顺序会对应url中占位符定义的数字的顺序

请求接口:

@Slf4j
@RestController
@RequestMapping("/memo")
public class BmsBillMemoController {
    @Autowired
    private IBmsBillMemoService bmsBillMemoService;

    /**
     * 获取结算账单手账详细信息
     */
    @GetMapping(value = "/{id}/{name}")
    public AjaxResult getInfo(@PathVariable("id") Long id,@PathVariable("name") String name) {
        return AjaxResult.success(bmsBillMemoService.selectBmsBillMemoById(id));
    }

 请求代码

    @Test
    public void Rest() {
        String url = "http://localhost:8080/memo/{1}/{2}";
        Class responseType = String.class;
        String [] str = new String[2];
        str[0] = "3";
        str[1] = "小林";
        ResponseEntity responseEntity = restTemplate.getForEntity(url, responseType, str);
        System.out.println("1     "+responseEntity.getStatusCode());
        System.out.println("2     "+responseEntity.getStatusCodeValue());
        System.out.println("3     "+responseEntity.getHeaders());
        System.out.println("4     "+responseEntity.getBody());
        String body = responseEntity.getBody();
        AjaxResult ajaxResult = JSONUtil.toBean(body, AjaxResult.class);
        Object data = ajaxResult.get("data");
        BmsBillMemo bmsBillMemo = JSONUtil.toBean(data.toString(), BmsBillMemo.class);
        System.out.println(bmsBillMemo);
    }

3.1.2getForEntity(String url, Class responseType, Map uriVariables)
解析:这里只有uriVariables这个参数不同,这里使用了Map类型,
注意:使用该方法进行参数绑定时需要在占位符中指定Map的key

请求接口

@Slf4j
@RestController
@RequestMapping("/memo")
public class BmsBillMemoController {
    @Autowired
    private IBmsBillMemoService bmsBillMemoService;

    /**
     * 查询结算账单手账列表
     */
    @GetMapping("/list")
    public TableDataInfo list(BmsBillMemo bmsBillMemo) {
        List list = bmsBillMemoService.selectBmsBillMemoList(bmsBillMemo);
        return getDataTable(list);
    }

 请求代码

    @Test
    public void Rest2() {
        String url = "http://localhost:8080/memo/list?id={id}&clientName={clientName}";
        Class responseType = String.class;
        Map map = new HashMap<>();
        map.put("id","3");
        map.put("clientName","顾客");
        ResponseEntity responseEntity = restTemplate.getForEntity(url, responseType, map);
        System.out.println("1     "+responseEntity.getStatusCode());
        System.out.println("2     "+responseEntity.getStatusCodeValue());
        System.out.println("3     "+responseEntity.getHeaders());
        System.out.println("4     "+responseEntity.getBody());
        String body = responseEntity.getBody();
        TableDataInfo result = JSONUtil.toBean(body, TableDataInfo.class);
        Object data = result.getRows();
        List bmsBillMemos = JSONUtil.toList(JSONUtil.parseArray(data.toString()), BmsBillMemo.class);
        bmsBillMemos.stream().forEach(System.out::println);
    }

 3.1.3 getForEntity(URI url, Class responseType)
解析:该方法使用URI替换之前的url和urlVariables参数来指定访问地址和参数绑定。
例如:
                        RestTemplate restTemplate = new RestTemplate();
                        UriComponents uriComponenets = UriComponentsBuilder.formUriString{
                            "http://USER-SERVICE/user?name={name}"
                            .build()
                            .expand("dodo")
                            .encode();
                        }
                        URI uri = UriComponents.toUri();
                        ResponseEntity responseEntity = restTemplate.getForEntity(uri,
                        String.class).getBody();

3.1.4 getForObject()函数

 解析:它可以理解为getForEntity的进一步封装,它通过HttpMessageConverterExtractor对HTTP请求响应体body内容进行对象转换,实现请求直接返回包装好的对象内容
使用场景:当不需要关注请求响应除body外的其他内容时,该函数就非常好用,可以少一个从Response中获取body的步骤。

1.getForObject(String url, Class responseType, Object... uriVariables)
解析:url指定访问的地址,responseType指定访问的地址,urlVariables为url中占位符对应的参数
2.getForObject(String url, Class responseType, Map uriVariables)
解析:该函数使用Map类型的urlVariables替代上面数组形式的urlVariables,因此使用时在url中需要将占位符的名称与Map类型中的Key一一对应设置

3.getForObject(URI url, Class responseType)
解析:该方法使用URI对象来替换之前的url和urlVariabels参数使用

请求代码

    @Test
    public void Rest3() {
        String url = "http://localhost:8080/memo/{1}/{2}";
        Class responseType = AjaxResult.class;
        String [] str = new String[2];
        str[0] = "3";
        str[1] = "小林";
        AjaxResult ajaxResult = restTemplate.getForObject(url, responseType, str);
        Object data = ajaxResult.get("data");
        JSONObject jsonObject = JSONUtil.parseObj(data);
        System.out.println(jsonObject);
//        BmsBillMemo bmsBillMemo = JSONUtil.toBean(jsonObject, BmsBillMemo.class);
        BmsBillMemo bmsBillMemo = JSONUtil.toBean(JSONUtil.toJsonStr(data), BmsBillMemo.class);
        System.out.println(bmsBillMemo);

    }

 3.2 POST请求

1.postForEntity(String url, Object request, Class responseType, Object... uriVariables)
2.postForEntity(String url, Object request, Class responseType, Map uriVariables)
3.postForEntity(URI url, Object request, Class responseType)

 解析:重载函数中的uriVariables用来对url中的参数进行绑定,responseType参数是对请求响应的body内容的类型定义
注意:新增的request参数,改参数可以是一个普通的对象,也可以是一个HttpEntity对象。
如果request是一个普通对象时,RestTemplate会将这个普通对象转换成HttpEntity对象来处理,其中Object就是request的类型,request内容会被当成一个完整的body来处理;
如果resuqet是一个HttpEntity对象时,那么request会被当成一个完整的HTTP请求对象来处理,这个request中不仅包含了body内容,也包含了header的内容
下面的测试代码是第二种的,其他的和上面get的类似

请求接口


    /**
     * 查询结算账单手账列表
     */
    @PostMapping("/list1")
    public AjaxResult list1(@RequestBody BmsBillMemo bmsBillMemo, BmsBillMemo bmsBillMemo2) {
        List list = bmsBillMemoService.selectBmsBillMemoList(bmsBillMemo);
        List list2 = bmsBillMemoService.selectBmsBillMemoList(bmsBillMemo2);
        list.addAll(list2);
        return AjaxResult.success(list);
    }

请求代码

    @Test
    public void Rest5() {
        String url = "http://localhost:8080/memo/list1?clientId={clientId}&supplierId={supplierId}";
        Class responseType = String.class;
        HttpHeaders head = new HttpHeaders();
        head.add("Content-Type","application/json");
        //设置请求体参数
        BmsBillMemo memo = new BmsBillMemo();
        memo.setId(3l);
        memo.setClientId(8l);
        memo.setSupplierId(33l);
        //设置请求头参数
        Map map = new HashMap<>();
        map.put("clientId","8");
        map.put("supplierId","66");
        HttpEntity entity = new HttpEntity(JSONUtil.toJsonStr(memo),head);
        ResponseEntity responseEntity = restTemplate.postForEntity(url, entity, responseType,map);
        System.out.println(responseEntity.getHeaders());
        System.out.println(responseEntity.getStatusCode());
        System.out.println(responseEntity.getStatusCodeValue());
        System.out.println(responseEntity.getBody());
    }
HttpEntity中也可以换成具体的实体类对象
    @Test
    public void Rest5() {
        String url = "http://localhost:8080/memo/list1?clientId={clientId}&supplierId={supplierId}";
        Class responseType = String.class;
        HttpHeaders head = new HttpHeaders();
        head.add("Content-Type","application/json");
        //设置请求体参数
        BmsBillMemo memo = new BmsBillMemo();
        memo.setId(3l);
        memo.setClientId(8l);
        memo.setSupplierId(33l);
        //设置请求头参数
        Map map = new HashMap<>();
        map.put("clientId","8");
        map.put("supplierId","66");
        HttpEntity entity = new HttpEntity(memo,head);
        ResponseEntity responseEntity = restTemplate.postForEntity(url, entity, responseType,map);
        System.out.println(responseEntity.getHeaders());
        System.out.println(responseEntity.getStatusCode());
        System.out.println(responseEntity.getStatusCodeValue());
        System.out.println(responseEntity.getBody());
    }

 4.postForObject()函数
解析:它简化了postForEntity()的后续处理,通过直接将请求响应的body内容包装陈对象来简化返回使用。
                RestTemplate restTemplate = new RestTemplate();
                User user = new User("didi", 20);
                String postResult = restTemplate.postForObject("http[://USER-SERVICE/user", user, String.class);

三个重载方法:
postForObject(String url, Object request, Class responseType, Object... uriVariables)
postForObject(String url, Object request, Class responseType, Map uriVariables)
postForObject(URI url, Object request, Class responseType)

4 exchange

 exchange(String url, HttpMethod method, @Nullable HttpEntity requestEntity, Class responseType, Map uriVariables)

有关exchange方法,这边只介绍这一种,其他的基本类似

get请求代码

    @Test
    public void rest6(){
        String url = "http://localhost:8080/memo/list?id={id}&clientId={clientId}&clientName={clientName}";
        //设置请求头
        HttpHeaders head = new HttpHeaders();
        head.add("Content-Type","application/json");
        //封装请求体和请求头
        HttpEntity  entity = new HttpEntity<>(null,head);
        //设置请求返回值类型(一般设置为string,再进行转换)
        Class responseType = String.class;
        //设置请求url中的参数,可以用map或者数组
        Map map = new HashMap<>();
        map.put("id","3");
        map.put("clientName","顾客");
        map.put("clientId","4");
        //发起请求
        ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.GET,entity,responseType, map);
        //判断请求状态并获取请求的结果
        System.out.println("1     "+responseEntity.getStatusCode());
        System.out.println("2     "+responseEntity.getStatusCodeValue());
        System.out.println("3     "+responseEntity.getHeaders());
        System.out.println("4     "+responseEntity.getBody());
        String body = responseEntity.getBody();
        TableDataInfo result = JSONUtil.toBean(body, TableDataInfo.class);
        Object data = result.getRows();
        List bmsBillMemos = JSONUtil.toList(JSONUtil.parseArray(data.toString()), BmsBillMemo.class);
        bmsBillMemos.stream().forEach(System.out::println);
    }

 post请求代码

    @Test
    public void rest7() {
        String url = "http://localhost:8080/memo/list1?clientId={clientId}&supplierId={supplierId}";
        //设置请求头
        HttpHeaders head = new HttpHeaders();
        head.add("Content-Type", "application/json");
        //设置请求体参数
        BmsBillMemo memo = new BmsBillMemo();
        memo.setId(3l);
        memo.setClientId(8l);
        memo.setSupplierId(33l);
        //封装请求头和请求体
        HttpEntity entity = new HttpEntity(memo, head);
        //设置请求的返回类型(一般为String,便于共用)
        Class responseType = String.class;
        //设置请求头参数
        Map map = new HashMap<>();
        map.put("clientId", "8");
        map.put("supplierId", "66");
        ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, responseType, map);
        System.out.println(responseEntity.getHeaders());
        System.out.println(responseEntity.getStatusCode());
        System.out.println(responseEntity.getStatusCodeValue());
        System.out.println(responseEntity.getBody());
    }

5.带有basicAuth的请求示例

   /**
     * 获取bpm的token信息
     *
     * @return
     */
    public static String getBpmToken() {
        // 请求头
        HttpHeaders head = new HttpHeaders();
        head.add("Content-Type", "application/json");
        head.setBasicAuth(accessKey, secret);
        // 请求体
        JSONObject data = new JSONObject();
        data.put("userCode", userCode);
        HttpEntity entity = new HttpEntity<>(JSON.toJSONString(data), head);
        // 添加try catch,防止bpm接口不存在导致的异常
        try {
            ResponseEntity responseEntity = restTemplate.exchange(tokenUrl, HttpMethod.POST, entity, String.class);

            if (responseEntity.getStatusCodeValue() == HttpStatus.OK.value()) {
                JSONObject body = JSON.parseObject(responseEntity.getBody());
                Boolean flag = body.getBoolean("success");
                if (flag) {
                    // 调用接口正常,获取token信息
                    String process = body.getString("process");
                    JSONObject processInfo = JSON.parseObject(process);
                    String token = processInfo.getString("token");
                    return token;
                } else {
                    // 调用接口异常,输出异常信息,发送钉钉通知
                    logTool.saveExceptionLog("", "", "getBpmToken", body.getString("info"));
                    DingDingTool.sendDingMsg(body.getString("info"));
                }
            } else {
                // 调用接口异常,输出异常信息,发送钉钉通知
                logTool.saveExceptionLog("", "", "getBpmToken", JSON.toJSONString(responseEntity));
                DingDingTool.sendDingMsg(JSON.toJSONString(responseEntity));
            }
        } catch (Exception e) {
            // 调用接口异常,输出异常信息,发送钉钉通知
            logTool.saveExceptionLog("", "", "getBpmToken", e);
            DingDingTool.sendDingMsg("获取token接口调用失败,异常信息:" + e.getMessage());
        }

        return null;
    }

 请求头中可以添加basicAuth认证,restTemplate外面需要嵌套try catch,捕获接口调用时出现的异常(比如当接口不存在时执行报错),

6.总结

还有常用的delete和put请求相对简单,这里就不一一介绍的,常用的请求中请求头中通常需要添加token进行访问,这点需要注意,

你可能感兴趣的:(java常用,java)