运行测试服务器的Spring Boot 2.1.7-需要使用url作为键来检查我的缓存中是否有命中,然后根据是否有缓存命中来进行操作。
我从浏览器发送了一个对https://localhost:8443/test/param=value的请求-我的过滤器收到了请求,然后使用SO上另一个答案的代码,该过滤器构造了url-过滤器代码看到url为{{ 3}} 大! 然后我的拦截器被击中了(这要感谢Theo),但是它认为URL是https://localhost:8443/test?param=value -怎么回事?如果我不截取原始的/ test网址,那么拦截器的数量就很少。
为了解决这个问题,在过滤器中,我将“真实” URL存储在ServletContext中,并且在拦截器中正确读取了该变量。似乎很糟糕,我必须这样做。现在,我已经硬编码了重定向到url / test2的决定,但是回到Chrome,我看到的是test1而不是test2的输出。
Chrome中的“网络”标签似乎建议:
我被重定向到test2,但是仅在插入了favicon请求之后(出于某种神秘的原因),但是如图所示,输出显然是test1,而不是test2。
我不明白的是devtools还显示了test2的响应:
@WebFilter(urlPatterns =“ / test”,description =“测试servlet的过滤器”,initParams = { @WebInitParam(name =“ msg”,value =“ ==>”)},filterName =“测试过滤器”) 公共类TestFilter实现了Filter {
private FilterConfig filterConfig;
@Override
public void doFilter( ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain )
throws IOException, ServletException
{
String url = getCurrentUrlFromRequest( servletRequest );
// in the debugger, url is correctly shown as
// https://localhost:8443/test/param=value
if ( null != url )
{
ServletContext s = servletRequest.getServletContext();
s.setAttribute( "realUrl", url );
}
servletResponse.getOutputStream().print( filterConfig.getInitParameter( "msg" ) );
filterChain.doFilter( servletRequest, servletResponse );
public String getCurrentUrlFromRequest( ServletRequest request )
{
if ( !( request instanceof HttpServletRequest ) ) return null;
return getCurrentUrlFromRequest( (HttpServletRequest) request );
}
public String getCurrentUrlFromRequest( HttpServletRequest request )
{
StringBuffer requestURL = request.getRequestURL();
String queryString = request.getQueryString();
if ( queryString == null ) return requestURL.toString();
return requestURL.append( '?' ).append( queryString ).toString();
}
@Override
public void destroy()
{
}
@Override
public void init( FilterConfig filterConfig ) throws ServletException
{
this.filterConfig = filterConfig;
}
}
//然后是拦截器:
@Component 公共类CheckForCacheInterceptor实现HandlerInterceptor {
@Bean
public MappedInterceptor myInterceptor()
{
CheckForCacheInterceptor ci = new CheckForCacheInterceptor();
ci.setRedirectMapping( "/test2" );
return new MappedInterceptor( null, ci );
}
private String redirectMapping;
@Override
public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler )
{
String url = (String) request.getServletContext().getAttribute( "realUrl" );
// "realUrl" has https://localhost:8443/test/param=value, but I'd like
// to get rid of hack. Problem is that right here, running the same
// exact code (copy/paste of filter's
// getCurrentUrlFromRequest( HttpServletRequest request ) method )
//which gets the correct url in the filter yields
// https://localhost:8443/favicon.ico -- where did that come from?
// TODO check cache using requestUrl as key
boolean foundInCache = false;
if ( foundInCache )
{
// TODO: somehow write cache value to response
// then send response
return false;
} else
{
try
{
// TODO: make direct request,
// get response body, then
response.sendRedirect( redirectMapping );
return false;
} catch ( IOException e )
{
e.printStackTrace();
}
}
return false;
}
所以在我的问题浮出水面之前,我会寻求帮助-这个favicon请求是如何在我的拦截器甚至没有破解原始URL之前就潜入的,为什么我无法获得原始URL我的拦截器,并且考虑到Chrome devtools显示我正在进入test2,那么输出是如何从test1 servlet而不是test2 servlet来的?
FWIW,我在Postman中得到了完全相同的行为。非常感谢您的帮助!
答案 0 :(得分:0)
我在SO上阅读了另一个答案(对不起,我没有链接)已解决了不拦截对/ test的初始get请求的问题-它说拦截器仅拦截去往Controllers的请求,所以我需要具有映射到/ test的Controller。编写了快捷控制器后,拦截器现在可以像预期的那样进行拦截。