Reputation: 494
I am trying to implement a RESTful API with Spring MVC. And my coding messed up while using AOP Aspect
for my application. I need to check an authToken
in every request coming for the source, so that I can give authorization and also I need it for logging.
In my code I have several custom exception classes
inherited from another main customized exception class
which is extented from Exception. When a custom exception is thrown, I need that just expected method waiting for exception works in my Aspect class so that I can return an appropriate error JSON response.
However, in my code both methods waiting for an exception work, and I wonder whether I have written my exception classes in a correct way or not. One more thing, I don't know how to tell that my aspect class does not to work for some actions which I define.
Here is my code:
@Aspect
public class SowLoggerAOP {
protected Logger logger = Logger.getLogger("SowLoggerAOP");
@Autowired(required = true)
private HttpServletRequest request;
@Resource(name = "personService")
private PersonService personService;
@Pointcut("execution(* sow.webservice.controllers..*.*(..))")
private void selectAll(){}
@Before("execution( * sow.webservice.controllers.PersonController.*(..))")
public void logBeforeReq(JoinPoint jp) throws Exception{
String personId = request.getParameter(Consts.AUTH_TOKEN);
if (personService.isUserValid(personId)) {
logger.debug("Spring AOP! Before invocation SUCCESFULL!!!: ");
}
else {
logger.error("Person not found for the " + Consts.AUTH_TOKEN + " : " + personId);
throw new PersonNotFoundException(
"Person not found for the " + Consts.AUTH_TOKEN + " : " + personId,
ErrorCodes.PERSON_NOT_FOUND);
}
}
@AfterThrowing(pointcut = "selectAll()", throwing = "sowEx")
public SowResult throwingSowException(SowCustomException sowEx){
int errorCode = ErrorCodes.GENERAL_SYSTEM_ERROR;
if(sowEx.getErrorCode() != 0)
errorCode = sowEx.getErrorCode();
SowResult result = new SowResult(Consts.SOW_RESULT_ERROR,
errorCode,
sowEx.getMessage(),
"islem hata almistir!!");
System.out.println("There has been an exception: " + sowEx.toString());
return result;
}
@AfterThrowing(pointcut = "selectAll()", throwing = "ex")
public void throwingJavaException(Exception ex){
System.out.println("JAVA EXCEPTION IS THROWN :");
}
}
public class SowCustomException extends Exception{
private int errorCode;
public SowCustomException(){
super();
}
public SowCustomException(String errMsg){
super(errMsg);
}
public SowCustomException(String errMsg, int errorCode){
super(errMsg);
this.errorCode = errorCode;
}
public SowCustomException(int errorCode){
super();
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
}
public class PersonNotFoundException extends SowCustomException{
public PersonNotFoundException(){
super();
}
public PersonNotFoundException(String errMsg){
super(errMsg);
}
public PersonNotFoundException(String errMsg, int errorCode){
super(errMsg);
super.setErrorCode(errorCode);
}
public PersonNotFoundException(int errorCode){
super();
super.setErrorCode(errorCode);
}
}
Expected JSON must be created from that class:
public class SowResult {
public int resultCode; // 1- Succesfull, 0- Fail
public int errorCode;
public String errorString;
public String message;
public Date date;
public SowResult(int resultCode, int errorCode, String errorString,
String message) {
this.resultCode = resultCode;
this.errorCode = errorCode; // 0 - No Error
this.errorString = errorString;
this.message = message;
this.date = new Date();
}
}
Upvotes: 1
Views: 889
Reputation: 11
As Sotirios Delimanolis said, if you want to return something after intercepting a method that throws an exception, you should use @Around
. Something like this (I am trusting that your pointcut is correct):
@Around("selectAll()")
public Object handleException(ProceedingJoinPoint pjp) throws Throwable {
int errorCode = ErrorCodes.GENERAL_SYSTEM_ERROR;
if(sowEx.getErrorCode() != 0)
errorCode = sowEx.getErrorCode();
SowResult retVal = null;
try {
retVal = (SowResult) pjp.proceed();
} catch (RequestValidationException sowEx) {
//now return the error response
return new SowResult(Consts.SOW_RESULT_ERROR,
errorCode,
sowEx.getMessage(),
"islem hata almistir!!");
}
return retVal;
}
Upvotes: 1
Reputation: 279910
Unfortunately, Spring's AOP stack ignores any return value from an @AfterThrowing
advice method. It just executes it and then continues by throwing the originally thrown exception.
You might want to use an @Around
advice, wrap the proceed
call in a try-catch
block, generate your SowResult
and return it.
Upvotes: 0