smart
smart

Reputation: 109

Use Spring Aop on Spring mvc controller

I have a Spring MVC controller throw two kind of exception:

@RequestMapping(value = "forwardRefundApply",method = RequestMethod.GET)
public ModelAndView forwardRefundApply1(String ticketNbr)throws Exception {
    if(true)
        throw new Exception();
    else
        throw new ApplicationException("test");
}

then I write a AOP class to hanlder the Exception then return Model like this:

  @Pointcut("execution(public * ..*(..))")
public void getRefundPointCut() {
}

@AfterThrowing(pointcut="getRefundPointCut()", throwing="e")
public ModelAndView throwException(Exception e){
    ModelAndView mav = null;
    if(e instanceof ApplicationException)
    {

        e.printStackTrace();
        mav = new ModelAndView(CommonConstants.ERRORPAGE);
        mav.addObject("errorMsg", "application error");
        return mav;
    }
    else{
        e.printStackTrace();

        mav  = new ModelAndView(CommonConstants.ERRORPAGE);
        mav.addObject("errorMsg", "system error");
        return mav;
    }
}

the aop is work . but the the result is error. system error:

org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoSuchMethodError

is Aspect class cannot return ModelAndView to Controller?

Upvotes: 0

Views: 3152

Answers (3)

Fawad Shah
Fawad Shah

Reputation: 1774

I haven't tested it myself but Spring AOP works with proxy objects and not the actual objects. So e is actually an instance of proxy and not of ApplicationException. So the following condition never executes to true.

if(e instanceof ApplicationException)

Easiest way of handling this would be to mark your aop setting in Spring configuration file with proxy-target-class="true".

<aop:aspectj-autoproxy proxy-target-class="true"/>

HTH

Upvotes: 0

Markus Malkusch
Markus Malkusch

Reputation: 7868

Why use AOP in this case at all? Spring comes with everything you need:

Upvotes: 6

Sotirios Delimanolis
Sotirios Delimanolis

Reputation: 279910

The NoSuchMethodError is unrelated to your question and is caused by something you haven't shown us.

As for the question

is Aspect class cannot return ModelAndView to Controller?

I couldn't find any reference to it anywhere in Spring's AOP documentation, but you can see it in the implementation.

When you declare a @AfterThrowing advice, Spring uses a AspectJAfterThrowingAdvice to handle it. Its invoke(..) method is implemented as

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
    try {
        return mi.proceed();
    }
    catch (Throwable t) {
        if (shouldInvokeOnThrowing(t)) {
            invokeAdviceMethod(getJoinPointMatch(), null, t);
        }
        throw t;
    }
}

where mi.proceed() invokes your advised method and invokeAdviceMethod(..) invokes your @AfterThrowing advice method. Notice that it does nothing with the return value. As such, you can return a ModelAndView object from a @AfterThrowing advice method, but it won't serve any purpose, it'll simply be discarded.

A possible alternative is to declare a @Around advice. Within it, you wrap the proceeding call and catch the possible exceptions, handling them appropriately

@Around(value = "getRefundPointCut()")
public ModelAndView throwException(ProceedingJoinPoint joinPoint) throws Throwable {
    ModelAndView mav = null;
    try {
        return (ModelAndView) joinPoint.proceed(); // might want to make sure that it is a ModelAndView
    } catch(ApplicationException e) {
        e.printStackTrace();
        mav = new ModelAndView("home");
        mav.addObject("errorMsg", "application error");
        return mav;
    } catch (Exception e) {
        e.printStackTrace();
        mav = new ModelAndView("home");
        mav.addObject("errorMsg", "system error");
        return mav;
    }
}

Here you return the value of the advised method if it returns correctly. Or your catch any thrown Exception and again handle it appropriately by returning a different ModelAndView.

Upvotes: 2

Related Questions