2017-07-01 2 views
2

Ich bin neu im Frühjahr, und versuchen, den AOP-Aspekt verwenden, um alle möglichen Ausnahmen in meinem Programm zu behandeln. Es funktioniert gut, außer für die Anfrage Para Parser Ausnahme, denn mein Aspekt kann es nicht abfangen. Der Fall ist wie folgt: Das ist mein Aspect CodeWie Spring-Aspekt fangen Ausnahme von Para-Parser-Ausnahme in Anforderung

@Aspect 
@Order(5) 
@Component 
public class WebLogAspect { 
    private static final Logger LOG = LoggerFactory.getLogger(WebLogAspect.class); 
    @Pointcut("execution(public * com.test.api..*.*(..))") 
    public void webLog() {} 

    @AfterThrowing(pointcut = "webLog()", throwing = "e") 
    public void afterThrowing(Throwable e) { 

     LOG.error(e.getMessage(), e); 
    } 
} 

Dann kommt der Controller Teil, dessen Paketpfad genau in dem Aspect Pointcut enthalten ist.

@RestController 
public class TestController { 

    @RequestMapping("/test") 
    public Long testApi(
    @RequestParam(value = "para", required = true)Long testPara) { 
     /*   
     do some thing; 
     */ 
     return testPara; 
    } 
} 

Die Sache ist, wenn ich eine Anfrage wie „127.0.0.1:9999/test?para=ABC“ senden, The testApi eine MethodArgumentTypeMismatchException, aber es wird nicht mein Aspect werfen gefangen werden. Jedoch kann jede andere Ausnahme, die in "tue some thing" ausgelöst wird, gefangen werden.

Also, ich bin verwirrt, ob meine Konfiguration auf Aspekt falsch ist, oder der Aspekt kann einfach solche Ausnahmen nicht fangen.

Sehr zu schätzen wissen Sie Ihren Rat!

// -------------------------------------------- ------------------------------ Nach dem Kommentar von @M.Deinum füge ich einen GlobalExceptionHandler mit der Annotation "@RestControllerAdvice" hinzu. Nun können solche Ausnahmen behandelt werden, die nicht in den Controller geworfen werden.

Anfügen der vollständige Stapel Ausnahme

ERROR com.test.exception.GlobalExceptionHandler:32 - Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "ABC" 
org.springframework.web.method.annotation.*MethodArgumentTypeMismatchException*: Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "ABC" 
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:128) 
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) 
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:160) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1712) 
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:247) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:105) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1699) 
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582) 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) 
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) 
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) 
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180) 
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512) 
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) 
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112) 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) 
    at org.eclipse.jetty.server.Server.handle(Server.java:534) 
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320) 
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) 
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) 
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) 
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) 
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) 
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) 
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.NumberFormatException: For input string: "ABC" 
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 
    at java.lang.Long.parseLong(Long.java:589) 
    at java.lang.Long.valueOf(Long.java:803) 
    at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:211) 
    at org.springframework.beans.propertyeditors.CustomNumberEditor.setAsText(CustomNumberEditor.java:113) 
    at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.java:468) 
    at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.java:441) 
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:199) 
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:108) 
    at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:64) 
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:47) 
    at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:713) 
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:120) 
    ... 61 more 
+0

Sind Sie sicher, dass MethodArgumentTypeMismatchException innerhalb der TestApi-Methode geworfen wird? Ich denke, es wird von einem anderen Ort geworfen und dann nur in testApi selbst – fg78nc

+0

propagiert. Es kann Ihre Ausnahme nicht abfangen. Die Ausnahme wird ausgelöst, bevor die tatsächliche Methode aufgerufen wird. Daher bevor der Aspekt ausgeführt wird. –

+0

@ fg78cn Ja, ich denke auch, dass die Ausnahme ausgelöst wird, bevor der TestApi verarbeitet wird. Aber nicht sicher dafür, und komm hier um Rat fragen:) – EricOlivier

Antwort

0

können Sie versuchen, die OncePerRequestFilter-Klasse erweitern und das Überschreiben der doFilterInternal Methode. Etwas wie folgt wird den Trick tun:

public void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, 
      final FilterChain filterChain) throws ServletException, IOException { 

    try { 
     filterChain.doFilter(request, response); 
    } catch (RuntimeException e) { 
    // Any exception thrown from your code can be handled or retrhown from here. 
    } 
}