java.lang.IllegalArgumentException: Invalid character found in the request target.
在Spring Boot应用中,当GET请求的URL中包含方括号[]等特殊字符时,可能会触发java.lang.IllegalArgumentException: Invalid character found in the request target异常。这是因为Tomcat(默认嵌入式容器)对URL的合规性检查遵循了RFC 7230和RFC 3986,而方括号在这些标准中是不允许的。
java.lang.IllegalArgumentException: Invalid character found in the request target.
在Spring Boot应用中,当GET请求的URL中包含方括号[]等特殊字符时,可能会触发java.lang.IllegalArgumentException: Invalid character found in the request target异常。这是因为Tomcat(默认嵌入式容器)对URL的合规性检查遵循了RFC 7230和RFC 3986,而方括号在这些标准中是不允许的。
服务端报错为:
<!doctype html>
HTTP Status 400 – Bad Request
要解决这个问题,有几种方法:
修改Tomcat的配置,放宽对URL字符的限制(不推荐,因为会降低安全性,而且不符合RFC标准)。
在客户端对特殊字符进行编码(推荐在客户端解决)。例如,在URL中,方括号[和]应该分别编码为%5B和%5D。
在服务端捕获该异常,并返回一个友好的错误信息。
使用过滤器对请求URL进行过滤,将特殊字符进行替换或编码转换(注意:这可能会改变请求的原始意图,且实现复杂)。
这里,我们主要讨论服务端的处理:如何捕获该异常以及如何过滤。
要解决Spring Boot GET接口因URL中包含[]特殊字符导致的java.lang.IllegalArgumentException错误,并提供友好的错误处理,以下是完整的解决方案:
方法一:修改Tomcat配置(允许特殊字符)
步骤:
配置application.properties:
允许[]在路径和查询参数中出现
server.tomcat.relaxed-path-chars=‘[]’
server.tomcat.relaxed-query-chars=‘[]’
或通过Java配置类:
@Configuration
public class TomcatConfig {
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
return factory -> factory.addConnectorCustomizers(connector -> {
connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}"); // 添加需要的特殊字符
connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}");
});
}
}
注意事项:
此方法降低安全性(可能引入HTTP响应拆分攻击)
仅适用于Tomcat服务器
方法二:全局异常处理(捕获并返回友好错误)
步骤:
创建异常处理类:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<Map<String, String>> handleInvalidRequest(IllegalArgumentException ex) {
if (ex.getMessage() != null && ex.getMessage().contains("Invalid character found")) {
return ResponseEntity.badRequest().body(Map.of(
"code", "ILLEGAL_CHARACTER",
"message", "URL包含非法字符,请移除特殊符号如[]"
));
}
return ResponseEntity.internalServerError().body(Map.of("error", "服务器内部错误"));
}
}
添加Servlet异常监听器:
@Bean
public ServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, “/error/400”));
return factory;
}
@RestController
@RequestMapping(“/error”)
public class ErrorController implements org.springframework.boot.web.servlet.error.ErrorController {
@GetMapping("/400")
public ResponseEntity<Map<String, String>> handleBadRequest() {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Map.of(
"code", "INVALID_REQUEST",
"message", "请求包含非法字符(如[]),请进行URL编码"
));
}
}
方法三:URL编码过滤器(自动转义特殊字符)
步骤:
创建URL重写过滤器:
@WebFilter(urlPatterns = “/*”)
public class UrlDecodeFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestURI = httpRequest.getRequestURI();
String queryString = httpRequest.getQueryString();
try {
// 尝试直接处理(验证是否有效)
chain.doFilter(request, response);
} catch (IllegalArgumentException e) {
// 发生异常时重编码URL
String safeURI = URLEncoder.encode(requestURI, StandardCharsets.UTF_8.name())
.replaceAll("%2F", "/"); // 保留路径分隔符
String safeQuery = (queryString != null) ?
"?" + URLEncoder.encode(queryString, StandardCharsets.UTF_8) : "";
String newUrl = safeURI + safeQuery;
((HttpServletResponse) response).sendRedirect(newUrl);
}
}
}
推荐方案:结合使用
优先使用方法二(全局异常处理),因为最安全且符合标准
如果必须接受特殊字符:
内部系统:使用方法一(Tomcat配置)
对外系统:要求客户端进行URL编码(前端将[编码为%5B,]编码为%5D)
添加日志监控非法请求:
@ControllerAdvice
public class LoggingAdvice {
@ExceptionHandler(IllegalArgumentException.class)
public void logInvalidRequest(IllegalArgumentException ex, HttpServletRequest request) {
if (ex.getMessage().contains(“Invalid character found”)) {
logger.warn(“非法URL请求: {}?{}”,
request.getRequestURI(),
request.getQueryString());
}
}
}
客户端处理建议
// 前端发送请求前编码特殊字符
const encodeSpecialChars = (url) => {
return url.replace(/ / g , ′ /g, '%5B').replace(/ /g,′/g, ‘%5D’);
};
fetch(encodeSpecialChars(‘/api/data?filter=array[1]’))
最终选择:
安全性优先:使用方法二返回HTTP 400错误,强制客户端合规编码
兼容性优先:内部系统可开方法一(但需评估安全风险)
禁止修改URL的场景:用方法三(注意重定向可能改变语义)
选择
方法二:配置Tomcat的Connector(不推荐,但有时需要)
在Spring Boot中,我们可以通过修改application.properties或application.yml来配置Tomcat,允许特定的非法字符。
并在代码中对参数进行正则校验
补充全局异常处理
更多推荐
所有评论(0)