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

时间:2019-06-08 11:31:53

标签: java spring-boot tomcat netflix-zuul

有一个Zuul应用程序正在由Spring-boot-2.1.4.RELEASE运行。

当我以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}的身份请求

引发以下异常:

  

原因:java.net.URISyntaxException:查询中的非法字符   索引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}   在java.net.URI $ Parser.fail(URI.java:2848)〜[na:1.8.0_181]在   java.net.URI $ Parser.checkChars(URI.java:3021)〜[na:1.8.0_181]在   java.net.URI $ Parser.parseHierarchical(URI.java:3111)〜[na:1.8.0_181]   在java.net.URI $ Parser.parse(URI.java:3053)〜[na:1.8.0_181]在   java.net.URI。(URI.java:588)〜[na:1.8.0_181]在   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;
    }

哪里错了?

2 个答案:

答案 0 :(得分:2)

解决问题的标准方法是解码一些敏感的字符,例如{等,但是当有一个应用程序包含近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;
    }
}

答案 1 :(得分:0)

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