Frage

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();
    }
}
War es hilfreich?

Lösung 2

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.

Andere Tipps

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;
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top