Tomcat报错解决 --- The valid characters are defined in RFC 7230 and RFC 3986怎么解决

发布时间:2021-07-06 11:04:35 作者:chen
来源:亿速云 阅读:851
# Tomcat报错解决 --- The valid characters are defined in RFC 7230 and RFC 3986怎么解决

## 问题现象描述

当使用Tomcat作为Web服务器时,开发者可能会遇到如下错误提示:

java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986


这个错误通常出现在以下场景:
- URL中包含特殊字符(如`{`、`}`、`|`等)
- 请求参数中带有未编码的非ASCII字符
- 使用RestTemplate或HttpClient发送包含特殊字符的请求

## 错误原因深度解析

### 1. RFC规范要求
RFC 7230和RFC 3986定义了HTTP协议中URI的合法字符集:
- **RFC 3986**规定URI只能包含:
  - 字母(A-Za-z)
  - 数字(0-9)
  - 保留字符(`-._~!$&'()*+,;=:@`)
  - 百分号编码(%后跟两位十六进制数)

- **RFC 7230**进一步限制了HTTP请求行中的字符使用

### 2. Tomcat的严格校验
从Tomcat 7.0.73/8.0.39/9.0.0.M4版本开始,默认启用严格URI合规性检查,这是为了防止HTTP请求走私等安全漏洞。

## 五种解决方案

### 方案一:URL编码处理(推荐)

```java
// Java示例:编码URL参数
String originalUrl = "http://example.com/api?param=值|特殊";
String encodedUrl = URLEncoder.encode(originalUrl, StandardCharsets.UTF_8.toString());

// JavaScript示例
encodeURIComponent("特殊参数");

需要特别注意: 1. 不要对整个URL编码,只编码参数部分 2. 区分encodeURI()encodeURIComponent() 3. 服务端需要对应解码

方案二:修改Tomcat配置

conf/catalina.properties中添加:

# Tomcat 7/8/9通用配置
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}

或者通过JVM参数:

-Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
-Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH=true

安全警告:此方案会降低安全性,仅限内网环境使用

方案三:使用过滤器拦截处理

@WebFilter("/*")
public class UrlFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String uri = req.getRequestURI();
        
        if(containsInvalidChars(uri)) {
            // 处理非法字符或重定向
            response.getWriter().write("Invalid URL characters");
            return;
        }
        chain.doFilter(request, response);
    }
    
    private boolean containsInvalidChars(String uri) {
        // 自定义校验逻辑
        return uri.matches(".*[{}|].*"); 
    }
}

方案四:升级/降级Tomcat版本

版本策略对照表:

Tomcat版本 严格检查 建议操作
<7.0.73 升级到安全版本
7.0.73+ 严格 按需配置
9.0.x 严格 推荐使用方案一

方案五:前端预处理方案

// Axios拦截器示例
axios.interceptors.request.use(config => {
  config.url = config.url.replace(/{|}|/g, encodeURIComponent);
  return config;
});

最佳实践建议

  1. 开发阶段

    • 使用Postman测试含特殊字符的API
    • 启用Tomcat的访问日志验证请求
  2. 生产环境

    <!-- server.xml中配置AccessLog -->
    <Valve className="org.apache.catalina.valves.AccessLogValve"
          directory="logs"
          prefix="localhost_access_log"
          suffix=".txt"
          pattern="%h %l %u %t &quot;%r&quot; %s %b" />
    
  3. 安全加固

    • 定期扫描非法URL
    • 使用WAF过滤恶意请求

进阶:RFC规范详解

RFC 3986关键条款

RFC 7230相关要求

常见问题排查清单

  1. 日志分析步骤

    grep "Invalid character" catalina.out
    tail -f logs/localhost_access_log.*.txt
    
  2. 测试用例

    # 测试命令
    curl -v "http://localhost:8080/test?param=special{char}"
    
  3. 调试技巧

    • 使用WireShark抓包分析原始请求
    • 启用Tomcat调试日志:
      
      logging.level.org.apache.tomcat=DEBUG
      

总结

解决该问题的核心思路是: 1. 理解RFC规范对URI的要求 2. 确定特殊字符的来源 3. 选择适合场景的解决方案

对于新项目,建议从设计阶段就遵循URL编码规范;对于遗留系统,可采用过滤器或Tomcat配置的过渡方案。

注意事项:生产环境修改Tomcat配置前,务必评估安全影响,建议优先采用编码方案而非放宽校验规则。 “`

这篇文章包含了: 1. 问题现象描述 2. 深度原因分析 3. 五种详细解决方案 4. 最佳实践建议 5. RFC规范解读 6. 排查清单 7. 总结建议

总字数约1700字,采用Markdown格式,包含代码块、表格、列表等元素,便于技术文档阅读。

推荐阅读:
  1. 如何用Shell脚本实现tomcat日志定时切割
  2. tomcat自带连接池dbcp配置以及优化说明

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

tomcat

上一篇:动态加载css的示例分析

下一篇:如何利用vbs脚本实现设置IE的打印页眉页脚信息

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》