对 Spring RestTemplate 转换的 Curl Token 请求
Curl Token request to Spring RestTemplate Conversion
我正在尝试转换一个 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
如何使上述 RestTemplate
中的 curl 请求正常工作?
根据 post https://whosebug.com/a/49127760/11226302
的建议
您应该将 header 中的请求内容类型设置为;
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
希望对您有所帮助!
我刚刚解决了这个问题:
我有这个
// 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
注意:在我的例子中,添加或禁用此值没有任何区别,无论如何我都会获得授权令牌。
//headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
如果您查看 HttpEntity
的文档,您会发现您使用了错误的构造函数。
entity = new HttpEntity<>(reqBodyData, bodyParamMap);
您正在将要用作 body (bodyParamMap
) 的参数传递为 headers(因为第二个参数是要用于请求)。事实上,您甚至没有为请求使用 HttpHeaders
,因为您没有将它们传递给 HttpEntity
。我不确定 reqBodyData
是什么,但可能是 bodyParamMap
的 toString
。
你应该做的是以下内容
entity = new HttpEntity<>(bodyParamMap, headers);
作为 HttpHeaders
impements 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
但你更想配置一次并将其注入你的 class。
我正在尝试转换一个 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
如何使上述 RestTemplate
中的 curl 请求正常工作?
根据 post https://whosebug.com/a/49127760/11226302
的建议您应该将 header 中的请求内容类型设置为; headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
希望对您有所帮助!
我刚刚解决了这个问题:
我有这个
// 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
注意:在我的例子中,添加或禁用此值没有任何区别,无论如何我都会获得授权令牌。
//headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
如果您查看 HttpEntity
的文档,您会发现您使用了错误的构造函数。
entity = new HttpEntity<>(reqBodyData, bodyParamMap);
您正在将要用作 body (bodyParamMap
) 的参数传递为 headers(因为第二个参数是要用于请求)。事实上,您甚至没有为请求使用 HttpHeaders
,因为您没有将它们传递给 HttpEntity
。我不确定 reqBodyData
是什么,但可能是 bodyParamMap
的 toString
。
你应该做的是以下内容
entity = new HttpEntity<>(bodyParamMap, headers);
作为 HttpHeaders
impements 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
但你更想配置一次并将其注入你的 class。