怎么在默认异常处理建议已由其他建议处理时将其忽略

原学程将引见若何在默许异常处置修议已由其余修议处置时将其疏忽的处置办法,这篇学程是从其余处所瞅到的,而后减了1些海外法式员的疑问与解问,愿望能对于您有所赞助,佳了,上面开端进修吧。

怎么在默认异常处理建议已由其他建议处理时将其忽略 教程 第1张

成绩描写

我今朝有1个ExceptionAdvice类,它处置一切根本的(四00、四0五、四0四以及其余)异常。比方,我有1个默许修议,它处置一切的MethodArgumentNotValidExceptions并前往四00个毛病要求毛病。比方

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Error handleBadRequestException(Exception exception) {
 return buildError(extractTriggerElement(exception), exception);
}

我借有1个分歧的切进面修议,目的是处置办法ArgumentNotValidException的1个掌握器办法,由于我须要为这类情形创立自界说毛病新闻。年夜概是如许的

@AfterThrowing(pointcut = "execution(* 
package.controller.MyController*.updateSomething(*))", throwing = "ex")
private Error handleCustomError(MethodArgumentNotValidException ex) {
 return buildCustomError(ex);
}

成绩是,掌握器修议起首被挪用,但是随后它被默许的修议笼罩,是以我获得了默许的毛病新闻。
有甚么方法在其余修议曾经处置过的情形下疏忽去自默许修议的@ExceptionHandler,如许我便不妨拿回CustomError新闻?

推举谜底

您误解了@AfterThrowing

    您只能应用这类修议,以就在办法因异常加入以后、扔出它之前和能够由另外一段代码处置之前履行某些操纵。您没法变动运用法式流,比方,捕捉异常或者操纵办法成果。

    别的,因为我适才说明的缘由,@AfterThrowing修议必需前往void。您的修议乃至不该该编译,然则编译器应当会发生毛病"。这个修议必需前往void"。至多这是我的AspectJ编译器所做的(我应用的是完全的AspectJ,而没有是称为Spring AOP的粗简版,但是成果应当是雷同的。)

    有闭@AfterThrowing的具体信息,请参阅Spring AOP manual。

说明完这1面后,您能做甚么?我将在1个杂Java+AspectJ示例中向您展现,以就将Spring从等式中来失落。您不妨本身沉松天将常识教授给Spring AOP以及Spring MVC毛病处置法式:

变动运用法式流所需的是@Around修议。假如您收回这类告诉,捕捉特别办法中的毛病并前往毛病对于象,则默许的Spring异常处置法式乃至没有会瞅到存留异常,由于它曾经被圆里捕捉。即,默许处置法式将仅处置圆里未处置的一切其余毛病。

以下是1些完整自洽且可编译的示例代码:

呼应类:

我们在示例运用法式中应用它们,以就像在Spring中1样模仿正常以及毛病呼应。

package de.scrum_master.app;

public interface Response {
  String getMessage();
}
package de.scrum_master.app;

public class NormalResponse implements Response {
  private String message = "OK";

  @Override
  public String getMessage() {
 return message;
  }

  @Override
  public String toString() {
 return "NormalResponse [message=" + message + "]";
  }
}
package de.scrum_master.app;

public class ErrorResponse implements Response {
  private String message;
  private Exception exeception;

  public ErrorResponse(String message, Exception exeception) {
 this.message = message;
 this.exeception = exeception;
  }

  @Override
  public String getMessage() {
 return message;
  }

  public Exception getExeception() {
 return exeception;
  }

  @Override
  public String toString() {
 return "ErrorResponse [message=" + message + ", exeception=" + exeception + "]";
  }
}

启动法式运用法式:

该运用法式有二种办法,这二种办法都邑随机死成正常或者毛病呼应。办法produceSpecialException()是我们愿望由圆里稍后处置的办法。

我们经由过程try-Catch块模仿默许处置法式,而后挪用赞助器办法defaultHandler(Exception e)

package de.scrum_master.app;

import java.util.Random;

public class Application {
  private final static Random RANDOM = new Random();

  public Response produceException() throws Exception {
 if (RANDOM.nextBoolean())
throw new Exception("normal error");
 return new NormalResponse();
  }

  public Response produceSpecialException() throws Exception {
 if (RANDOM.nextBoolean())
throw new Exception("special error");
 return new NormalResponse();
  }

  public static ErrorResponse defaultHandler(Exception e) {
 return new ErrorResponse("default handler", e);
  }

  public static void main(String[] args) {
 Application application = new Application();
 for (int i = 0; i < 五; i++) {
try {
  System.out.println(application.produceException());
} catch (Exception e) {
  System.out.println(defaultHandler(e));
}
try {
  System.out.println(application.produceSpecialException());
} catch (Exception e) {
  System.out.println(defaultHandler(e));
}
 }
  }

}

有方里掌握台日记:

ErrorResponse [message=default handler, exeception=java.lang.Exception: normal error]
NormalResponse [message=OK]
ErrorResponse [message=default handler, exeception=java.lang.Exception: normal error]
ErrorResponse [message=default handler, exeception=java.lang.Exception: special error]
NormalResponse [message=OK]
NormalResponse [message=OK]
ErrorResponse [message=default handler, exeception=java.lang.Exception: normal error]
ErrorResponse [message=default handler, exeception=java.lang.Exception: special error]
NormalResponse [message=OK]
NormalResponse [message=OK]

正如您在下面瞅到的,一切毛病皆由默许处置法式处置。这其实不使人惊奇。

圆里:

该圆里仅处置&quot;特别&quot;毛病,疏忽其余毛病。

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.ErrorResponse;
import de.scrum_master.app.Response;

@Aspect
public class ErrorHandler {
  @Around("execution(de.scrum_master.app.Response produceSpecialException(..))")
  public Response handleError(ProceedingJoinPoint thisJoinPoint) throws Throwable {
 try {
return (Response) thisJoinPoint.proceed();
 }
 catch (Exception e) {
return new ErrorResponse("aspect handler", e);
 }
  }
}

戴无方里的掌握台日记:

ErrorResponse [message=default handler, exeception=java.lang.Exception: normal error]
ErrorResponse [message=aspect handler, exeception=java.lang.Exception: special error]
NormalResponse [message=OK]
ErrorResponse [message=aspect handler, exeception=java.lang.Exception: special error]
ErrorResponse [message=default handler, exeception=java.lang.Exception: normal error]
NormalResponse [message=OK]
ErrorResponse [message=default handler, exeception=java.lang.Exception: normal error]
ErrorResponse [message=aspect handler, exeception=java.lang.Exception: special error]
NormalResponse [message=OK]
NormalResponse [message=OK]

如上所述,如今某些毛病由aspect handler(&quot;特别毛病&)处置,而一切其余毛病仍由default handler(&quot;正常毛病&q;)处置。

佳了闭于怎样在默许异常处置修议已由其余修议处置时将其疏忽的学程便到这里便停止了,愿望趣模板源码网找到的这篇技巧文章能赞助到年夜野,更多技巧学程不妨在站内搜刮。