'Returning proper value from @AfterThrowing
I am new to String, SpringBoot.
Can we suppress thrown exception in a method annotated with @AfterThrowing
?
I mean when an exception is thrown, it will suppress that and will return a default value on behalf of the invoking method?
Say, I have a controller -
@RestController
public class MyRestController implements IRestController{
@Override
@GetMapping("hello-throw")
public String mustThrowException(@RequestParam(value = "name")final String name) throws RuntimeException {
System.out.println("---> mustThrowException");
if("Bakasur".equals(name)) {
throw new RuntimeException("You are not welcome here!");
}
return name + " : Welcome to the club!!!";
}
}
I have created a @AspectJ
, as follows -
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(* com.crsardar.handson.java.springboot.controller.IRestController.*(..))")
public void executionPointcut(){
}
@AfterThrowing(pointcut="executionPointcut()",
throwing="th")
public String afterThrowing(JoinPoint joinPoint, Throwable th){
System.out.println("\n\n\tMyAspect : afterThrowing \n\n");
return "Exception handeled on behalf of you!";
}
}
If I run this & hit a ULR like - http://localhost:8080/hello-throw?name=Bakasur
I will get RuntimeException
, but, I want to return a default message like - Exception handeled on behalf of you!
, can we do it using @AfterThrowing
?
I know it can be done using @Around
, but around will be called on every hit of the url, that I do not want
Solution 1:[1]
What you want to do is Exception Handling on the controller. You don't need to build it yourself, Spring already supports you with some annotations like @ExceptionHandler
and @ControllerAdvice
. Best would be to follow this example: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc#using-controlleradvice-classes
@ControllerAdvice
class GlobalControllerExceptionHandler {
@ResponseStatus(HttpStatus.CONFLICT) // 409
@ExceptionHandler(DataIntegrityViolationException.class)
public void handleConflict() {
// Nothing to do
}
}
@ControllerAdvice
class GlobalDefaultExceptionHandler {
public static final String DEFAULT_ERROR_VIEW = "error";
@ExceptionHandler(value = Exception.class)
public ModelAndView
defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
// If the exception is annotated with @ResponseStatus rethrow it and let
// the framework handle it - like the OrderNotFoundException example
// at the start of this post.
// AnnotationUtils is a Spring Framework utility class.
if (AnnotationUtils.findAnnotation
(e.getClass(), ResponseStatus.class) != null)
throw e;
// Otherwise setup and send the user to a default error-view.
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", req.getRequestURL());
mav.setViewName(DEFAULT_ERROR_VIEW);
return mav;
}
}
Solution 2:[2]
You should use the fully qualified name of the class before method's name when you're referring to a pointcut. So, you should change @AfterThrowing something like this.
@AfterThrowing(pointcut="packageName.MyAspect.executionPointcut()",
throwing="th")
Please note that packageName is full package name of MyAspect.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Ahmadreza Sedighi |