运行一个测试服务器的Spring boot 2.1.7 --需要使用url作为键检查我的缓存是否命中,然后根据缓存命中与否执行操作。
我从我的浏览器发送了一个对https://localhost:8443/test/param=value的请求-我的过滤器接收了它,然后使用另一个答案中的代码,过滤器构建了url -过滤器代码看到url is https://localhost:8443/test?param=value棒极了!然后我的拦截器被击中(多亏了Theo on SO),但它认为url是https://localhost:8443/favicon.ico --这是怎么回事?如果我没有截取原始的/test url,那就算不上什么拦截器了。
为了解决这个问题,在过滤器中,我将“真正的”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;
}因此,在我的问题堆积到天花板之前,我将寻求帮助--在我的拦截器甚至还没有破解原始url之前,这个favicon请求是如何偷偷进入的,为什么我无法在拦截器中获得原始url,而且考虑到Chrome devtools显示我正在连接到test2,test1 servlet而不是test2 servlet的输出是如何产生的?
顺便说一句,我在Postman中得到了完全相同的行为。非常感谢你的帮助!
发布于 2019-08-18 22:56:20
我在SO上读到了另一个答案(对不起,我没有链接),它解决了不拦截发送给/test的初始get请求的问题--它说拦截器只拦截去往控制器的请求,所以我需要有一个映射到/test的控制器。在编写quickie控制器之后,拦截器现在可以像预期的那样进行拦截。
https://stackoverflow.com/questions/57540039
复制相似问题