You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot解析URI查询报错:无法解析URI查询参数问题求助

嘿,我来帮你搞定这个Jetty报400的问题!

你遇到的org.eclipse.jetty.http.BadMessageException: 400: Unable to parse URI query错误,核心原因是请求里的%F8%FA是个无效的UTF-8编码序列。Jetty作为Spring Boot默认的嵌入式容器,默认会严格按照RFC 3986规范校验URI编码,一旦发现不符合规则的字节组合,就直接把请求拦下来返回400了。

具体说,UTF-8里以0xF8开头的字节本来应该对应5字节的Unicode序列,但你只传了两个字节,属于不完整的无效编码,自然过不了Jetty的严格校验。

下面给你两种可行的解决思路,按需选就行:

方案一:让Jetty放宽URI编码校验

通过自定义Spring Boot的Jetty容器配置,把URI的合规性校验改成宽松模式,这样Jetty就不会因为编码无效直接拒绝请求了。

在项目里加个配置类:

import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.UriCompliance;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JettyConfig {
    @Bean
    public JettyServletWebServerFactory jettyServletWebServerFactory() {
        JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
        factory.addServerCustomizers(server -> {
            for (Connector connector : server.getConnectors()) {
                if (connector instanceof ServerConnector) {
                    HttpConfiguration config = ((ServerConnector) connector).getHttpConfiguration();
                    // 切换到宽松的URI合规模式,允许解析不严格的编码
                    config.setUriCompliance(UriCompliance.RFC3986_LOOSE);
                }
            }
        });
        return factory;
    }
}

配置好之后,Jetty就会放过这类请求,Spring MVC会自动尝试解析参数。不过要注意,如果编码确实无效,解析后的name可能会是乱码,这时候可能需要你自己再手动调整解码逻辑。

方案二:禁用Jetty自动解码,手动处理原始参数

要是你需要精准控制参数的解码过程,可以让Jetty别自动解码URI,然后在控制器里自己拿原始查询字符串处理:

第一步:配置Jetty禁用自动解码

同样加个Jetty配置类,把自动解码关掉:

import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.ServerConnector;
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JettyConfig {
    @Bean
    public JettyServletWebServerFactory jettyServletWebServerFactory() {
        JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
        factory.addServerCustomizers(server -> {
            for (Connector connector : server.getConnectors()) {
                if (connector instanceof ServerConnector) {
                    HttpConfiguration config = ((ServerConnector) connector).getHttpConfiguration();
                    // 禁用自动解码,保留原始的查询字符串
                    config.setDecodeUri(false);
                }
            }
        });
        return factory;
    }
}

第二步:修改控制器手动处理参数

把原来的控制器方法改成通过HttpServletRequest获取原始查询字符串,然后自己解码:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;

@RestController
public class DemoApplication {
    @RequestMapping(value = "/*", method = RequestMethod.GET)
    public String getName(HttpServletRequest request) {
        String rawQuery = request.getQueryString();
        if (rawQuery == null || !rawQuery.contains("Name=")) {
            return null;
        }
        // 拆分出Name参数的原始编码值
        String nameRawValue = rawQuery.split("=")[1];
        // 这里可以根据实际业务场景调整解码逻辑,比如用ISO-8859-1转成UTF-8
        String decodedName = new String(nameRawValue.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
        return decodedName;
    }

    public static void main(String[] args) {
        org.springframework.boot.SpringApplication.run(DemoApplication.class, args);
    }
}

最后提个小建议

如果不是业务必须,尽量别传这种无效的UTF-8编码,优先用合法的编码格式传递参数,这样能避免后续的乱码或者兼容性问题。要是用了上面的配置还是不行,记得检查下Spring Boot对应的Jetty版本,不同版本的配置参数可能会有细微差别哦。

内容的提问来源于stack exchange,提问作者Bulbasour111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:45:29