java - 当 url 包含大括号字符时 Spring-boot Controller 出错

标签 java spring spring-boot

我有一个 Controller ,它接收带有 2 个参数 epGET 请求:

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

在某些情况下,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]

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

@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() {
    }

}

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

有什么办法可以处理这些类型的网址吗?

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

非常感谢:)

最佳答案

spring boot 2.2.0 起,可以配置 Tomcat,以便 URL 中允许使用特殊字符。

只需将您想要在 application.properties 中允许的内容相加即可

在你的情况下是

server.tomcat.relaxed-query-chars= {,}

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

application.yml中,这将是

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

关于java - 当 url 包含大括号字符时 Spring-boot Controller 出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53611922/

相关文章:

java - 如果所有元素都在同一个存储桶中,为什么会发生调整大小?

java - Drools 返回规则列表

spring 组件扫描找不到包

java - 从 cron 运行 Spring Boot 应用程序

mysql - Spring Boot + OAuth + JWT + MySQL 刷新 token 第二次不起作用

javascript - javascript在spring应用程序中访问属性文件中的值的最佳方式

java - 如何让 JSF2 与 Seam2 一起工作

java - Spring Data JPA 如何为实现公共(public)接口(interface)的两个域类创建单个存储库?

java - Spring 3 MVC 嵌套请求映射

java - Autowiring 与导入