当前位置:首页 >> 开发者生态 >> 【spring boot】RestTemplate 链接带签名post请求 400 bad request,oppo a109

【spring boot】RestTemplate 链接带签名post请求 400 bad request,oppo a109

cpugpu芯片开发光刻机 开发者生态 1
文件名:【spring boot】RestTemplate 链接带签名post请求 400 bad request,oppo a109 【spring boot】RestTemplate 链接带签名post请求 400 bad request

由于项目需要从服务端对第三方发起请求,而且第三方没有提供SDK的情况下,只能根据对方api文档发送请求了,对方接口的格式是:地址+签名,post请求上送具体参数的方式去请求对方服务。

背景

很简单的一个需求,然而开始就卡住了,在Apifox调用能正常返回数据,而一用restTemplate去请求,就报400错误。

org.springframework.web.client.HttpClientErrorException$BadRequest: 400 Bad Requestat org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:79)at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:122)at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:102)at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:778)at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:736)at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:670)at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:579)...

Apifox能调通,而代码调不通,不外乎代码创建起来的https请求有问题

分析

本来没打算细究,出错了打算改用OkHttpClient试一下,还真调通了

private void action(String uri){OkHttpClient client = new OkHttpClient();RequestBody body = null;body = RequestBody.create(MediaType.parse("application/json"), data);// data是jsonObject转的String数据Request request = new Request.Builder().url(uri).method("POST", body).addHeader("Content-Type", "application/json").build();try {Response execute = client.newCall(request).execute();System.out.println(execute);} catch (IOException e) {throw new RuntimeException(e);}}

感觉有点离谱,所以直接用抓包工具(这里用的是fiddler,刚学着用,踩了点坑)抓包一下

POST https://xxx/xx/request?AccessKeyId=xxx&Expires=xx&Signature=xxx&Timestamp=2023-12-11T03%253A39%253A36Z HTTP/1.1Accept: application/json, application/*+jsonContent-Type: application/json;charset=UTF-8User-Agent: Java/1.8.0_221Host: xxxxxConnection: keep-aliveContent-Length: xx{"data":"0"}

返回数据是

HTTP/1.1 400 Bad RequestDate: Mon, 11 Dec 2023 03:39:38 GMTContent-Type: text/plain; charset=utf-8Transfer-Encoding: chunkedConnection: keep-alive9d{"code":"","message":"日期格式错误,请使用yyyy-MM-ddTHH:mm:ssZ格式"}0

很明显的错误提示“日期格式错误,请使用yyyy-MM-ddTHH:mm:ssZ格式”,回头看下上送的报文是“Timestamp=2023-12-11T03%253A39%253A36Z”,虽然不怎么熟悉url的编码解码,但是很明显%253A实际上是%3A既“:”,所以是因为时间被双重加密了,因为在拼接url的时候,我已经手动给时间进行了URL编码

URLEncoder.encode(String.valueOf(time), "UTF-8")

所以去掉后再来

POST https://xxx/xx/request?AccessKeyId=xxx&Expires=xx&Signature=***&Timestamp=2023-12-11T08:25:21Z HTTP/1.1Accept: application/json, application/*+jsonContent-Type: application/json;charset=UTF-8User-Agent: Java/1.8.0_221Host: xxxxxConnection: keep-aliveContent-Length: xx{"data":"0"}

返回数据

HTTP/1.1 401 UnauthorizedDate: Mon, 11 Dec 2023 08:25:21 GMTContent-Type: text/plain; charset=utf-8Transfer-Encoding: chunkedConnection: keep-alive6c{"error":{"code":"AuthFailure","message":"签名错误"}}0

玩我呢…我不格式化它也不格式化,只能断点分析了。发现RestTemplate这里对url进行了处理

@Override@Nullablepublic <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,@Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException {// 这里getUriTemplateHandler调用了一个默认的处理器对url进行了处理URI expanded = getUriTemplateHandler().expand(url, uriVariables);return doExecute(expanded, method, requestCallback, responseExtractor);} 解决

所以,只要改变这个处理器就可以解决问题了

@Beanpublic RestTemplate restTemplate(){RestTemplate restTemplate = new RestTemplate();DefaultUriBuilderFactory uriFactory = new DefaultUriBuilderFactory();// 这里选择了不处理而是自己手动去处理编码了,所以就不再会出现之前的问题了uriFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE);restTemplate.setUriTemplateHandler(uriFactory);// ...return restTemplate;} 总结

很多时候,其实在编码的时候会下意识自信自己编写的没有问题, 以至于在调试的时候很难去发现问题点(开始的时候,其实我先断点了请求,发现请求是成功出去了,也没能关注到%253A的问题,一个劲的根据其他文章说的协议、请求头什么的问题在尝试),所以当发现问题但又自认为自己没有问题的时候,不妨换个角度换个方式,或者重新从头写一遍(有时候逻辑多的时候,其实也不要怕,一边写一边复盘会比自己只干看着分析还可能好一点)当然具体情况要结合自己实际去行动了。

协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接