spring mvc 的 intercept 和 DispatcherServlet ,出现异常后转 400,500的逻辑

 

问题和背景:

遇到问题,一开始死活找不到原因,也找不到error 堆栈.

找不到原因的原因,

       1. 这个堆栈是spring mvc本身打印的.

       2.更关键的是这个堆栈竟然是用debug打印出来的

        3. 但是代码里把非biz 打印的error,都统一打印到了 系统_other.log中 

 

具体细节:

1. 失败后自动转成 400.html (500.html)的逻辑探究

  1.1 先了解DispatcherServlet 框架代驾. 先pre 再调用,最后 post

  1.2 一旦失败后,打印堆栈,然后转成500

2018-12-14 19:33:58,535 [DEBUG] Resolving exception from handler [public handler.method: java.lang.reflect.UndeclaredThrowableException DefaultHandlerExceptionResolver 0b0d7b1f15447872381858935e086e

 含堆栈
2018-12-14 19:33:58,535 [DEBUG] Could not complete request DispatcherServlet 0b0d7b1f15447872381858935e086e
2018-12-14 19:33:58,536 [DEBUG] DispatcherServlet with name 'dispatcher' processing GET request for [/500.htm] DispatcherServlet 0b0d7b1f15447872381858935e086e

 

2018-12-14 18:05:31,864 [DEBUG] DispatcherServlet with name 'dispatcher' processing GET request for [/500.htm] DispatcherServlet 0b0d7b1f15447819316421804e0871
2018-12-14 18:05:31,864 [DEBUG] Looking up handler method for path /500.htm RequestMappingHandlerMapping 0b0d7b1f15447819316421804e0871
2018-12-14 18:05:31,864 [DEBUG] Did not find handler method for [/500.htm] RequestMappingHandlerMapping 0b0d7b1f15447819316421804e0871
2018-12-14 18:05:31,864 [DEBUG] Matching patterns for request [/500.htm] are [/**] SimpleUrlHandlerMapping 0b0d7b1f15447819316421804e0871
2018-12-14 18:05:31,864 [DEBUG] URI Template variables for request [/500.htm] are {} SimpleUrlHandlerMapping 0b0d7b1f15447819316421804e0871
2018-12-14 18:05:31,864 [DEBUG] Mapping [/500.htm] to HandlerExecutionChain with handler [org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler@6773adcf] and 1 interceptor SimpleUrlHandlerMapping 0b0d7b1f15447819316421804e0871
2018-12-14 18:05:31,864 [DEBUG] Last-Modified value for [/500.htm] is: -1 DispatcherServlet 0b0d7b1f15447819316421804e0871
2018-12-14 18:05:31,865 [DEBUG] Null ModelAndView returned to DispatcherServlet with name 'dispatcher': assuming HandlerAdapter completed request handling DispatcherServlet 0b0aac0a15447819318651431d08dd
2018-12-14 18:05:31,865 [DEBUG] Successfully completed request DispatcherServlet 0b0aac0a15447819318651431d08dd

 

附录

logback.xml 的自动把error日志过滤出来.
 <!-- 系统日志 -->
<root level="${lippi_meetingroom_log_level}">
   <!-- 不要把业务日志记录在这里 -->
       <appender-ref ref="ROOT_APPENDE_OTHER"/>
   <!-- 要求配置报警,出现一个error就报 -->
   <appender-ref ref="ROOT_ERROR_APPENDER" />
</root>
<appender name="ROOT_ERROR_APPENDER_SYNC" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${lippi_meetingroom_log_output}/lippi_meetingroom_error.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <fileNamePattern>${lippi_meetingroom_log_output}/lippi_meetingroom_error.log.%d{yyyy-MM-dd}</fileNamePattern>
    </rollingPolicy>
   <encoder>  
           <pattern>%date [%level] [${lippi_meetingroom_current_environment}] %msg %X{EAGLE_TRACE_ID}%n</pattern>
           <charset>UTF-8</charset>
       </encoder>
   <filter class="ch.qos.logback.classic.filter.LevelFilter">  
           <level>ERROR</level>
           <onMatch>ACCEPT</onMatch>  
           <onMismatch>DENY</onMismatch>  
       </filter>
</appender>
   <appender name ="ROOT_ERROR_APPENDER" class= "ch.qos.logback.classic.AsyncAppender">  
       <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->  
       <discardingThreshold>0</discardingThreshold>  
       <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->  
       <queueSize>1024</queueSize>  
       <neverBlock>true</neverBlock>
       <!-- 添加附加的appender,最多只能添加一个 -->  
       <appender-ref ref ="ROOT_ERROR_APPENDER_SYNC"/>  
   </appender>

 

日志:

2018-12-14 19:33:58,203 [DEBUG] method  0b0d7b1f15447872381858935e086e
java.lang.Exception: null
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
 

        ======

        2018-12-14 19:36:11,198 [DEBUG] Filter postHandle 
java.lang.Exception: null
  at org.springframework.web.servlet.HandlerExecutionChain.applyPostHandle(HandlerExecutionChain.java:149)
  at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:934)
  at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
  at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
  at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
  at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
  at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
  at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
  at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
  at com.taobao.eagleeye.EagleEyeFilter.doFilter(EagleEyeFilter.java:106)
  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
  at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:410)
  at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1043)
  at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1721)
  at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1147)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
  at java.lang.Thread.run(Thread.java:834)

------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring和MyBatis整合的情况下,可以通过在MyBatis的配置文件中配置一个插件来实现下划线驼峰。 具体操作如下: 1. 在MyBatis的配置文件中添加以下插件配置: ``` <plugins> <plugin interceptor="org.apache.ibatis.plugin.Interceptor"> <property name="properties"> <property name="helperDialect" value="mysql"/> <property name="offsetAsPageNum" value="true"/> <property name="rowBoundsWithCount" value="true"/> <property name="reasonable" value="true"/> </property> <property name="typeAliases"> <typeAlias type="com.example.domain.User" alias="User"/> </property> <property name="mapperLocations" value="classpath:com/example/mapper/*.xml"/> </plugin> </plugins> ``` 2. 在Spring的配置文件中配置一个Bean,将上一步中配置的插件添加到SqlSessionFactory中: ``` <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath:com/example/mapper/*.xml"/> <property name="plugins"> <array> <bean class="com.example.plugin.CamelCaseInterceptor"/> </array> </property> </bean> ``` 3. 编写一个插件类,实现下划线驼峰的逻辑: ``` public class CamelCaseInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { Object[] args = invocation.getArgs(); MappedStatement ms = (MappedStatement) args[0]; Object parameter = args[1]; BoundSql boundSql = ms.getBoundSql(parameter); String sql = boundSql.getSql(); // 下划线驼峰 sql = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, sql); BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject()); MappedStatement newMs = copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql)); args[0] = newMs; return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { // do nothing } private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) { MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType()); builder.resource(ms.getResource()); builder.fetchSize(ms.getFetchSize()); builder.statementType(ms.getStatementType()); builder.keyGenerator(ms.getKeyGenerator()); builder.keyProperty(StringUtils.join(ms.getKeyProperties(), ",")); builder.timeout(ms.getTimeout()); builder.parameterMap(ms.getParameterMap()); builder.resultMaps(ms.getResultMaps()); builder.cache(ms.getCache()); builder.useCache(ms.isUseCache()); return builder.build(); } } ``` 通过以上步骤,即可实现在Spring和MyBatis整合的情况下将数据库中下划线命名的字段换为驼峰命名的字段。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值