【远程调用返回400问题排查(已解决)】

这篇具有很好参考价值的文章主要介绍了【远程调用返回400问题排查(已解决)】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

我最近给公司一个两年前开发的项目售后,帮助客户验视功能点,顺便帮助解决项目中的问题,由于原负责该项目的项目组已经全都离职了,导致验收之路漫长且艰苦…

在解决问题的过程中碰到了许多疑难杂症都一一解决了,唯独其中有一个问题让我和同事绞尽脑汁花了三天才得以解决,所以为了以后不再被这个问题困扰,特地记录一下,毕竟好记性不如烂笔头嘛,话不多说,我们接着往下看

发生问题由来

是这样一个问题,在测试的过程中发现某部分功能依赖的数据源有部分缺失的情况,然后就着手开始排查问题,调用链调用方式如下:

问题排查

刚开始我觉得肯定是接口报错了,然后开了一个测试接口去调用远程访问方法,结果报错400 Bad Request!!!WTF?如果这个接口400那应该一条数据都没有才对啊,怎么一部分成功一部分失败??

1. 参数400

常见的400就是参数和定义的参数类型不一致导致参数400,然后我拿跑成功的数据作为条件传入,然后成功了,我觉得可能就是这个问题,然后又访问了一次然后也爆出400问题,然后接下去访问的都是400了,再换个成功的数据也无济于事,只要有访问通过的接口就说明肯定不是因为参数问题导致的400了,然后就去看转发平台的日志,也证实了没有爆出参数400的问题
ps:使用Postman调用也是畅通无阻…

2. 请求头过大导致400

通过查看转发平台日志,发现有个问题就是调用的接口要么访问到达,然后转发平台打出日志,要么什么反应也没有,然后我想到了是不是由于请求头过大的原因,然后我直接把所有参数都去掉然后直接访问,结果还是400,然后我又把请求头的token以及标识全去掉,结果终于在转发平台看到了unauthorization错误,果然是这个问题,然后我就询问负责转发平台的同事他们的Nginx设置请求最大大小是多少,然后被告知他们的平台没用到Nginx,那就是说刚刚那个就仅仅只是因为没有token报的错,跟请求头大小没有关系,到这再次断了线索…

然后我就往封装调用的各个地方都插入日志打印,想从日志中找出蛛丝马迹,在漫长的打印查看打印查看日志的过程中,终于让我逮住了问题的小尾巴,我在打印Header的内容时发现token的value是一个数组,且里面有两个token!!!

3. header异常400

在发现header异常后,我就仔细的去看封装好的代码,结果发现了下面这一串代码:

public HttpHeaders getHeaders() {
	  HttpHeaders httpHeaders = new HttpHeaders();
      httpHeaders.setContentType(MediaType.APPLICATION_JSON);
      TokenHelp tokenHelp = tokenHelpRepository.findTokenByConsumerId("客户标识");
      // 如果当前客户在数据库中没有token则取用默认的token
      if (null == tokenHelp){
          tokenHelp = tokenHelpRepository.defaultToken();
      }
      // 如果还是为空则取用登录token
      if (null == tokenHelp){
          LoginResponse loginResponse = getToken();
          httpHeaders.add(HttpHeaders.AUTHORIZATION, BEARER + loginResponse.getToken());
      } else {
      	  // 如果不为空则设置token
      	  httpHeaders.add(HttpHeaders.AUTHORIZATION, tokenHelp.getToken());
      	  // 获得时间差
          long diffMillis = System.currentTimeMillis() - tokenHelp.getCreateTime();
          // 超过十分钟重新获取token
          long outTime = 10 * 60 * 1000;
          if (diffMillis > outTime) {
              LoginResponse loginResponse = getToken();
              httpHeaders.add(HttpHeaders.AUTHORIZATION, BEARER + loginResponse.getToken());
          }
          httpHeaders.add("consumerId", "客户标识");
      }
      return httpHeaders;
}

以上代码乍看上去没什么问题,但是当我点击进HttpHeaders的实现:

package org.springframework.http;

public class HttpHeaders implements MultiValueMap<String, String>, Serializable {
  private static final long serialVersionUID = -8578554704772377436L;
  // ...省略多行代码
}

我看到了MultiValueMap,如果不了解MultiValueMap的同学可能觉得这没什么问题,Map装很正常啊,但是认识的同学都知道MultiValueMap 可以同一个key下面放多个value,原来的Map如果设置了同样的Key,那么值会被替换,但是当使用MultiValueMap时设置了同样的Key,那么值会被用一个数组装起来,为了方便大家理解,这里贴一段简单的演示代码:

public static void main(String[] args) {
    MultiValueMap<String, String> valueMap = new LinkedMultiValueMap<>();
    valueMap.add("1","1");
    valueMap.add("1","2");
    valueMap.add("1","3");
    valueMap.add("1","4");
    valueMap.add("1","5");
    valueMap.add("2","1");
    valueMap.add("2","2");
    valueMap.add("3","1");
    for (Map.Entry<String, List<String>> stringListEntry : valueMap.entrySet()) {
        System.out.println(“key:+stringListEntry.getKey());
        List<String> value = stringListEntry.getValue();
        System.out.println("value:"+value);
    }
}


输出结果:=================================================
key:1
value:[1, 2, 3, 4, 5]
key:2
value:[1, 2]
key:3
value:[1]
输出结果:=================================================

