配置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

 

  

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

 

转载于:https://www.cnblogs.com/xujingyang/p/9103554.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx配置php 9000,Nginx支持php配置

Nginx本身是不支持对外部程序的直接调用或者解析&#xff0c;所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux 下是socket&#xff0c;(这个socket可以是文件socket&#xff0c;也可以是ip socket)。为了调用CGI程序&#xff0c;还需要一个FastCGI的wra…

用例写到抽筋

这几天是第一次写web类的测试用例&#xff0c;不得不说&#xff0c;写web类的测试用例真是会写死人&#xff0c;每一项都要至少写一个测试用例&#xff0c;就算以一项一个用例来算&#xff0c;一个非常非常简单的网站都要写上上百个测试用例。比如说今天写的测试用例中&#xf…

ansible 判断和循环

标准循环 模式一 - name: add several usersuser: name{{ item }} statepresent groupswheelwith_items:- testuser1- testuser2 orwith_items: "{{ somelist }}" 模式2. 字典循环- name: add several usersuser: name{{ item.name }} statepresent groups{{ item.g…

Windows XP中快速识别真假SVCHOST.EXE

SVCHOST.EXE是基于NT核心技术的操作系统非常重要的进程&#xff0c;它提供许多系统服务&#xff0c;比如远程过程调用系统服务 (RPCSS)、动态主机配置协议&#xff08;DPCH) 服务等与网络相关的服务。现在广大计算机用户普遍使用的Windows XP、Windows 2003等操作系统都涉及该进…

php require 500,thinkphp5出现500错误怎么办

thinkphp5出现500错误&#xff0c;如下图所示&#xff1a;require(): open_basedir restriction in effect. File(/home/wwwroot/pic/thinkphp/start.php) is not within the allowed解决方法&#xff1a;1、我是lnmp1.4 php5.6&#xff0c;php.ini里面的open_basedir 是注释掉…

eclipse从svn导入maven项目变成普通项目解决办法

右击项目-->configure-->Convert to Maven Project转载于:https://www.cnblogs.com/zhanzhuang/p/9105463.html

php安装soap扩展

例&#xff1a; 1、编译安装 解压对应php版本安装包 进入解压后的ext目录 phpize --生成configure文件&#xff0c;报以下错误&#xff0c;可以忽略 ------------------------------------------------------------------------------ Configuring for: PHP Api Version: …

php yaf 教程,Yaf教程2:入门使用

接下来我们通过最简单的“hello yaf”例子说明 Yaf 的用法&#xff0c;然后一步步走向更加复杂的用法。Yaf的PHP官方手册位置是&#xff1a;http://php.net/manual/zh/book.yaf.php&#xff0c;这比鸟哥(Yaf作者)自己博客 http://www.laruence.com/manual/的文档要新&#xff0…

在移动端项目中使用vconsole

1.先在项目中引入 <script type"text/javascript" src"vconsole.min.js"> 2.初始化vConsole window.vConsole new window.VConsole({defaultPlugins: [system, network, element, storage], // 可以在此设定要默认加载的面板maxLogNumber: 1000 });…

如何创建路径别名

在访问页面时&#xff0c;页面地址会以 DocumentRoot所指定的路径为相对路径&#xff0c;但若不想使用指定的路径&#xff0c;则需要创建路径别名。假如DocumentRoot为/var/www/html &#xff0c;现想将/var/www/html/mail 建立别名/web/mail&#xff0c;该如何修改呢&#xff…

matlab矩阵除以一个数字,matlab矩阵中每一行数除以一个数 | 学步园

例如&#xff1a;用a中每一行数除以x中相对应的每一个数x[5 10 6 8 16 6 8 8 22 11];a[4 4 4 5 4 4 4 4 3 46 8 6 2 6 8 8 6 8 64 4 4 4 6 4 4 4 6 44 6 6 4 6 6 6 4 7 410 14 14 10 12 12 12 10 14 123 5 5 3 6 3 3 4 5 44 6 7 4 4 4 4 4 6 64 6 6 6 5 6 5 5 7 613 16 19 16 1…

Redis(四):Spring + JedisCluster操作Redis(集群)

1.maven依赖&#xff1a; <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.3</version> </dependency> 2.增加spring 配置 <!-- JedisCluster配置 --> <bean …

js对象数组转java对象数组对象数组对象数组对象,前台js数组json字符串,后台json转为对象数组的具体实现...

$("#savaUserSet").click(function(){var JSONArr[];$("i[nameeventName]").each(function() {//获取所有name属性为eventName的i标签,并遍历if(!($(this).hasClass("active"))){var eventCode$(this).attr("id");var eventName$(this…

matlab绘制烟花,[原创]利用MATLAB燃放烟花(礼花)

function firework% 烟花烟花满天飞% CopyRight&#xff1a;xiezhh(谢中华)% 2011.6.25OldHandle findobj( Type, figure, Tag, FireWork ) ;if ishandle(OldHandle)close(OldHandle) ;end% 图形窗口初始化fig figure(units,normalized,position,[0.1 0.1 0.8 0.8],...menuba…

33 -jQuery 属性操作,文档操作(未完成)

转载于:https://www.cnblogs.com/venicid/p/9110130.html

GNU C - 关于8086的内存访问机制以及内存对齐(memory alignment)

接着前面的文章&#xff0c;这篇文章就来说说menory alignment -- 内存对齐. 一、为什么需要内存对齐&#xff1f; 无论做什么事情&#xff0c;我都习惯性的问自己&#xff1a;为什么我要去做这件事情&#xff1f; 是啊&#xff0c;这可能也是个大家都会去想的问题&#xff0c;…

mysql权限说法正确的是,【多选题】下面关于修改 MySQL 配置的说法中,正确的是...

参考答案如下【单选题】4.正常枕先露分娩时&#xff0c;多选的说仰伸发生于()39、题下【单选题】人们常常用来判断一种活动是不是游戏的一项外部指标是( )面关【多选题】S-S法阶段2训练内容包括于修【判断题】痉挛性睑内翻多发生于下睑。配置【判断题】萤火虫不仅成虫会发光,其…

读取exchange邮件的未读数(转载)

protected void Page_Load(object sender, EventArgs e) { Response.Write("administrator的未读邮件数是&#xff1a;" UnReadCount("administratordomainname")); } int UnReadCount(string userMailAddress) {…

嵌入式Linux下Qt的中文显示

一般情况下&#xff0c;嵌入式Qt界面需要中文显示&#xff0c;下面总结自己在项目中用到的可行的办法 1&#xff0c;下载一种中文简体字体&#xff0c;比如我用的是”方正准圆简体“&#xff0c;把字体文件放在ARM开发板系统的Qt字库中&#xff0c;即/usr/lib/fonts下 2&#x…

Robot Framework + Selenium library + IEDriver环境搭建

转载&#xff1a;https://www.cnblogs.com/Ming8006/p/4998492.html#c.d 目录&#xff1a; 1 安装文件准备2 Robot框架结构3 环境搭建 3.1 安装Python 3.2 安装Robot Framework 3.3 安装wxPython 3.4 安装RIDE 3.5 安装Selenium2Library 3.6 安装IEDriverServer 1 安装文…