java - Zuul 网关异常中的 java.net.URI 编码异常
问题描述
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}
引发以下异常:
引起: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] 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;
}
哪里错了?
解决方案
解决这个问题的标准方法是解码一些敏感的字符,比如{
等等,但是当有一个应用程序有接近 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;
}
}
推荐阅读
- javascript - Vuex 提交在没有有效负载参数的情况下无法工作
- ruby-on-rails - 如何命名一个名称与其在数据库中的名称不同的枚举?
- javascript - 修改作为方法内部参数传递的对象是一种不好的做法吗?
- json - 试图通过带有 JSON 正文的 POST 方法保存客户记录及其地址信息?
- php - 将 vtiger 与 mysql 连接时出现意外错误
- python - Numpy ND 数组
- python - 围绕特定节点的图集群节点
- javascript - 将新数据加载到 DOM 时如何避免 MathJAX 排版队列错误
- c - C 中 switch() 的成本
- javascript - 使用 requestAnimationFrame 启动和停止在 Barba.js 中运行 three.js 的函数?