结合之前的代码看这个问题

		  // 如果不为空则设置token
      	  httpHeaders.add(HttpHeaders.AUTHORIZATION, tokenHelp.getToken());
      	  // 获得时间差
          long diffMillis = System.currentTimeMillis() - tokenHelp.getCreateTime();
          // 超过十分钟重新获取token
          long outTime = 10 * 60 * 1000;
          if (diffMillis > outTime) {
              LoginResponse loginResponse = getToken();
              httpHeaders.add(HttpHeaders.AUTHORIZATION, BEARER + loginResponse.getToken());
          }

else代码块中,先设置了一遍AUTHORIZATION然后如果当前token过期了那么会再次设置一遍,这就导致了,如果在token过期的一段时间内,就会有少部分的请求头中有两个token,就会导致请求400,然后更改了设置token逻辑后,接口就顺利通车啦!!!

总结

在处理接口400问题的时候一定要擦亮眼睛,一步一步的去排查问题所在点,魔鬼永远藏在不经意发现的地方,好了,到这分享就结束了,写的不好大家多多谅解哈~文章来源地址https://www.toymoban.com/news/detail-782471.html

到了这里,关于【远程调用返回400问题排查(已解决)】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【生产问题记录】一次简单的 Http 请求异常处理 (请求的 url 太长, Nginx 直接返回 400, 导致请求服务异常)

    按照惯例直接说结论。 后台服务 A 有一个 Http 接口, 代码如下: 没错, 一个 Get 请求, 入参是一个 List 。 同时有另一个后台服务 B, 里面有段逻辑会通过 RestTemplate 调用服务 A 的这个接口, 代码如下: 在服务 B 中, 通过 batchGetUserInfo 方法请求服务 A 时, 传入了一个长度为 122 的 List

    2024年01月16日
    浏览(56)
  • 解决ssh远程连接服务器出现的中文乱码问题

    ssh远程连接服务器出现中文乱码主要分为两种: 1、命令行输出的中文有乱码 比如ll输出的月份,ibus等命令输出的信息 2、vim打开文件,文件显示乱码 1、查看使用的XShell活MobaXterm等远程连接软件的会话属性。 以XShell为例:文件-当前会话属性/默认会话属性-终端-编码,设置成

    2024年02月06日
    浏览(71)
  • 解决pycharm中,远程服务器上文件找不到的问题

    一、问题描述         pycharm中,当我们连接到远程服务器上时。编译器中出现报错问题:        can\\\'t open file \\\'/tmp/OV2IRamaar/test.py\\\': [Errno 2] No such file or directory        第二节是原理解释,第三节是解决方法。 二、原理解释        实际上这是由于我们没有设置好工作路径导

    2024年02月05日
    浏览(48)
  • C# webservice 接收json数据 接口返回 远程服务器返回错误: (500) 内部服务器错误

    C# post 调用webservice 服务端接口,会返回上面那个错误,8成是发送的数据和接口不符合造成的。有2种情况 第一种情况如下:如果类型是默认request.ContentType = \\\"application/x-www-form-urlencoded\\\";这个类型 那么你发送数据和被调用接口参数名如果不对,则会报下图这个错 我发送的参数名

    2024年02月13日
    浏览(64)
  • 三招解决Windows服务器远程桌面连接不上问题

            远程桌面协议 (RDP)是由微软开发的专有协议,它为用户提供远程桌面服务,以便通过网络使用电脑远程控制另一台电脑。远程桌面连接客户端适用于大多数Windows版本,比如Windows Mobile、Linux、Unix、macOS、iOS、Android和其他操作系统,并且远程桌面连接服务器内置

    2024年02月02日
    浏览(54)
  • 解决VS Code安装远程服务器插件慢的问题

    最近想在服务器上做juypter notebook的代码运行,发现要给服务器安装Jupyter插件,但是安装速度奇慢无比(因为服务器不连外网),一开始查看从VS Code插件市场下载插件的博客,但是感觉还是比较麻烦。 假如单位的网络可以高速访问外网的话,给出更加便捷的做法如下: 打开

    2024年02月07日
    浏览(52)
  • 远程桌面连接不上个别服务器的问题分析与解决方案

    在日常的IT运维工作中,远程桌面连接(RDP,Remote Desktop Protocol)是我们经常使用的工具之一,用于管理和维护远程服务器。然而,有时我们可能会遇到无法连接到个别服务器的情况。针对这一问题,我将从多个角度进行分析,并提供相应的解决方案。 一、问题分析 远程桌面

    2024年04月28日
    浏览(49)
  • 远程服务调用的简单应用,并轻松解决LinkedHashMap无法转成相关实体类的问题

    🏀(一)为啥需要远程服务调用?     🐠知其然还要知其所以然,在我们的生产项目上一般而言会部署多个微服务,每个微服务会负责不同版块的业务工作。如果某个微服务 需要借助 另外的某些微服务中的接口才能完成相应操作时,那么服务与服务之间就会存在相互

    2024年02月08日
    浏览(53)
  • RTSP/Onvif视频服务器EasyNVR安防视频云服务调用接口录像会被自动删除的问题解决方案

    EasyNVR安防视频云服务是基于RTSP/Onvif协议接入的视频平台,可支持将接入的视频流进行全平台、全终端的分发,分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等。平台丰富灵活的视频能力,可应用在智慧校园、智慧工厂、智慧水利等场景中。 有用户反馈,在使用EasyN

    2024年02月12日
    浏览(59)
  • 解决VScode远程服务器时opencv和matplotlib无法直接显示图像的问题

    问题描述 :在VSCode中通过SSH连接服务器,使用cv2.imshow或plt.show()无法显示图像。 并且VScode与MobaXterm可以ssh到远程服务器 参数说明: 保持MobaXterm开启的状态下,在VSCode中运行xclock,会显示一个时钟。

    2024年02月14日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包