我对Spring AOP真的很新。在我的应用程序中,我已配置HiddenHttpMethodFilter
将方法参数转换为HTTP方法,并使Spring能够处理其他HTTP方法,如DELETE
,PUT
等,包括GET
和{{1 }}
有时需要禁用此功能,尤其是在处理多部分请求时。为了在特定请求(关于mulripart)禁用它,我使用以下代码。
POST
并在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() {}
}
文件中,需要以下xml。
application-context.xml
此代码摘自this条款 - MULTIPART RESOLVER DISABLING ASPECT。
当<aop:aspectj-autoproxy proxy-target-class="false" />
<bean class="resolver.MultipartResolverDisablingAspect" /> <!--Registers the above bean (class)-->
参数GET
用作上面代码指定的查询字符串时,意味着按HiddenHttpMethodFilter
禁用多部分处理,以便可以像往常一样使用commons fileupload(当multipartResolverDisable=1
作为查询字符串提供时)
实际问题仍未出现在图片中。此方法之前在以下环境中正常工作(使用NetBeans 6.9.1)。
最近,我使用带有Servlet API 3.0的Apache Tomcat 7.0.35升级了NetBeans 7.2.1。 Spring版本和以前一样 - Spring 3.2.0。
通过此更新,上述方法会导致以下异常。
multipartResolverDisable=1
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**
是上述类中的最后一个方法。
代码可能会有一些小改动,但我对AOP知之甚少,并且无法在这个漂亮的代码中弄清楚这个异常的原因。
此异常的原因是什么?是否需要使用Servlet API做什么?
答案 0 :(得分:2)
我认为你应该改变你的建议
@Around("isMultipartOperation(..) && args(request)")
你的切入点注释
@Pointcut("execution(* org.springframework.web.multipart.MultipartResolver.isMultipart(..)) && args(request)")
和切入点注释方法
private void isMultipartOperation(HttpServletRequest request) {}
从记忆中,我遇到了这个问题,我试图用一些建议包装一个切入点,并且这个建议对切入点有不同数量的参数。在您的代码中,您似乎正在使用@Around来使用args(请求)来定位切入点,但您的切入点方法没有这样的参数。