Support selective filtering of error dispatches

OncePerRequestFilter now allows sub-classes to choose whether they
should ever get involved in processing an error dispatch.

Issue: SPR-9895
This commit is contained in:
Rossen Stoyanchev
2012-10-28 07:40:50 -04:00
parent d952da2338
commit 5d04ef4c4a
8 changed files with 137 additions and 46 deletions

View File

@@ -178,6 +178,15 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
return false;
}
/**
* Returns "false" so that the filter may provide a Hibernate
* {@code Session} to each error dispatches.
*/
@Override
protected boolean shouldNotFilterErrorDispatch() {
return false;
}
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@@ -187,7 +196,6 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
boolean participate = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
boolean isFirstRequest = !asyncManager.hasConcurrentResult();
String key = getAlreadyFilteredAttributeName();
if (isSingleSession()) {
@@ -197,6 +205,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
participate = true;
}
else {
boolean isFirstRequest = !isAsyncDispatch(request);
if (isFirstRequest || !applySessionBindingInterceptor(asyncManager, key)) {
logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter");
Session session = getSession(sessionFactory);
@@ -210,8 +219,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
}
else {
// deferred close mode
Assert.state(!asyncManager.isConcurrentHandlingStarted(),
"Deferred close mode is not supported on async dispatches");
Assert.state(!isAsyncStarted(request), "Deferred close mode is not supported on async dispatches");
if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) {
// Do not modify deferred close: just set the participate flag.
participate = true;
@@ -230,7 +238,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
// single session mode
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
if (!asyncManager.isConcurrentHandlingStarted()) {
if (!isAsyncStarted(request)) {
logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter");
closeSession(sessionHolder.getSession(), sessionFactory);
}

View File

@@ -102,7 +102,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
}
/**
* The default value is "false" so that the filter may re-bind the opened
* Returns "false" so that the filter may re-bind the opened Hibernate
* {@code Session} to each asynchronously dispatched thread and postpone
* closing it until the very last asynchronous dispatch.
*/
@@ -111,6 +111,15 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
return false;
}
/**
* Returns "false" so that the filter may provide a Hibernate
* {@code Session} to each error dispatches.
*/
@Override
protected boolean shouldNotFilterErrorDispatch() {
return false;
}
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@@ -120,7 +129,6 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
boolean participate = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
boolean isFirstRequest = !asyncManager.hasConcurrentResult();
String key = getAlreadyFilteredAttributeName();
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
@@ -128,6 +136,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
participate = true;
}
else {
boolean isFirstRequest = !isAsyncDispatch(request);
if (isFirstRequest || !applySessionBindingInterceptor(asyncManager, key)) {
logger.debug("Opening Hibernate Session in OpenSessionInViewFilter");
Session session = openSession(sessionFactory);
@@ -147,7 +156,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
if (!participate) {
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
if (!asyncManager.isConcurrentHandlingStarted()) {
if (!isAsyncStarted(request)) {
logger.debug("Closing Hibernate Session in OpenSessionInViewFilter");
SessionFactoryUtils.closeSession(sessionHolder.getSession());
}

View File

@@ -126,7 +126,7 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
}
/**
* The default value is "false" so that the filter may re-bind the opened
* Returns "false" so that the filter may re-bind the opened
* {@code EntityManager} to each asynchronously dispatched thread and postpone
* closing it until the very last asynchronous dispatch.
*/
@@ -135,6 +135,15 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
return false;
}
/**
* Returns "false" so that the filter may provide an {@code EntityManager}
* to each error dispatches.
*/
@Override
protected boolean shouldNotFilterErrorDispatch() {
return false;
}
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
@@ -144,7 +153,6 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
boolean participate = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
boolean isFirstRequest = !asyncManager.hasConcurrentResult();
String key = getAlreadyFilteredAttributeName();
if (TransactionSynchronizationManager.hasResource(emf)) {
@@ -152,6 +160,7 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
participate = true;
}
else {
boolean isFirstRequest = !isAsyncDispatch(request);
if (isFirstRequest || !applyEntityManagerBindingInterceptor(asyncManager, key)) {
logger.debug("Opening JPA EntityManager in OpenEntityManagerInViewFilter");
try {
@@ -175,7 +184,7 @@ public class OpenEntityManagerInViewFilter extends OncePerRequestFilter {
if (!participate) {
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(emf);
if (!asyncManager.isConcurrentHandlingStarted()) {
if (!isAsyncStarted(request)) {
logger.debug("Closing JPA EntityManager in OpenEntityManagerInViewFilter");
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}