java.net.URI Zuul网关异常编码异常

java.net.URI encoding exception in Zuul gateway exception

运行 Spring-boot-2.1.4.RELEASE.

有一个 Zuul 应用程序

当我请求时 http://192.168.10.84:8080/app/rest/micro1/inquiry/printCarInquiryList/1?param={%22storeHouseId%22:%22%22,%22storeHouseName%22:%22%22,%22storeHouseType%22:%22%22,%22plaqueSeries%22:%22%22,%22productionYearFrom%22:%22-1%22,%22productionYearTo%22:%22-1%22,%22overallInquery%22:false,%22edited%22:false,%22confirmerCount%22:%22-1%22,%22reportStoreHouseType%22:%22-1%22,%22plaqueNumber%22:%22%22,%22motorNumber%22:%22%22,%22motorNumberOperator%22:%227%22,%22chassisNumber%22:%22%22,%22chassisNumberOperator%22:%227%22,%22storeHouseShowType%22:%221%22,%22havePlaque%22:%22-1%22,%22isFilterByStoreHouseStatus%22:true,%22storeHouseList%22:[%221518691%22],%22goodsStatus%22:null,%22statusId%22:%22-1%22,%22goodsDeleted%22:null,%22formType%22:1,%22searchFilter%22:%22%22,%22order%22:%22%20e.samapelItem.id%20%22,%22pageNumber%22:0,%22pageSize%22:%227%22,%22plaqueType%22:%22-1%22}

引发了以下异常:

Caused by: java.net.URISyntaxException: Illegal character in query at index 95: http://192.168.10.84:8080/app/rest/micro1/inquiry/printCarInquiryList/1?param={%id%22:%22%22,%22storeHouseName%22:%22%22,%22storeHouseType%22:%22%22,%22plaqueSeries%22:%22%22,%22productionYearFrom%22:%22-1%22,%22productionYearTo%22:%22-1%22,%22overallInquery%22:false,%22edited%22:false,%22confirmerCount%22:%22-1%22,%22reportStoreHouseType%22:%22-1%22,%22plaqueNumber%22:%22%22,%22motorNumber%22:%22%22,%22motorNumberOperator%22:%227%22,%22chassisNumber%22:%22%22,%22chassisNumberOperator%22:%227%22,%22storeHouseShowType%22:%221%22,%22havePlaque%22:%22-1%22,%22isFilterByStoreHouseStatus%22:true,%22storeHouseList%22:[%221518691%22],%22goodsStatus%22:null,%22statusId%22:%22-1%22,%22goodsDeleted%22:null,%22formType%22:1,%22searchFilter%22:%22%22,%22order%22:%22%20e.samapelItem.id%20%22,%22pageNumber%22:0,%22pageSize%22:%227%22,%22plaqueType%22:%22-1%22} at java.net.URI$Parser.fail(URI.java:2848) ~[na:1.8.0_181] at java.net.URI$Parser.checkChars(URI.java:3021) ~[na:1.8.0_181] at java.net.URI$Parser.parseHierarchical(URI.java:3111) ~[na:1.8.0_181] at java.net.URI$Parser.parse(URI.java:3053) ~[na:1.8.0_181] at java.net.URI.(URI.java:588) ~[na:1.8.0_181] at java.net.URI.create(URI.java:850) ~[na:1.8.0_181]

而有以下配置:

@Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
            @Override
            public void customize(Connector connector) {
                connector.setProperty("relaxedQueryChars", "|{}[]");
            }
        });
        return factory;
    }

哪里错了?

您需要对 URI 的查询部分中的 {} 字符进行编码。它们应分别替换为 %7B%7D

解决问题的标准方法是对{等敏感字符进行解码,但是当应用程序中有近1000个JSP文件时这些字符没有被编码,这种方式要么不可能,要么很难应用到所有使用这些字符的地方。因此,问题由 ZUUL Filter 解决,如下所示:

@Component
public class CharacterEncodingZuulFilter extends ZuulFilter {


    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 10000;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();

        Map<String, String[]> qp = new HashMap<>();
        String s = "";
        try {
            s = ctx.getRequest().getQueryString().replaceAll("\{", URLEncoder.encode("{", "UTF-8"));
            s = s.replaceAll("}", URLEncoder.encode("}", "UTF-8"));
            s = s.replaceAll("\[", URLEncoder.encode("[", "UTF-8"));
            s = s.replaceAll("]", URLEncoder.encode("]", "UTF-8"));

            HttpServletRequest request = ctx.getRequest();

            CustomRequestWrapper wrapped = new CustomRequestWrapper(request, qp, s);

            ctx.setRequest(wrapped);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return null;
    }
}