我想实现一个Http Filter来拦截对我的网站发出的一些请求。我想截取http://www.mywebsite.com/referral/userid的请求。我写了以下Filter类:
public class ReferralFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String contextPath = ((HttpServletRequest) request).getContextPath();
String requestURI = httpRequest.getRequestURI();
requestURI = StringUtils.substringAfter(requestURI, contextPath);
if(StringUtils.contains(requestURI, "/referral/")){
String referralIdentifier = StringUtils.substringAfter(requestURI, contextPath+"/referral/");
//Search the referral's user
if(referralIdentifier!=null && referralIdentifier.length()==12){
String cookieKey = "website.referral";
String cookieValue = referralIdentifier;
Cookie cookie = new Cookie(cookieKey,cookieValue);
cookie.setMaxAge(60*60*24*365);
((HttpServletResponse) response).addCookie(cookie);
//redirect to the home page angularJS app
requestURI = StringUtils.substringBeforeLast(requestURI,"/referral/")+"#";
}
}
String newURI = requestURI;
request.getRequestDispatcher(newURI).forward(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
这是我的配置:
@Configuration
@AutoConfigureAfter(CacheConfiguration.class)
public class WebConfigurer implements ServletContextInitializer, EmbeddedServletContainerCustomizer {
private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);
@Inject
private Environment env;
@Autowired(required = false)
private MetricRegistry metricRegistry;
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
log.info("Web application configuration, using profiles: {}", Arrays.toString(env.getActiveProfiles()));
EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
// some initializations
initReferralFilter(servletContext,disps);
log.info("Web application fully configured");
}
/**
* Initializes the Referral filter.
*/
private void initReferralFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) {
log.debug("Registering Referral Filter");
FilterRegistration.Dynamic referralFilter = servletContext.addFilter("referralFilter", new ReferralFilter());
referralFilter.addMappingForUrlPatterns(disps, true, "/referral/*");
}
// other methods
}
当我尝试访问http://www.mywebsite.com/referral/eRfdg54GDGd2时,我的过滤器无限执行。为什么?
由于
答案 0 :(得分:1)
您的过滤器配置为在对FORWARD
形式的某个网址执行/referral/*
时执行。当您转发到具有该表单的URL时,从您的过滤器代码中,您的过滤器会再次执行,并且一次又一次地执行,因此您有一个inifinte递归。
尝试从此行中删除DispatcherType.FORWARD
:
EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);
另一种方法是更改您的应用程序网址,以便转发到您的过滤器未拦截的网址。
除此之外,您永远不会让过滤器链继续使用。如果您不想中断请求,则必须将此行放在doFilter()
方法中:
chain.doFilter(request, response);
我不知道你是否想让链条继续下去,这只是为了澄清。