Spring 4 upgrade broke error page filter chain -
scenario:
have interceptor looks bogus attributes in urls , throws nosuchrequesthandlingmethodexception
if finds one. display custom 404 page.
all pages go through same filter chain set local request state, log information, , display requested page. in spring 4, stopped going through filter chain 404 page in case. still goes through if go bogus page, , 404 works, when throw nosuchrequesthandlingmethodexception
, filters don't happen.
spring 3:
1. runs filter chain main request
2. throw nosuchrequesthandlingmethodexception
3. filter chain finishes
4. new filter chain starts
5. log error page metrics
6. display nice 404 page customer
spring 4:
1. runs filter chain main request
2. throw nosuchrequesthandlingmethodexception
3. filter chain finishes
4. try log error page metrics, npe since second filter chain never started
5. display terrible blank page customer
filter code in web.xml:
<!-- filter captures httpservletrequest , httpservletresponse--> <filter> <filter-name>servletobjectfilter</filter-name> <filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class> <init-param> <param-name>targetbeanname</param-name> <param-value>xxxxxxx.servletobjectfilter</param-value> </init-param> </filter> <filter-mapping> <filter-name>servletobjectfilter</filter-name> <servlet-name>springmvc</servlet-name> <dispatcher>request</dispatcher> <dispatcher>forward</dispatcher> <dispatcher>error</dispatcher> </filter-mapping> ... <error-page> <error-code>404</error-code> <location>/errors/404</location> </error-page>
filter code:
public void dofilterinternal( httpservletrequest request, httpservletresponse response, filterchain chain ) throws servletexception, ioexception { try { getservletcontainer().setservletobjects( request, response ); chain.dofilter( request, response ); } { getservletcontainer().removeall(); }
servletcontainer:
static final threadlocal< httpservletrequest > requests = new threadlocal< httpservletrequest >(); static final threadlocal< httpservletresponse > responses = new threadlocal< httpservletresponse >(); public void setservletobjects( httpservletrequest request, httpservletresponse response ) { requests.set( request ); responses.set( response ); } public void removeall() { requests.remove(); responses.remove(); }
code fails:
public class requestresponseawarebeanpostprocessor implements beanpostprocessor { public object postprocessbeforeinitialization( object bean, string beanname ) { ... if ( bean instanceof requestaware ) { httpservletrequest request = getservletcontainer().getrequest(); if ( request == null ) { throw new illegalstateexception( "the request object null" ); } requestaware requestaware = (requestaware) bean; requestaware.setrequest( request ); } }
i "solved" problem splitting error page @controller two, 1 they're targets of internal redirects , don't filter chain, , 1 directly loaded, , filter chain. added redirect @controller interceptor blacklist, doesn't require logic or data filters. solved specific problem, i'm worried else in codebase relies on behavior.
Comments
Post a Comment