spring - GET 请求在 Postman 中有效,但不适用于 RestTemplate - SpringBoot
问题描述
当我尝试通过邮递员发送时,我有一个工作正常的请求。我试图使用遇到错误的代码来实现相同的功能。
我正在使用的代码 -
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
map.add("client_id", clientid);
map.add("client_secret",clientsecret);
HttpEntity<?> request = new HttpEntity<>(map, headers);
logger.info(request.toString());
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(access_token_url)
.queryParam("grant_type", "client_credentials");
logger.info("URI -" + builder.toUriString());
ResponseEntity<String> response = restTemplate.exchange(builder.build().encode().toUri(),
HttpMethod.GET, request, String.class);
logger.info("Response" + response.getBody());
我得到的错误是 -
org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 未经授权
但是在 POSTMAN 中同样的工作具有相同的细节。
我想指定的东西
- 后端 API 不在我手中。
- clientid、clientsecret、access_token_url 是从属性文件中获取的,并且是正确的,我已经交叉检查了它们。
- 这是一个带有 x-www-form-urlencoded 数据的 GET 请求。我检查了多次它不是POST
- 没有诸如 Basic Auth 之类的授权,因为它没有在 POSTMAN 本身中设置
- 经历了这个 这个和这个没有任何帮助。
我主要担心的是我从未见过任何地方发送带有方法主体的 GET 请求,但它在 POSTMAN 中工作,如果它在那里工作,为什么不在代码中工作?我哪里错了?
编辑 - 1 被标记为重复,但它总体上是一个不同的错误代码。OP 得到了500 Internal Server Error
因为他提供了错误的内容类型。
编辑 - 2 调试输出 -
2019-07-31 14:53:05.208 DEBUG 3576 --- [nio-8080-exec-1] o.s.web.client.RestTemplate : HTTP GET ORIGINAL_URL?grant_type=client_credentials
2019-07-31 14:53:05.215 DEBUG 3576 --- [nio-8080-exec-1] o.s.web.client.RestTemplate : Accept=[text/plain, application/json, application/*+json, */*]
2019-07-31 14:53:05.218 DEBUG 3576 --- [nio-8080-exec-1] o.s.web.client.RestTemplate : Writing [{client_id=[CLIENTID], client_secret=[CLIENT_SECRET]}] as "application/x-www-form-urlencoded"
2019-07-31 14:53:06.976 DEBUG 3576 --- [nio-8080-exec-1] o.s.web.client.RestTemplate : Response 401 UNAUTHORIZED
2019-07-31 14:53:07.034 DEBUG 3576 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Using 'text/html', given [text/html, application/xhtml+xml, image/webp, image/apng, application/signed-exchange;v=b3, application/xml;q=0.9, */*;q=0.8] and supported [text/plain, */*, text/plain, */*, application/json, application/*+json, application/json, application/*+json]
2019-07-31 14:53:07.035 DEBUG 3576 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Nothing to write: null body
2019-07-31 14:53:07.039 DEBUG 3576 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK
2019-07-31 14:53:07.108 DEBUG 3576 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : GET "/favicon.ico", parameters={}
2019-07-31 14:53:07.119 DEBUG 3576 --- [io-8080-exec-10] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/], class path resource []]
2019-07-31 14:53:07.181 DEBUG 3576 --- [io-8080-exec-10] o.s.web.servlet.DispatcherServlet : Completed 200 OK
解决方案
对于相同的用例,我们使用以下实现。
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Accept", MediaType.APPLICATION_JSON_VALUE);
String token = new String(Base64.getEncoder().encode((clientId + ":" + clientSecret).getBytes()));
headers.add("Authorization", "Basic " + token);
HttpEntity<?> request = new HttpEntity<>(headers);
logger.info(request.toString());
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(access_token_url).queryParam("grant_type", "client_credentials");
logger.info("URI -" + builder.toUriString());
ResponseEntity<String> response = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.POST,request, String.class);
logger.info("Response" + response.getBody());
这可能会帮助你。
推荐阅读
- css - 来自父组件的CSS不适用于子组件Angular 9
- css - Gatsby-plugin-postcss + autoprefixer + browserslist 的 Gatsby 插件设置
- php - Adobesign PHP API v6 不为自定义字段设置位置
- octave - 如何根据结果检查数值方法的收敛性?(八度)
- javascript - 使用 iText 从 PDF 获取 Javascript
- python-asyncio - 需要 asyncio.Future、协程或 awaitable
- javascript - 如果数字在给定范围之间,是否有一种简洁的方法来返回用于舍入数字的值?
- sql-server - SHA2_256直接比较
- python - 如何将 Azure Function 绑定到 Python 中的 blob 容器?
- php - php ftp_nlist 函数返回 504 网关超时错误