【Spring 老中医】解决 RestTemplate 在GET请求下不能发送Request Body 的问题

976 阅读1分钟

摘要

工程中有一个第三方API,是通过HTTP GET下载服务器中的图片,但是需要在request body中输入用户名和密码做鉴权。但是Spring中的 RestTemplate 并不能在 HttpMethod.GET 下发送 Request Body。此时需要自定义ClientHttpRequestFactory解决问题。

解决方案

  1. 在注册RestTemplate时,使用自定义的ClientHttpRequestFactory。强制指定当请求方法为HttpMethod.GET时,生成带 Body 的 Request。
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }

    @Bean
    public ClientHttpRequestFactory httpComponentsClientHttpRequestWithBodyFactory() {
        return new HttpComponentsClientHttpRequestWithBodyFactory();
    }
}

public class HttpComponentsClientHttpRequestWithBodyFactory extends HttpComponentsClientHttpRequestFactory {
    @Override
    protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
        if (httpMethod == HttpMethod.GET) {
            return new HttpGetRequestWithEntity(uri);
        }
        return super.createHttpUriRequest(httpMethod, uri);
    }

    private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
        public HttpGetRequestWithEntity(final URI uri) {
            super.setURI(uri);
        }

        @Override
        public String getMethod() {
            return HttpMethod.GET.name();
        }
    }
}
  1. 发送带request body 的GET请求
    @Resource private RestTemplate restTemplate;
    public MessageDTO get() {
        MessageDTO msg = new MessageDTO();
        msg.setAppId("Lark");
        msg.setMsg("这是来是restTemplate的一条消息.");

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

        HttpEntity<MessageDTO> entity = new HttpEntity<>(msg, headers);

        ResponseEntity<MessageDTO> response = restTemplate.exchange(BASE_URL+PATH, HttpMethod.GET, entity, MessageDTO.class);
        log.info("response:{}", response);
        return response.getBody();
    }

参考文献

  1. mekaso.rocks/get-request…
  2. stackoverflow.com/questions/1…