400即使在请求到达筛选器之前,spring引导中仍返回错误请求

400即使在请求到达筛选器之前,spring引导中仍返回错误请求,spring,spring-boot,tomcat,intellij-idea,Spring,Spring Boot,Tomcat,Intellij Idea,我有一个带有GET服务的spring启动应用程序 @RequestMapping(value = "/abc/track/{type}", method = RequestMethod.GET) public void DummFunc( @RequestParam(value="subs", required = false) String sub, , HttpServletResponse respon

我有一个带有GET服务的spring启动应用程序

@RequestMapping(value = "/abc/track/{type}", method = RequestMethod.GET)

    public void DummFunc(                            
          @RequestParam(value="subs", required = false) String sub,
,  HttpServletResponse response) {}
subs
的值是一个编码值

如果我将以下内容作为值传递给参数subs

{%22endpoint%22:%22https://def.abc.com/tyu/send/eD3vpGNQW28:APA91bHOo8rYrV0xccdQz3okjZJG-QGrJX8LG6ahJnEUpMNfGedqi3hJxQsJx_8BMbH6oDjaSPPEXqzNWchWrGSkhuTkSdemikkys1U22Ipd7MsRw0owWbw89V2fslIVAJ6G5lkyvYuQ%22,%22expirationTime%22:null,%22keys%22:{%22p256dh%22:%22BK0pktn50CMsTQtqwdPlKlJtdFs0LFeXX14T1zgoz6QWnvSTp5dxtChnUP5P1JX0TsjcopbdPKyN31HfABMUyic%22,%22auth%22:%22qbO_z0vGao9wD-E5g8VU-A%22}}
它无法捕获请求,并且控件不在函数内部

如果我们改为将值传递给参数subs:

%7B%22endpoint%22:%22https://def.abc.com/tyu/send/dX5q5eV7hFQ:APA91bHib-0QXrMzjatcvTR_uaIeeJK8lf6GmXUC9Jxv0Oxth-BzD4GmWnd4-YpDZv8qSFZ0eSg9mB2YkRvkc5ezdXW5KeaHjuQZfdyDxyBXjJgE-25Xbtlk37pdm8vfLk20k0k_VxW9%22,%22expirationTime%22:null,%22keys%22:%7B%22p256dh%22:%22BCCvcBLpRqp4u0auP688_MUJLsAiwWlQSn5kpyl8YVsEo_J-KpSdnhCmVIE_BhDXBcFYflPK52hqhYf3EaOCyuY%22,%22auth%22:%22iKuW_ESkCZnubWcQu_JK8w%22%7D%7D
它很好用

基本上,有问题通过的请求是
{
}
,而不是
%7B
%7D

我的问题不是应用程序因400个错误请求而失败,而是如何在我的应用程序中捕获这些请求,对它们进行正确编码,然后对它们进行处理,或者至少可以处理此错误

此外,我还尝试添加过滤器和RestControllerAdvice

到目前为止的调查结果:

  • 我意识到请求甚至可能没有到达应用程序,因为如果我从映射到请求的代码中删除
    DummFunc
    ,它仍然不会返回
    404
    ,而只返回400
  • commonLoggingFilter
    没有用400个错误的响应代码记录这个特定的请求,但是能够记录其余的请求(另一个提示是请求没有命中应用程序-我猜)
  • 在调试过程中,我意识到如果我从chrome应用程序
    Postman
    和浏览器中点击这个API,它会返回400个错误请求,但如果我从桌面
    Postman
    应用程序中点击这个API,它会返回200个错误请求
  • 我还尝试通过一个新类在控制器中添加异常处理程序,但没有一个捕获到请求
  • /@ResponseStatus(HttpStatus.BAD\u请求)
    @ExceptionHandler(Throwable.class)
    公共无效句柄(HttpMessageDataableException){
    System.out.println(“发生异常”);
    系统输出打印ln(e);
    
    }
    基本上,问题是
    Tomcat
    不允许请求通过

    Tomcat 7.0.76、8.0.42和8.5.12中引入了这种行为,以符合RFC 7231

    可以使用catalina中的属性requestTargetAllow还原此强制检查。属性允许禁止字符:

    tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
    
    由于我在Intellij中使用嵌入式tomcat,无法直接编辑
    cataline.properties
    ,因此我添加了

    -Dtomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
    

    要在
    Run->Edit Configuration
    VM选项
    ,我强烈建议您使用
    RequestMethod.POST
    而不是
    RequestMethod.GET

    “{”、“}”、“|”、“\”、“^”、“~”、“[”、“]”和“
    ”`都是“不安全的字符”,您在使用%7B和%7D时非常聪明,这应该是有效的,只要确保以正确的顺序使用%7B和%7D即可

    在《邮递员》中,它们起作用是因为邮递员将花括号解释为环境变量。如果我错了,请纠正我,但我想邮递员会给您返回200,但您的应用程序仍然没有收到任何数据。(对吗?)

    还有另一个可能的解决方案。。。 400表示错误假设在客户端,只需尝试将加密数据作为简单字符串发送,然后在服务器端处理该字符串


    祝你好运

    不是。一个版本的邮递员回复了400,另一个版本回复了200。浏览器和其他客户端,始终为400。我意识到了问题所在,并发布了答案。