I'm really very new to Spring AOP. In my application, I had configured HiddenHttpMethodFilter
that converts method parameters into HTTP methods and enables Spring to handle other HTTP methods like DELETE
, PUT
etc including GET
and POST
.
It is some times necessary to disable this functionality especially when handling multipart requests. In order to disable it at a specific request (regarding mulripart), I was using the following code.
package resolver;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartResolver;
/**
* Disables the spring multipart resolver for specific client requests and
* therefore keeps the request intact so that controllers can process it in
* whatever way they wish. This behaviour is triggered by a particular GET
* parameter in the client request so it is configurable.
* @see MultipartResolver
*/
@Aspect
public final class MultipartResolverDisablingAspect
{
/**
* GET parameter which, if present in request, enables advice.
*/
private static final String DISABLING_HTTP_REQUEST_PARAMETER_KEY = "_multipartResolverDisable";
private static boolean disablingParameterExists(final HttpServletRequest request)
{
Assert.notNull(request);
return request.getParameter(DISABLING_HTTP_REQUEST_PARAMETER_KEY) != null;
}
/**
* If above GET parameter exists in request then prompt the spring multipart
* resolver to always tell spring that request is not of type multipart.
* Spring then does not process the request any further.
* @param pjp
* @param request
* @return
* @throws Throwable
*/
@Around("isMultipartOperation() && args(request)")
public Object disableIsMultipartOperation(final ProceedingJoinPoint pjp, final HttpServletRequest request) throws Throwable
{
Assert.notNull(pjp);
Assert.notNull(request);
if (disablingParameterExists(request))
{
return Boolean.FALSE;
}
return pjp.proceed();
}
/**
* Applies to any implementation of {@linkplain MultipartResolver}
*/
@SuppressWarnings("unused")
@Pointcut("execution(public boolean " + "org.springframework.web.multipart.MultipartResolver." + "isMultipart(javax.servlet.http.HttpServletRequest))")
private void isMultipartOperation() {}
}
and in the application-context.xml
file, the following xml is required.
<aop:aspectj-autoproxy proxy-target-class="false" />
<bean class="resolver.MultipartResolverDisablingAspect" /> <!--Registers the above bean (class)-->
This code was taken from this article under the section - MULTIPART RESOLVER DISABLING ASPECT.
It is meant to disable multipart processing by HiddenHttpMethodFilter
when a GET
parameter multipartResolverDisable=1
is used as a query string as specified by the code above so that one can use commons fileupload as usual (when multipartResolverDisable=1
is supplied as a query string)
The actual question is still not in the picture. This approach was earlier working correctly in the following environment (with NetBeans 6.9.1).
Recently I have upgraded NetBeans 7.2.1 with Apache Tomcat 7.0.35 which has the Servlet API 3.0. The Spring version is the same as it was before - Spring 3.2.0.
With this updates, the approach as described above caused the following exception.
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
'org.springframework.transaction.config.internalTransactionAdvisor':
Cannot resolve reference to bean
'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0'
while setting bean property 'transactionAttributeSource'; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0':
Initialization of bean failed; nested exception is
**java.lang.IllegalArgumentException: error at ::0 can't find referenced
pointcut isMultipartOperation**
Where the isMultipartOperation()
is the last method in the above class.
There might be a small change to the code but I know a very little about AOP and cannot figure out the cause of this exception in this nice-looking code.
What is the cause of this exception? Dose it have to do something with the Servlet API?
I think you should change your around advice to
@Around("isMultipartOperation(..) && args(request)")
your pointcut annotation to
@Pointcut("execution(* org.springframework.web.multipart.MultipartResolver.isMultipart(..)) && args(request)")
and the pointcut annotated method to
private void isMultipartOperation(HttpServletRequest request) {}
From memory, I had this issue where I was trying to wrap a pointcut with some advice, and the advice had a different number of arguments to the pointcut. In your code you appear to be using @Around to target a pointcut with args(request), but your pointcut method has no such parameter.