当 url 包含大括号字符时,Spring-boot 控制器错误

ham*_*emi 1 java spring spring-boot

我有一个控制器,它接收GET带有 2 个参数的请求,e并且p

@GetMapping("")
public String getIframe(
    @RequestParam(value = "p", required = false) String p,
    @RequestParam(value = "e", required = false) String e
){
    System.out.println("Hi");
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下ep值可以包含{}字符。它在 spring-boot 1 中运行良好,但在将模块更新到 spring-boot 2 后,它开始引发异常:

java.net.URISyntaxException: Illegal character in query at index 47: http://127.0.0.1:8080/shorteners/click/RikBV?e={CLICKID}&p={PUBID}
  at java.net.URI$Parser.fail(URI.java:2848)
  at java.net.URI$Parser.checkChars(URI.java:3021)
  at java.net.URI$Parser.parseHierarchical(URI.java:3111)
  at java.net.URI$Parser.parse(URI.java:3053)
  at java.net.URI.<init>(URI.java:588)
  at java.net.URI.create(URI.java:850)
  ... 45 common frames omitted
Wrapped by: java.lang.IllegalArgumentException: Illegal character in query at index 47: http://127.0.0.1:8080/shorteners/click/RikBV?e={CLICKID}&p={PUBID}
  at java.net.URI.create(URI.java:852)
  at fr.hamid.testApp.app.configurations.HeadersFilter.doFilter(HeadersFilter.java:43) [26 skipped]
  at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [9 skipped]
  at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
  at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
  at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [2 skipped]
 [1 skipped]
Run Code Online (Sandbox Code Playgroud)

另外,我的过滤器类如下:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class HeadersFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        String referer = request.getHeader("referer") ;
        if (referer != null && new UrlValidator().isValid(referer)) {
            URL url = new URL(referer);
            response.setHeader("Access-Control-Allow-Origin", url.getProtocol() + "://" + url.getHost());
        }
        else {
            response.setHeader("Access-Control-Allow-Origin", "*");
        }
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "x-auth-token, x-requested-with, content-type, accept, " +
                "origin, referer, Authorization, customer-user-id, device-os, t-user-id, t-network-cache-capacity," +
                "t-network-bandwidth, device-client-date, dev-platform, sdk-version, sdk-type, app-package-name," +
                "device-imei, developer-key, device-model, device-os-version, secret-token, t-network-type");

        response.setHeader("Access-Control-Expose-Headers", "x-requested-with");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        if (!"OPTIONS".equals(request.getMethod())) {
            //Exception raises here!
            chain.doFilter(req, res);
        }

        response.setHeader("X-Frame-Options", "*");
    }

    public void init(FilterConfig filterConfig) {
    }

    public void destroy() {
    }

}
Run Code Online (Sandbox Code Playgroud)

当我使用wget命令时它运行良好,但是当我使用浏览器调用 url 时会引发异常!

有没有办法处理这些类型的网址?

注意:由于客户正在使用这些网址,因此我无法通过{}与其他人更改字符来解决此问题。所以,处理好这个服务器端很重要!

非常感谢 :)

Dir*_*yne 9

由于spring boot 2.2.0可以这样配置 Tomcat,因此 URL 中允许使用特殊字符。

只需总结你想允许的那些 application.properties

在你的情况下

server.tomcat.relaxed-query-chars= {,}
Run Code Online (Sandbox Code Playgroud)

所有可配置的字符是`{}[]^<>|

application.yml那将是

server:
  tomcat:
    relaxed-query-chars: ['{','}']

Run Code Online (Sandbox Code Playgroud)