Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何摆脱每个方法中的try/catch方法_Java_Spring_Try Catch_Aop - Fatal编程技术网

Java 如何摆脱每个方法中的try/catch方法

Java 如何摆脱每个方法中的try/catch方法,java,spring,try-catch,aop,Java,Spring,Try Catch,Aop,我有许多rest服务的应用程序,其中大多数遵循以下模式: class RestService{ public Response execute1() { try{ // doLogicThere... return response; } catch () { // handle exception and build Response object.. return response;

我有许多rest服务的应用程序,其中大多数遵循以下模式:

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;
    }
}
您可以使用“throws”关键字来指示方法抛出某些异常。然后,当您调用该方法时,您可以简单地将调用包装在try/catch块中


请参阅:

您可以使用需要执行的方法创建一个接口。然后,您可以将该方法包装在新方法中的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 */); 
    }

}
如果您使用的是Java8,那么可以用更优雅的lambda表达式替换anonynous类


下面是一个使用lambdas的简单示例

public Response executeLambda() {
    return handleCall(() -> {
        ... // Your code here
        return response;
    });
}

JAX-WS包括一种机制,用于为REST方法可能产生的每种类型的异常创建适当的响应

对于每个异常类型,创建一个实现
ExceptionMapper
的类,其中
E
是异常的类型。您可以在
to response
方法中创建响应。您需要用注释异常映射器,以便在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();
    }
}
@Provider
公共类UserNotFoundMapper实现ExceptionMapper{
@凌驾
公共响应(UserNotFounde异常){
返回Response.status(404).entity(例如getMessage()).type(“text/plain”).build();
}
}

如果您正在使用SPring MVC构建RESTFul服务,那么使用以下注释“@ExceptionHandler(CustomExceptionForRestServices.class)”确实是一个更好的选择。在这里,您可以编写customException,或者拥有一个逗号分隔的异常类列表,这些异常类是您希望方法抛出的

@ExceptionHandler值可以设置为异常类型数组。如果抛出的异常与列表中的某个类型匹配,则将调用使用匹配的@ExceptionHandler注释的方法。如果未设置注释值,则将使用作为方法参数列出的异常类型


很像用@RequestMapping注释的标准控制器方法,@ExceptionHandler方法的方法参数和返回值非常灵活

我用普通的AspectJ创建了一个小示例,即没有任何Spring。我甚至创建了一个虚拟的
Response
类,以展示方面驱动的异常处理背后的基本机制:

虚拟响应类:

package de.scrum\u master.app;
公众课堂反应{
专用int状态码;
私有字符串消息;
公共响应(int状态代码){
this.statusCode=状态码;
开关(状态代码){
案例200:
message=“确定”;
打破
案例202:
message=“已接受”;
打破
案例401:
message=“未经授权”;
打破
违约:
message=“未知状态”;
}
}
public int getStatusCode(){
返回状态码;
}
@凌驾
公共字符串toString(){
返回“响应(statusCode=“+statusCode+”,message=“+message+”)”;
}
}
要截取的驱动程序应用程序有两种方法:

如您所见,这两种方法都随机抛出异常,这些异常应该稍后由方面捕获

package de.scrum\u master.app;
导入java.util.Random;
公共类服务{
私有静态最终随机=新随机();
公共响应请求(){
响应=新响应(RANDOM.nextBoolean()?200:401);
if(response.getStatusCode()!=200)
抛出新的RuntimeException(“请求失败:+响应”);
返回响应;
}
公共响应另一个请求(字符串参数){
响应=新响应(RANDOM.nextBoolean()?200:401);
if(response.getStatusCode()!=200)
抛出新的RuntimeException(“请求失败:+响应”);
返回响应;
}
公共静态void main(字符串[]args){
RestService RestService=新的RestService();
对于(int i=0;i<3;i++){
System.out.println(restService.someRequest());
System.out.println(restService.anotherRequest(“foo”);
}
}
}
异常处理方面:

package de.scrum\u master.aspect;
导入org.aspectj.lang.ProceedingJoinPoint;
导入org.aspectj.lang.annotation.Around;
导入org.aspectj.lang.annotation.Aspect;
导入de.scrum_master.app.Response;
@面貌
公共类ResponseErrorHandler{
@大约(“执行(de.scrum_master.app.Response*(..)”)
公共响应句柄错误(处理连接点此连接点){
System.out.println(“\n”+此连接点);
试一试{
返回(响应)thisJoinPoint.continue();
}
捕获(例外e){
System.out.println(“处理异常:+e.getMessage());
返回新的响应(202);
}
}
}
控制台日志:

执行(Response de.scrum\u master.app.RestService.someRequest())
响应(状态代码=200,消息=OK)
执行(Response de.scrum_master.app.RestService.anotherRequest(字符串))
响应(状态代码=200,消息=OK)
执行(Response de.scrum_master.app.RestService.someRequest())
响应(状态代码=200,消息=OK)
执行(Response de.scrum_master.app.RestService.anotherRequest(字符串))
处理异常:请求失败:响应(状态代码=401,消息=未授权)
响应(状态代码=202,消息=已接受)
执行(Response de.scrum_master.app.RestService.someRequest())
响应(状态代码=200,消息=OK)
执行(Response de.scrum_master.app.RestService.anotherRequest(字符串))
处理e