基于Zuul实现多路由参数过滤至同一Solr服务端点的问题
解决Zuul多路由转发同一端点并传递不同参数的问题
这个问题其实很好解决,你不需要为每个路由单独编写过滤器,只需要在现有的ProjectParamFilter里做一点逻辑调整就能实现需求,我给你一步步讲清楚:
第一步:配置Zuul路由规则
首先在你的配置文件(比如application.yml)里配置三个路由,让它们都指向同一个Solr API端点:
zuul: routes: api1: path: /api-zuul/api1/** url: http://mysolrserver/api/select api2: path: /api-zuul/api2/** url: http://mysolrserver/api/select api3: path: /api-zuul/api3/** url: http://mysolrserver/api/select
这样所有发往/api-zuul/api1/*、/api-zuul/api2/*、/api-zuul/api3/*的请求都会被Zuul转发到你的Solr服务器。
第二步:修改现有过滤器,动态设置参数
你现在的过滤器是固定设置collection=Project,我们只需要根据请求路径判断当前路由,然后动态替换collection参数即可,同时还可以优化shouldFilter方法,让过滤器只对这三个路由生效,避免不必要的性能消耗。
修改后的完整过滤器代码如下:
public class ProjectParamFilter extends ZuulFilter { private static Logger log = LoggerFactory.getLogger(ProjectParamFilter.class); @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 1; } @Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String path = request.getRequestURI(); // 只对目标三个路由的请求执行过滤逻辑 return path.startsWith("/api-zuul/api1/") || path.startsWith("/api-zuul/api2/") || path.startsWith("/api-zuul/api3/"); } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); String requestPath = request.getRequestURI(); Map<String, List<String>> params = new HashMap<>(); List<String> paramAll = new ArrayList<>(); List<String> paramTrue = new ArrayList<>(); List<String> paramJson = new ArrayList<>(); List<String> paramCollection = new ArrayList<>(); // 固定参数保持不变 paramAll.add("*:*"); paramTrue.add("true"); paramJson.add("json"); // 根据请求路径动态设置collection参数 if (requestPath.startsWith("/api-zuul/api1/")) { paramCollection.add("api1"); } else if (requestPath.startsWith("/api-zuul/api2/")) { paramCollection.add("api2"); } else if (requestPath.startsWith("/api-zuul/api3/")) { paramCollection.add("api3"); } params.put("q", paramAll); params.put("indent", paramTrue); params.put("wt", paramJson); params.put("collection", paramCollection); // 可选:保留原请求的其他参数(比如用户传入的otherParams) // Map<String, String[]> originalParams = request.getParameterMap(); // originalParams.forEach((key, values) -> params.put(key, Arrays.asList(values))); ctx.setRequestQueryParams(params); log.info("passed params :" + ctx.getRequestQueryParams().toString()); log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString())); return null; } }
额外说明
- 如果需要保留用户原请求中的其他参数(比如你提到的
otherParams),可以把代码中注释的部分取消注释,这样就能将用户传递的参数和我们设置的固定参数合并后一起转发到Solr。 - 这种方式不需要新增多个过滤器,通过一个过滤器就能处理所有目标路由的参数设置,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者okno
相关产品推荐
相关产品推荐

