I have created a little example in plain AspectJ, i.e. without any Spring. I even created a dummy Response
class just so as to show the basic mechanics behind aspect-driven exception handling:
Dummy response class:
package de.scrum_master.app;
public class Response {
private int statusCode;
private String message;
public Response(int statusCode) {
this.statusCode = statusCode;
switch (statusCode) {
case 200:
message = "OK";
break;
case 202:
message = "Accepted";
break;
case 401:
message = "Unauthorized";
break;
default:
message = "Unknown status";
}
}
public int getStatusCode() {
return statusCode;
}
@Override
public String toString() {
return "Response(statusCode=" + statusCode + ", message=" + message + ")";
}
}
Driver application with two methods to be intercepted:
As you can see, both methods randomly throw exceptions which ought to be caught by an aspect later.
package de.scrum_master.app;
import java.util.Random;
public class RestService {
private static final Random RANDOM = new Random();
public Response someRequest() {
Response response = new Response(RANDOM.nextBoolean() ? 200 : 401);
if (response.getStatusCode() != 200)
throw new RuntimeException("request failed: " + response);
return response;
}
public Response anotherRequest(String argument) {
Response response = new Response(RANDOM.nextBoolean() ? 200 : 401);
if (response.getStatusCode() != 200)
throw new RuntimeException("request failed: " + response);
return response;
}
public static void main(String[] args) {
RestService restService = new RestService();
for (int i = 0; i < 3; i++) {
System.out.println(restService.someRequest());
System.out.println(restService.anotherRequest("foo"));
}
}
}
Exception handling aspect:
package de.scrum_master.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import de.scrum_master.app.Response;
@Aspect
public class ResponseErrorHandler {
@Around("execution(de.scrum_master.app.Response *(..))")
public Response handleError(ProceedingJoinPoint thisJoinPoint) {
System.out.println("\n" + thisJoinPoint);
try {
return (Response) thisJoinPoint.proceed();
}
catch (Exception e) {
System.out.println(" Handling exception: " + e.getMessage());
return new Response(202);
}
}
}
Console log:
execution(Response de.scrum_master.app.RestService.someRequest())
Response(statusCode=200, message=OK)
execution(Response de.scrum_master.app.RestService.anotherRequest(String))
Response(statusCode=200, message=OK)
execution(Response de.scrum_master.app.RestService.someRequest())
Response(statusCode=200, message=OK)
execution(Response de.scrum_master.app.RestService.anotherRequest(String))
Handling exception: request failed: Response(statusCode=401, message=Unauthorized)
Response(statusCode=202, message=Accepted)
execution(Response de.scrum_master.app.RestService.someRequest())
Response(statusCode=200, message=OK)
execution(Response de.scrum_master.app.RestService.anotherRequest(String))
Handling exception: request failed: Response(statusCode=401, message=Unauthorized)
Response(statusCode=202, message=Accepted)
Feel free to ask follow-up questions if you do not understand the answer.