我在 Spring Boot 中设计了一个休息端点。 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));
}
}
您正在网址中传递
%
符号,但 %
是网址中的符号,要按原样传递 %
...您必须传递 %25
然后它将按您的预期工作。
因此,如果您通过
%25uFF07
那么它会向您显示 %uFF07
作为值。
无需更改 application.properties 中的任何内容或任何类型的设置。我已经在我的项目中对此进行了测试。
如有任何疑问,请随时询问。希望有帮助。
我找到了一种使用过滤器的方法。有关过滤器的基础知识可以在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() {
}
}