Spring POST请求含%字符触发HttpMessageNotReadableException异常
POST请求含%字符触发HttpMessageNotReadableException的解决方案
问题回顾
你写了一个包含多个方法的Spring Controller,其中某个处理POST请求的方法,在请求的abnormalDesc字段包含%字符时,会抛出org.springframework.http.converter.HttpMessageNotReadableException,提示“Required request body is missing”;但把%字符移除后,请求就能正常处理。你的请求Content-Type是application/x-www-form-urlencoded;charset=UTF-8,提交的表单数据是一段JSON格式的内容。
原因分析
这个问题的核心在于请求内容格式和Content-Type不匹配,加上URL编码的规则冲突:
- 你提交的是JSON结构的数据,但却使用了
application/x-www-form-urlencoded这个表单编码类型。在这种编码规则下,%是URL转义字符的起始标记(比如%20代表空格),当出现单独的%而不是完整的转义序列时,Tomcat或Spring的解析器会认为这是非法的URL编码,直接解析失败,最终Spring就会误以为请求体缺失,抛出对应的异常。
可行的解决方案
方案1:改用正确的Content-Type(推荐)
既然你提交的是JSON数据,最规范的做法是把请求的Content-Type设置为application/json:
- 前端请求时,将Content-Type头设为
application/json;charset=UTF-8,然后直接发送JSON格式的字符串(不需要做表单编码)。 - 后端Controller的方法参数保持用
@RequestBody CxContractGoodsDTO接收,Spring会用JSON解析器处理请求体,此时%字符只是普通字符串内容,不会触发编码解析错误。
方案2:对%字符进行URL编码
如果因为某些限制必须使用application/x-www-form-urlencoded类型,需要把请求中的%转成对应的URL编码值%25:
- 比如把
abnormalDesc的值从"asdf%"改成"asdf%25",这样服务器在解析时,会把%25还原成普通的%字符,就能正常解析请求体了。
方案3:调整服务器配置允许未转义的%(不推荐,谨慎使用)
如果不想修改请求,可以调整Tomcat的编码解析规则,允许单独的%字符:
- 如果你用的是独立Tomcat,找到
server.xml里的<Connector>标签,添加relaxedQueryChars="%"属性,比如:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" relaxedQueryChars="%" /> - 如果你用的是Spring Boot,可以在
application.properties或application.yml里添加配置:server.tomcat.relaxed-query-chars=%
注意:这个方案会放松服务器的编码校验规则,可能带来安全风险(比如注入类攻击),只在万不得已的情况下使用。
内容的提问来源于stack exchange,提问作者Z.yue
相关产品推荐
相关产品推荐

