RestTemplate简单使用

2023-01-10 10:57:29

简介

RestTemplate 深度解析 https://my.oschina.net/lifany/blog/688889

method GET must not have a request body. 错误解决办法https://blog.csdn.net/weixin_44299027/article/details/106646412

一、RestTemplate

spring 自带

  • 默认的 RestTemplate 是不支持 get 方式通过 Body 携带参数(get 方法不支持传递 request,所以不支持传递 json 类型数据)
  • 默认使用的是SimpleClientHttpRequestFactory
  • RestTemplate 支持通过 setRequestFactory 设置 HTTP 请求客户端工具,支持 jdk、httpclient、okHttp 等

RestTemplate 详细配置使用可参考 https://www.cnblogs.com/wyq178/p/9058030.html

1、新建配置类

新建 RestTemplateConfig 配置类注入 RestTemplate,可以配置其他工厂设置参数,默认使用 SimpleClientHttpRequestFactory

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate() {
        // 默认的是JDK提供http连接,需要的话可通过setRequestFactory方法替换为例如Apache HttpComponents、Netty或//OkHttp等其它HTTP library(需要导包)
/*        OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory();
        factory.setReadTimeout(5000);//单位为ms
        factory.setConnectTimeout(5000);//单位为ms
        return new RestTemplate(factory);*/
        return new RestTemplate();
    }
}
2、get 请求

新建 RestTempController 控制层带参数

    @GetMapping("/get/url_path_params")
    public JSONObject getUrlPathParams(@RequestParam(value = "name",required = true) String userName,@RequestParam(value = "id")int id) {
        JSONObject jsonObject = JSON.parseObject("{\"message\":\"SUCCESS\",\"code\":200}");
        jsonObject.put("body", new Student(id, userName));
        return jsonObject;
    }

springboot 测试

    @Test
    public void getUrlPathParams() {
        String url = "http://127.0.0.1:8080/rest/get/url_path_params?name={name}&id={id}";
        ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(url, JSONObject.class, "admin", 99);
        log.info(JSON.toJSONString(responseEntity.getBody()));
    }

执行结果
在这里插入图片描述
get 请求(可以打开源码查看重载方法)

  • getForEntity() 方法的返回值是一个 ResponseEntity,包括了响应码、contentType、contentLength、响应消息体
  • getForObject() 只返回响应消息体,没有响应码等
3、post 请求

新建 RestTempController 控制层带参数

    @PostMapping(value = "/post/params_bean")
    public JSONObject postParamsBean(@RequestBody Map<String, Object> map) {
        JSONObject jsonObject = JSON.parseObject("{\"message\":\"SUCCESS\",\"code\":200}");
        jsonObject.put("body", map);
        return jsonObject;
    }

springboot 测试

    @Test
    public void postParamsBean() {
        try {
            ClientHttpRequestFactory requestFactory = restTemplate.getRequestFactory();
            System.out.println(requestFactory);
            String url = "http://127.0.0.1:8080/rest/post/params_bean";
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE));
			/*Map<String, Object> map = new HashMap<>();
            map.put("id", 18);
            map.put("name", "test");*/
            //String str = "{\"id\": 1, \"name\": \"admin\"}";
            Student student = new Student(18, "root");
            HttpEntity httpEntity = new HttpEntity(student, headers);
            ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(url, httpEntity, JSONObject.class);
            log.info(Objects.requireNonNull(responseEntity.getBody()).toJSONString());
            log.info(responseEntity.getStatusCode().toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

执行结果
在这里插入图片描述
注意: cotroller 层接口参数类型为 Map 类型,测试类中传递 json 字符串、Map、实体类都可以

post请求(可以打开源码查看重载方法)

  • postForEntity() 方法的返回值是一个 ResponseEntity,包括了响应码、contentType、contentLength、响应消息体
  • postForObject() 只返回响应消息体,没有响应码等
4、其他请求方式

GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE 都可以使用通用的 exchange 和execute 方法,其他请求类型不常用,可参考源码实现
在这里插入图片描述

5、源码说明 get 请求不支持 body 传参

如下 SimpleClientHttpRequestFactory 类的 prepareConnection() 方法

DoOutput 默认值为 false,设置为 true 可进行输出。
在这里插入图片描述
SimpleBufferingClientHttpRequest.executeInternal() 将 body 中的参数写出到流
在这里插入图片描述
上面方法中的 this.connection.getOutputStream() 最终调用sun.net.www.protocol.http.HttpURLConnection 类的 getOutputStream0() 方法(如果你将 get 请求的 DoOutput 设置为 true,将被强制修改为 post 请求,最终会报一个405 Method Not Allowed 的错误)

在这里插入图片描述

  • 作者:不懂一休
  • 原文链接:https://yixiu.blog.csdn.net/article/details/123560238
    更新时间:2023-01-10 10:57:29