2017-07-01 1 views
2

Je suis nouveau au printemps et j'essaie d'utiliser l'aspect AOP pour gérer toutes les exceptions possibles dans mon programme. Cela fonctionne bien sauf pour l'exception Request parser, car mon aspect ne peut pas l'attraper. Le cas est la suivante: Ceci est mon code AspectComment l'aspect de démarrage du ressort intercepte l'exception de l'exception parser dans la requête

@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); 
    } 
} 

Puis vient la partie du contrôleur, son chemin de package est exactement inclus dans l'aspect Pointcut.

@RestController 
public class TestController { 

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

La chose est, si j'envoie une demande comme « 127.0.0.1:9999/test?para=ABC », Le TestAPI lancera une MethodArgumentTypeMismatchException, mais il ne sera pas pris par mon aspect. Cependant, toute autre exception soulevée dans "faire quelque chose" peut être interceptée. Donc, je suis confus, si ma configuration sur Aspect est fausse, ou l'aspect ne peut tout simplement pas attraper de telles exceptions.

Appréciez vraiment vos conseils!

// -------------------------------------------- ------------------------------ Après le commentaire de M.Deinum, j'ajoute un GlobalExceptionHandler avec l'annotation "@RestControllerAdvice". Maintenant, de telles exceptions qui ne sont pas lancées à l'intérieur du contrôleur peuvent être gérées.

la pleine exception Adjonction de la pile

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

Etes-vous sûr MethodArgumentTypeMismatchException est jeté à l'intérieur méthode TestAPI? Je suppose qu'il est jeté de l'autre endroit et ensuite propagé dans testApi lui-même – fg78nc

+0

Il ne peut pas attraper votre exception. L'exception est levée avant que la méthode réelle ne soit invoquée. Donc avant que l'aspect soit exécuté. –

+0

@ fg78cn Oui, je suppose également que l'exception est levée avant le traitement de testApi. Mais pas sûr pour cela, et venez ici demander conseil:) – EricOlivier

Répondre

0

Vous pouvez étendre la classe OncePerRequestFilter et redéfinissant la méthode doFilterInternal. Quelque chose comme suit fera l'affaire:

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. 
    } 
}