有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Curl令牌请求到Spring RestTemplate转换

我正在尝试将一个curl请求转换为Spring的Resttemplate post请求,这会给我一个令牌,但我得到403——错误的请求

我的卷发请求

curl -d "grant_type=client_credentials&client_id=nu5yzeth9tektzf5egxuntp7&client_secret=uP2Xvr6SCKYgXgxxJsv2QkUG" 
  -H "Content-Type: application/x-www-form-urlencoded" 
  -X POST https://cloudsso.example.com/as/token.oauth2

卷曲反应:

{"access_token":"HVURQ845OPJqs8UpOlef5m2ZCNwR","token_type":"Bearer","expires_in":3599}

现在,这里是我的Java代码来实现上述curl post请求

RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

MultiValueMap<String, String> bodyParamMap = new LinkedMultiValueMap<String, String>();
bodyParamMap.add("grant_type", "client_credentials");
bodyParamMap.add("client_id", "nu5yzeth9tektzf5egxuntp7");
bodyParamMap.add("client_secret", "uP2Xvr6SCKYgXgxxJsv2QkUG");

entity = new HttpEntity<>(reqBodyData, bodyParamMap);

restTemplate.postForEntity(url, entity, TokenDTO.class)

Resttemplate调用响应:

2019-12-04 11:10:16,483[0;39m [39mDEBUG[0;39m [[34mrestartedMain[0;39m] [33morg.springframework.core.log.CompositeLog[0;39m: Accept=[application/json, application/*+json]
[30m2019-12-04 11:10:16,484[0;39m [39mDEBUG[0;39m [[34mrestartedMain[0;39m] [33morg.springframework.core.log.CompositeLog[0;39m: Writing [{"grant_type":["client_credentials"],"client_id":["nu5yzeth9tektzf5egxuntp7"],"client_secret":["uP2Xvr6SCKYgXgxxJsv2QkUG"]}] with org.springframework.http.converter.StringHttpMessageConverter
[30m2019-12-04 11:10:17,976[0;39m [39mDEBUG[0;39m [[34mrestartedMain[0;39m] [33morg.springframework.core.log.CompositeLog[0;39m: Response 400 BAD_REQUEST
[30m2019-12-04 11:10:17,981[0;39m [34mINFO [0;39m [[34mrestartedMain[0;39m] [33mcom.ibm.ciscoApiIntegration.service.impl.CiscoAPIServiceImpl[0;39m: e::: 400 Bad Request

如何使上述curl请求在RestTemplate中工作

注意:https://cloudsso.example.com/as/token.oauth2对于这个问题几乎没有修改


共 (3) 个答案

  1. # 1 楼答案

    正如post https://stackoverflow.com/a/49127760/11226302所建议的那样

    您应该将header中的请求内容类型设置为; 标题。setContentType(MediaType.APPLICATION\u FORM\u URLENCODED)

    希望这有帮助

  2. # 2 楼答案

    如果你看一下^{}的文档,你会发现你使用了错误的构造函数

    entity = new HttpEntity<>(reqBodyData, bodyParamMap);
    

    您正在将要用作正文(bodyParamMap)的参数作为头传递(因为第二个参数是用于请求的头)。事实上,您甚至没有对请求使用HttpHeaders,因为您没有将它们传递给HttpEntity。我不确定reqBodyData是什么,但可能是bodyParamMaptoString

    你应该做的是

    entity = new HttpEntity<>(bodyParamMap, headers);
    

    作为HttpHeadersimpements MultiValueMap,您可以在构造函数中直接使用它们。您还希望按原样传递bodyParamMap

    注意:我还建议在HttpHeaders上明确设置Content-Type,以便您确定发送的内容

    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    

    因此,总的结果代码应该是

    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    
    MultiValueMap<String, String> bodyParamMap = new LinkedMultiValueMap<>();
    bodyParamMap.add("grant_type", "client_credentials");
    bodyParamMap.add("client_id", "nu5yzeth9tektzf5egxuntp7");
    bodyParamMap.add("client_secret", "uP2Xvr6SCKYgXgxxJsv2QkUG");
    
    entity = new HttpEntity<>(bodyParamMap, headers);
    
    restTemplate.postForEntity(url, entity, TokenDTO.class)
    

    注意:您不应该构建单一用途RestTemplate,但您更希望配置一次并将其注入到类中

  3. # 3 楼答案

    我刚刚解决了这个问题:

    我有这个

    // wrong
    //private HttpEntity<String> entity;
    

    我改成这样:

    private MultiValueMap<String, String> parametersMap;
    

    然后改变了

    // not working
    entity = new HttpEntity<>(reqBodyData, bodyParamMap);
    

    对这个

    // working
    entity = new HttpEntity<>(bodyParamMap, headers);
    

    现在它工作得很好

    答复:

    2019-12-04 11:52:46,503 DEBUG [restartedMain] org.springframework.core.log.CompositeLog: HTTP POST https://cloudsso.example.com/as/token.oauth2
    2019-12-04 11:52:46,521 DEBUG [restartedMain] org.springframework.core.log.CompositeLog: Accept=[application/json, application/*+json]
    2019-12-04 11:52:46,522 DEBUG [restartedMain] org.springframework.core.log.CompositeLog: Writing [{grant_type=[client_credentials], client_id=[nu5yzeth9tektzf5egxuntp7], client_secret=[uP2Xvr6SCKYgXgxxJsv2QkUG]}] with org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
    2019-12-04 11:52:47,831 DEBUG [restartedMain] org.springframework.core.log.CompositeLog: Response 200 OK
    

    注意:在我的情况下,添加或禁用这个值并没有任何区别,反正我得到的是auth令牌

    //headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);