我有许多休息服务的应用程序,其中大多数遵循这种模式:
class RestService{
public Response execute1() {
try{
// doLogicThere...
return response;
} catch () {
// handle exception and build Response object..
return response;
}
}
public Response execute2() {
try{
// doLogicThere...
return response;
} catch() {
// handle exception and build Response object..
return response;
}
}
}
catch子句对于所有方法都是相同的,所以我希望下面有这样的模式,但是从其他地方调用try / catch。我想做一些包装这些方法。
class RestService{
public Response execute1() {
// doLogicThere...
return response;
}
public Response execute2() {
// doLogicThere...
return response;
}
}
答案 0 :(得分:2)
您可以使用需要执行的方法创建接口。然后,您可以在新方法的try catch中包装该方法。这将避免使用许多重复的try catch块。
你可以这样做:
public interface CallableClass {
public Response call();
}
...
class RestService {
private Response handleCall(CallableClass myClass) {
try {
return myClass.call();
} catch (Exception e) {
// Handle exception and return a particular response
...
}
}
public Response execute1() {
return handleCall(/* put anonymous class of type CallableClass here */);
}
public Response execute2() {
return handleCall(/* put anonymous class of type CallableClass here */);
}
}
如果您使用的是Java 8,则可以使用更优雅的lambda表达式替换anonynous类。
这是一个使用lambdas
的简单示例public Response executeLambda() {
return handleCall(() -> {
... // Your code here
return response;
});
}
答案 1 :(得分:2)
JAX-WS包含一种机制,用于为REST方法可能产生的每种类型的异常创建正确的响应。
对于每种异常类型,创建一个实现ExceptionMapper<E>
的类,其中E
是异常类型。您可以使用toResponse
方法创建回复。您需要使用@Provider
注释异常映射器,以便将其注册到JAX-RS运行时。
@Provider
public class UserNotFoundMapper implements ExceptionMapper<UserNotFoundException> {
@Override
public Response toResponse(UserNotFoundException e) {
return Response.status(404).entity(e.getMessage()).type("text/plain").build();
}
}
答案 2 :(得分:0)
您可以使用“throws”关键字来指示方法抛出某些异常。然后,当您调用该方法时,您只需将调用包装在try / catch块中即可。
请参阅:https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html
答案 3 :(得分:0)
如果您正在使用SPring MVC构建RESTFul服务,那么您可以更好地利用以下注释&#34; @ExceptionHandler(CustomExceptionForRestServices.class)&#34;。在哪里可以编写customException或者有一个逗号分隔的异常类列表,你希望你的方法可以抛出。
@ExceptionHandler值可以设置为Exception类型的数组。如果抛出的异常与列表中的某个类型匹配,则将调用使用匹配的@ExceptionHandler注释的方法。如果未设置注释值,则使用列为方法参数的异常类型。
与使用@RequestMapping注释注释的标准控制器方法非常相似,@ ExceptionHandler方法的方法参数和返回值非常灵活。
答案 4 :(得分:0)
我在简单的AspectJ中创建了一个小例子,即没有任何Spring。我甚至创建了一个虚拟Response
类,以便显示方面驱动的异常处理背后的基本机制:
虚拟回复类:
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 + ")";
}
}
有两种截获方法的驱动程序应用程序:
正如您所看到的,这两种方法都会随机抛出异常,这些异常应该稍后被某个方面捕获。
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"));
}
}
}
异常处理方面:
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);
}
}
}
控制台日志:
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)
如果您不理解答案,请随时提出后续问题。