java 使用 Spring RestTemplate 进行 POST 时收到 400 BAD 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17177107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 01:13:12  来源:igfitidea点击:

Getting 400 BAD Request when using Spring RestTemplate to POST

javaspringhttprestbox-api

提问by user2498487

Can someone please help me figure out what is wrong with the code below?

有人可以帮我弄清楚下面的代码有什么问题吗?

I am using Spring 3.1.1 RestTemplateto try to call a REST WS on Box.comto get a new access token from a refresh token.

我正在使用Spring 3.1.1 RestTemplate尝试调用Box.com上的REST WS以从刷新令牌中获取新的访问令牌。

The code below is returning a 400 (BAD REQUEST). I am able to successfullycall the same method using the FireFox POST plugin. I've compared output from the writeForm methodon the FormHttpMessageConverter classand it is exactly as I am sending it from FireFox.

下面的代码返回一个400 (BAD REQUEST). 我能够使用FireFox POST 插件成功调用相同的方法。我已经比较了上的输出,它与我从 FireFox 发送的完全一样。writeForm methodFormHttpMessageConverter class

Does anyone have any ideas?

有没有人有任何想法?

public static void main(String[] args) throws InterruptedException {
    try {
        String apiUrl = "https://www.box.com/api/oauth2/token";
        String clientSecret = "[MY SECRET]";
        String clientId = "[MY ID]";
        String currentRefreshToken = "[MY CURRENT VALID REFRESHTOKEN]";

        RestTemplate restTemplate = new RestTemplate();

        List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();

        messageConverters.add(new FormHttpMessageConverter());
        restTemplate.setMessageConverters(messageConverters);

        MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();

        body.add("grant_type", "refresh_token");
        body.add("refresh_token", currentRefreshToken);
        body.add("client_id", clientId);
        body.add("client_secret", clientSecret);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json");
        headers.add("Accept-Encoding", "gzip, deflate");


        HttpEntity<?> entity = new HttpEntity<Object>(body, headers);

        restTemplate.exchange(apiUrl, HttpMethod.POST, entity, String.class);
    } catch (Exception ex) {
        System.out.println("ex = " + ex.getMessage());
    }
  }
}

回答by Dillon Ryan Redding

The no-arg constructor for RestTemplateuses the java.netAPI to make requests, which does not support gzip encoding. There is, however, a constructor that accepts a ClientHttpRequestFactory. You can use the HttpComponentsClientHttpRequestFactoryimplementation, which uses the Apache HttpComponents HttpClient API to make requests. This doessupport gzip encoding. So you can do something like the following (from the Spring Docs) when creating your RestTemplate:

的无参数构造函数RestTemplate使用java.netAPI 发出请求,不支持 gzip 编码。但是,有一个构造函数接受ClientHttpRequestFactory. 您可以使用HttpComponentsClientHttpRequestFactory实现,它使用 Apache HttpComponents HttpClient API 发出请求。这确实支持 gzip 编码。因此,您可以在创建您的时执行以下操作(来自Spring DocsRestTemplate

HttpClient httpClient = HttpClientBuilder.create().build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);

回答by nobar

In Spring Boot, adding something like this to pom.xmlseems to add some magic.

在 Spring Boot 中,添加这样的东西pom.xml似乎增添了一些魔力。

<dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>retrofit</artifactId>
    <version>2.3.0</version>
</dependency>

I'm assume that there are other, similar, solutions...

我假设还有其他类似的解决方案......

回答by RathanaKumar

double check the HttpHeaders properly !!

仔细检查 HttpHeaders 正确!