项目遇到了这样一个问题,我们一个系统要给多个客户同时使用,但是可以要求访问的URL要有他们的名称,于是就产生了一个重定向url的需求
说到url重定向,我想很多人都不陌生,而且有现成的工具包 urlrewirter 但是好像并满足不了我们按客户定制url的的需求,于是产生了自己定义url格式的想法
思路是这样的,重写struts过滤器:struts的过滤器直接决定了一个url是否被struts所接受并交由那个action和那个方法处理,于是我将struts的默认过滤器源代码复制下来并自行定义过滤方法,按照我定义的url格式 客户名称\action名称\方法名称 struts是无法识别的,因为struts定义的uri后缀是.do 但是这个url依然是到了过滤器,只是被过滤掉了而已,在过滤器中的实际表现是组装出来的ActionMapping对象为空,于是我就在这里增加代码,当过滤器产生的ActionMapping对象是空的时候,根据uri自己组装一个ActionMapping对象,代码如下
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String uri = getUri(request);
try {
prepare.setEncodingAndLocale(request, response);
prepare.createActionContext(request, response);
prepare.assignDispatcherToThread();
if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
chain.doFilter(request, response);
} else {
request = prepare.wrapRequest(request);
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null && !uri.contains(".")) {
mapping = URLRewrite.getActionMapping(uri, request, response);
execute.executeAction(request, response, mapping);
} else if (mapping != null) {
mapping.setName(mapping.getName().toLowerCase());
mapping.setNamespace("/");
execute.executeAction(request, response, mapping);
} else {
boolean handled = execute.executeStaticResourceRequest(request, response);
if (!handled) {
chain.doFilter(request, response);
}
}
}
} finally {
prepare.cleanupRequest(request);
}
}