SpringBoot嵌入式tomcat服务器读取查询参数中的unicode字符为null

问题描述 投票:0回答:2

我在 Spring Boot 中设计了一个休息端点。 Tomcat 被用作嵌入式服务器。它需要一个查询参数。

  1. 当我将查询参数作为 param1%uFF07 传递时,tomcat 内部将参数读取为 null
  2. 当我将查询参数作为 param1%FF07 传递时,tomcat 读取为某个字符。

tomcat 仅在后面跟两个十六进制数字时读取“%”字符,如果 u 放在“%”字符之后,tomcat 将参数解析为

null
并带有消息

字符解码失败。参数 [名称],值为 [param1%uFF07] 已被忽略。请注意,此处引用的名称和值可能是 由于解码失败而损坏。使用调试级别日志记录来查看 原始的、未损坏的值。注意:进一步出现 参数错误将在 DEBUG 级别记录。

这是 Spring Boot 控制器代码

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value = "name", required = false) String name) {
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
}
java spring-boot tomcat unicode
2个回答
0
投票

您正在网址中传递

%
符号,但
%
是网址中的符号,要按原样传递
%
...您必须传递
%25
然后它将按您的预期工作。

因此,如果您通过

%25uFF07
那么它会向您显示
%uFF07
作为值。

无需更改 application.properties 中的任何内容或任何类型的设置。我已经在我的项目中对此进行了测试。

如有任何疑问,请随时询问。希望有帮助。


0
投票

我找到了一种使用过滤器的方法。有关过滤器的基础知识可以在here找到。我们可以在那里拦截请求查询字符串,并使用 Tomcat UDecoder 类来解析查询字符串,如果抛出任何异常,我们可以显示 400 的响应

public class SimpleFilter implements Filter {

    private final UDecoder urlDecoder = new UDecoder();
    private final Logger logger = LoggerFactory.getLogger(SimpleFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        String queryString = httpServletRequest.getQueryString();
        if (queryString != null) {
            ByteChunk byteChunk = new ByteChunk();
            byteChunk.setBytes(queryString.getBytes(), 0, queryString.length());
            try {
                urlDecoder.convert(byteChunk, true);
            } catch (IOException ioException) {
                logger.error("Hazarduos character found in request parameter.");
                httpServletResponse.setStatus(HttpStatus.BAD_REQUEST.value());
                return;
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.