zoukankan      html  css  js  c++  java
  • 配置springboot在访问404时自定义返回结果以及统一异常处理

    在搭建项目框架的时候用的是springboot,想统一处理异常,但是发现404的错误总是捕捉不到,总是返回的是springBoot自带的错误结果信息。

    如下是springBoot自带的错误结果信息:

    1 {
    2   "timestamp": 1492063521109,
    3   "status": 404,
    4   "error": "Not Found",
    5   "message": "No message available",
    6   "path": "/rest11/auth"
    7 }

    百度一波,发现需要配置文件中加上如下配置:

    properties格式:

    #出现错误时, 直接抛出异常
    spring.mvc.throw-exception-if-no-handler-found=true
    #不要为我们工程中的资源文件建立映射
    spring.resources.add-mappings=false

    yml格式:

    spring:
    #出现错误时, 直接抛出异常(便于异常统一处理,否则捕获不到404)
      mvc:
        throw-exception-if-no-handler-found: true
    
    #不要为我们工程中的资源文件建立映射
      resources:
        add-mappings: false

       

    下面是我SpringMVC-config配置代码,里面包含统一异常处理代码,都贴上:

      

      1 package com.qunyi.jifenzhi_zx.core.config;
      2 
      3 import com.alibaba.druid.pool.DruidDataSource;
      4 import com.alibaba.druid.support.http.StatViewServlet;
      5 import com.alibaba.druid.support.http.WebStatFilter;
      6 import com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator;
      7 import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
      8 import com.alibaba.fastjson.JSON;
      9 import com.alibaba.fastjson.serializer.SerializerFeature;
     10 import com.alibaba.fastjson.support.config.FastJsonConfig;
     11 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
     12 import com.qunyi.jifenzhi_zx.core.Const;
     13 import com.qunyi.jifenzhi_zx.core.base.exception.ServiceException;
     14 import com.qunyi.jifenzhi_zx.core.base.result.ResponseMsg;
     15 import com.qunyi.jifenzhi_zx.core.base.result.Result;
     16 import org.slf4j.Logger;
     17 import org.slf4j.LoggerFactory;
     18 import org.springframework.beans.factory.annotation.Value;
     19 import org.springframework.boot.web.servlet.FilterRegistrationBean;
     20 import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
     21 import org.springframework.boot.web.servlet.ServletRegistrationBean;
     22 import org.springframework.context.annotation.Bean;
     23 import org.springframework.context.annotation.Configuration;
     24 import org.springframework.http.converter.HttpMessageConverter;
     25 import org.springframework.web.context.request.RequestContextListener;
     26 import org.springframework.web.method.HandlerMethod;
     27 import org.springframework.web.servlet.HandlerExceptionResolver;
     28 import org.springframework.web.servlet.ModelAndView;
     29 import org.springframework.web.servlet.NoHandlerFoundException;
     30 import org.springframework.web.servlet.config.annotation.CorsRegistry;
     31 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
     32 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
     33 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
     34 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
     35 
     36 import javax.servlet.http.HttpServletRequest;
     37 import javax.servlet.http.HttpServletResponse;
     38 import java.io.IOException;
     39 import java.nio.charset.Charset;
     40 import java.util.List;
     41 
     42 /**
     43  * Spring MVC 配置
     44  *
     45  * @author xujingyang
     46  * @date 2018/05/25
     47  */
     48 @Configuration
     49 public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
     50 
     51     private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class);
     52     @Value("${spring.profiles.active}")
     53     private String env;//当前激活的配置文件
     54 
     55     //使用阿里 FastJson 作为JSON MessageConverter
     56     @Override
     57     public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
     58         FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
     59         FastJsonConfig config = new FastJsonConfig();
     60         config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,//保留空的字段
     61                 SerializerFeature.WriteNullStringAsEmpty,//String null -> ""
     62                 SerializerFeature.WriteNullNumberAsZero);//Number null -> 0
     63         converter.setFastJsonConfig(config);
     64         converter.setDefaultCharset(Charset.forName("UTF-8"));
     65         converters.add(converter);
     66     }
     67 
     68 
     69     //统一异常处理
     70     @Override
     71     public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
     72         exceptionResolvers.add(new HandlerExceptionResolver() {
     73             public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {
     74                 ResponseMsg result;
     75                 if (e instanceof ServiceException) {//业务失败的异常,如“账号或密码错误”
     76                     result = new ResponseMsg("501", "业务层出错:" + e.getMessage());
     77                     logger.info(e.getMessage());
     78                 } else if (e instanceof NoHandlerFoundException) {
     79                     result = new ResponseMsg("404", "接口 [" + request.getRequestURI() + "] 不存在");
     80                 } else {
     81                     result = new ResponseMsg("500", "接口 [" + request.getRequestURI() + "] 错误,请联系管理员!");
     82                     String message;
     83                     if (handler instanceof HandlerMethod) {
     84                         HandlerMethod handlerMethod = (HandlerMethod) handler;
     85                         message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s",
     86                                 request.getRequestURI(),
     87                                 handlerMethod.getBean().getClass().getName(),
     88                                 handlerMethod.getMethod().getName(),
     89                                 e.getMessage());
     90                     } else {
     91                         message = e.getMessage();
     92                     }
     93                     logger.error(message, e);
     94                 }
     95                 responseResult(response, result);
     96                 return new ModelAndView();
     97             }
     98 
     99         });
    100     }
    101 
    102     //解决跨域问题
    103     @Override
    104     public void addCorsMappings(CorsRegistry registry) {
    105         registry.addMapping("/**") // **代表所有路径
    106                 .allowedOrigins("*") // allowOrigin指可以通过的ip,*代表所有,可以使用指定的ip,多个的话可以用逗号分隔,默认为*
    107                 .allowedMethods("GET", "POST", "HEAD", "PUT", "DELETE") // 指请求方式 默认为*
    108                 .allowCredentials(false) // 支持证书,默认为true
    109                 .maxAge(3600) // 最大过期时间,默认为-1
    110                 .allowedHeaders("*");
    111     }
    112 
    113     //添加拦截器
    114     @Override
    115     public void addInterceptors(InterceptorRegistry registry) {
    116         //接口登录验证拦截器
    117         if (!"dev".equals(env)) { //开发环境忽略登录验证
    118             registry.addInterceptor(new HandlerInterceptorAdapter() {
    119                 @Override
    120                 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    121                     //验证登录
    122                     Object obj = request.getSession().getAttribute(Const.LOGIN_SESSION_KEY);
    123                     if (obj != null) {
    124                         return true;
    125                     } else {
    126                         logger.warn("请先登录!==> 请求接口:{},请求IP:{},请求参数:{}",
    127                                 request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap()));
    128 
    129                         responseResult(response, new ResponseMsg(Result.SIGNERROR));
    130                         return false;
    131                     }
    132                 }
    133             });
    134         }
    135     }
    136 
    137 
    138     private void responseResult(HttpServletResponse response, ResponseMsg result) {
    139         response.setCharacterEncoding("UTF-8");
    140         response.setHeader("Content-type", "application/json;charset=UTF-8");
    141         response.setStatus(200);
    142         try {
    143             response.getWriter().write(JSON.toJSONString(result));
    144         } catch (IOException ex) {
    145             logger.error(ex.getMessage());
    146         }
    147     }
    148 
    149     private String getIpAddress(HttpServletRequest request) {
    150         String ip = request.getHeader("x-forwarded-for");
    151         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    152             ip = request.getHeader("Proxy-Client-IP");
    153         }
    154         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    155             ip = request.getHeader("WL-Proxy-Client-IP");
    156         }
    157         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    158             ip = request.getHeader("HTTP_CLIENT_IP");
    159         }
    160         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    161             ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    162         }
    163         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    164             ip = request.getRemoteAddr();
    165         }
    166         // 如果是多级代理,那么取第一个ip为客户端ip
    167         if (ip != null && ip.indexOf(",") != -1) {
    168             ip = ip.substring(0, ip.indexOf(",")).trim();
    169         }
    170 
    171         return ip;
    172     }
    173 
    174 
    175     /**
    176      * druidServlet注册
    177      */
    178     @Bean
    179     public ServletRegistrationBean druidServletRegistration() {
    180         ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet());
    181         registration.addUrlMappings("/druid/*");
    182         return registration;
    183     }
    184 
    185     /**
    186      * druid监控 配置URI拦截策略
    187      *
    188      * @return
    189      */
    190     @Bean
    191     public FilterRegistrationBean druidStatFilter() {
    192         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
    193         // 添加过滤规则.
    194         filterRegistrationBean.addUrlPatterns("/*");
    195         // 添加不需要忽略的格式信息.
    196         filterRegistrationBean.addInitParameter("exclusions", "/web_frontend/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid,/druid/*,/error,/login*");
    197         // 用于session监控页面的用户名显示 需要登录后主动将username注入到session里
    198         filterRegistrationBean.addInitParameter("principalSessionName", "username");
    199         return filterRegistrationBean;
    200     }
    201 
    202 
    203     /**
    204      * druid数据库连接池监控
    205      */
    206     @Bean
    207     public DruidStatInterceptor druidStatInterceptor() {
    208         return new DruidStatInterceptor();
    209     }
    210 
    211     /**
    212      * druid数据库连接池监控
    213      */
    214     @Bean
    215     public BeanTypeAutoProxyCreator beanTypeAutoProxyCreator() {
    216         BeanTypeAutoProxyCreator beanTypeAutoProxyCreator = new BeanTypeAutoProxyCreator();
    217         beanTypeAutoProxyCreator.setTargetBeanType(DruidDataSource.class);
    218         beanTypeAutoProxyCreator.setInterceptorNames("druidStatInterceptor");
    219         return beanTypeAutoProxyCreator;
    220     }
    221 
    222     /**
    223      * RequestContextListener注册
    224      */
    225     @Bean
    226     public ServletListenerRegistrationBean<RequestContextListener> requestContextListenerRegistration() {
    227         return new ServletListenerRegistrationBean<>(new RequestContextListener());
    228     }
    229 
    230     /**
    231      * 将swagger-ui.html 添加 到 resources目录下
    232      *
    233      * @param registry
    234      */
    235     @Override
    236     public void addResourceHandlers(ResourceHandlerRegistry registry) {
    237         registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
    238         registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    239         registry.addResourceHandler("/web_frontend/**").addResourceLocations("classpath:/web_frontend/");
    240 
    241     }
    242 
    243 }
    View Code

      

      至此,所有错误异常都能捕捉到,统一处理了~~

  • 相关阅读:
    SpringBoot 第一篇:HelloWorld 跑起来
    CentOS 7.X 静默安装Oracle 12C数据库
    CentOS7 服务器连接超时自动断开问题解决
    Nexus3.0搭建私服上传JAR包 Windows10
    JQuery-FullCalendar 多数据源实现日程展示
    Maven构建 SpringMVC+Spring+MyBatis 环境整合
    Android内存越界检测工具ASAN
    Cookie、Session、Token 的区别
    Java线程池详解
    @Autowired 与@Resource的区别(详细) 转载
  • 原文地址:https://www.cnblogs.com/xujingyang/p/9103554.html
Copyright © 2011-2022 走看看