配置springboot在訪問404時(shí)自定義返回結(jié)果以及統(tǒng)一異常處理

在搭建項(xiàng)目框架的時(shí)候用的是springboot但惶,想統(tǒng)一處理異常,但是發(fā)現(xiàn)404的錯(cuò)誤總是捕捉不到,總是返回的是springBoot自帶的錯(cuò)誤結(jié)果信息。

如下是springBoot自帶的錯(cuò)誤結(jié)果信息:



{

? "timestamp": 1492063521109,

? "status": 404,

? "error": "Not Found",

? "message": "No message available",

? "path": "/rest11/auth"

}



配置文件中加上如下配置:

properties格式:

#出現(xiàn)錯(cuò)誤時(shí), 直接拋出異常

spring.mvc.throw-exception-if-no-handler-found=true

#不要為我們工程中的資源文件建立映射

spring.resources.add-mappings=false

yml格式:

spring:

#出現(xiàn)錯(cuò)誤時(shí), 直接拋出異常(便于異常統(tǒng)一處理摇予,否則捕獲不到404)

? mvc:

? ? throw-exception-if-no-handler-found: true

#不要為我們工程中的資源文件建立映射

? resources:

? ? add-mappings: false


下面是我SpringMVC-config配置代碼,里面包含統(tǒng)一異常處理代碼吗跋,都貼上:



package com.qunyi.jifenzhi_zx.core.config;

import com.alibaba.druid.pool.DruidDataSource;

import com.alibaba.druid.support.http.StatViewServlet;

import com.alibaba.druid.support.http.WebStatFilter;

import com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator;

import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.serializer.SerializerFeature;

import com.alibaba.fastjson.support.config.FastJsonConfig;

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

import com.qunyi.jifenzhi_zx.core.Const;

import com.qunyi.jifenzhi_zx.core.base.exception.ServiceException;

import com.qunyi.jifenzhi_zx.core.base.result.ResponseMsg;

import com.qunyi.jifenzhi_zx.core.base.result.Result;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.web.servlet.FilterRegistrationBean;

import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;

import org.springframework.boot.web.servlet.ServletRegistrationBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.http.converter.HttpMessageConverter;

import org.springframework.web.context.request.RequestContextListener;

import org.springframework.web.method.HandlerMethod;

import org.springframework.web.servlet.HandlerExceptionResolver;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.NoHandlerFoundException;

import org.springframework.web.servlet.config.annotation.CorsRegistry;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.nio.charset.Charset;

import java.util.List;

/**

* Spring MVC 配置

*

* @author xujingyang

* @date 2018/05/25

*/

@Configuration

public class WebMvcConfigurer extends WebMvcConfigurerAdapter {

? ? private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class);

? ? @Value("${spring.profiles.active}")

? ? private String env;//當(dāng)前激活的配置文件

? ? //使用阿里 FastJson 作為JSON MessageConverter

? ? @Override

? ? public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

? ? ? ? FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();

? ? ? ? FastJsonConfig config = new FastJsonConfig();

? ? ? ? config.setSerializerFeatures(SerializerFeature.WriteMapNullValue,//保留空的字段

? ? ? ? ? ? ? ? SerializerFeature.WriteNullStringAsEmpty,//String null -> ""

? ? ? ? ? ? ? ? SerializerFeature.WriteNullNumberAsZero);//Number null -> 0

? ? ? ? converter.setFastJsonConfig(config);

? ? ? ? converter.setDefaultCharset(Charset.forName("UTF-8"));

? ? ? ? converters.add(converter);

? ? }

? ? //統(tǒng)一異常處理

? ? @Override

? ? public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {

? ? ? ? exceptionResolvers.add(new HandlerExceptionResolver() {

? ? ? ? ? ? public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) {

? ? ? ? ? ? ? ? ResponseMsg result;

? ? ? ? ? ? ? ? if (e instanceof ServiceException) {//業(yè)務(wù)失敗的異常侧戴,如“賬號或密碼錯(cuò)誤”

? ? ? ? ? ? ? ? ? ? result = new ResponseMsg("501", "業(yè)務(wù)層出錯(cuò):" + e.getMessage());

? ? ? ? ? ? ? ? ? ? logger.info(e.getMessage());

? ? ? ? ? ? ? ? } else if (e instanceof NoHandlerFoundException) {

? ? ? ? ? ? ? ? ? ? result = new ResponseMsg("404", "接口 [" + request.getRequestURI() + "] 不存在");

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? result = new ResponseMsg("500", "接口 [" + request.getRequestURI() + "] 錯(cuò)誤,請聯(lián)系管理員跌宛!");

? ? ? ? ? ? ? ? ? ? String message;

? ? ? ? ? ? ? ? ? ? if (handler instanceof HandlerMethod) {

? ? ? ? ? ? ? ? ? ? ? ? HandlerMethod handlerMethod = (HandlerMethod) handler;

? ? ? ? ? ? ? ? ? ? ? ? message = String.format("接口 [%s] 出現(xiàn)異常酗宋,方法:%s.%s,異常摘要:%s",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? request.getRequestURI(),

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? handlerMethod.getBean().getClass().getName(),

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? handlerMethod.getMethod().getName(),

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? e.getMessage());

? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? message = e.getMessage();

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? logger.error(message, e);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? responseResult(response, result);

? ? ? ? ? ? ? ? return new ModelAndView();

? ? ? ? ? ? }

? ? ? ? });

? ? }

? ? //解決跨域問題

? ? @Override

? ? public void addCorsMappings(CorsRegistry registry) {

? ? ? ? registry.addMapping("/**") // **代表所有路徑

? ? ? ? ? ? ? ? .allowedOrigins("*") // allowOrigin指可以通過的ip疆拘,*代表所有蜕猫,可以使用指定的ip,多個(gè)的話可以用逗號分隔入问,默認(rèn)為*

? ? ? ? ? ? ? ? .allowedMethods("GET", "POST", "HEAD", "PUT", "DELETE") // 指請求方式 默認(rèn)為*

? ? ? ? ? ? ? ? .allowCredentials(false) // 支持證書丹锹,默認(rèn)為true

? ? ? ? ? ? ? ? .maxAge(3600) // 最大過期時(shí)間,默認(rèn)為-1

? ? ? ? ? ? ? ? .allowedHeaders("*");

? ? }

? ? //添加攔截器

? ? @Override

? ? public void addInterceptors(InterceptorRegistry registry) {

? ? ? ? //接口登錄驗(yàn)證攔截器

? ? ? ? if (!"dev".equals(env)) { //開發(fā)環(huán)境忽略登錄驗(yàn)證

? ? ? ? ? ? registry.addInterceptor(new HandlerInterceptorAdapter() {

? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

? ? ? ? ? ? ? ? ? ? //驗(yàn)證登錄

? ? ? ? ? ? ? ? ? ? Object obj = request.getSession().getAttribute(Const.LOGIN_SESSION_KEY);

? ? ? ? ? ? ? ? ? ? if (obj != null) {

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? logger.warn("請先登錄芬失!==> 請求接口:{}楣黍,請求IP:{},請求參數(shù):{}",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap()));

? ? ? ? ? ? ? ? ? ? ? ? responseResult(response, new ResponseMsg(Result.SIGNERROR));

? ? ? ? ? ? ? ? ? ? ? ? return false;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? });

? ? ? ? }

? ? }

? ? private void responseResult(HttpServletResponse response, ResponseMsg result) {

? ? ? ? response.setCharacterEncoding("UTF-8");

? ? ? ? response.setHeader("Content-type", "application/json;charset=UTF-8");

? ? ? ? response.setStatus(200);

? ? ? ? try {

? ? ? ? ? ? response.getWriter().write(JSON.toJSONString(result));

? ? ? ? } catch (IOException ex) {

? ? ? ? ? ? logger.error(ex.getMessage());

? ? ? ? }

? ? }

? ? private String getIpAddress(HttpServletRequest request) {

? ? ? ? String ip = request.getHeader("x-forwarded-for");

? ? ? ? if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

? ? ? ? ? ? ip = request.getHeader("Proxy-Client-IP");

? ? ? ? }

? ? ? ? if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

? ? ? ? ? ? ip = request.getHeader("WL-Proxy-Client-IP");

? ? ? ? }

? ? ? ? if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

? ? ? ? ? ? ip = request.getHeader("HTTP_CLIENT_IP");

? ? ? ? }

? ? ? ? if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

? ? ? ? ? ? ip = request.getHeader("HTTP_X_FORWARDED_FOR");

? ? ? ? }

? ? ? ? if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

? ? ? ? ? ? ip = request.getRemoteAddr();

? ? ? ? }

? ? ? ? // 如果是多級代理棱烂,那么取第一個(gè)ip為客戶端ip

? ? ? ? if (ip != null && ip.indexOf(",") != -1) {

? ? ? ? ? ? ip = ip.substring(0, ip.indexOf(",")).trim();

? ? ? ? }

? ? ? ? return ip;

? ? }

? ? /**

? ? * druidServlet注冊

? ? */

? ? @Bean

? ? public ServletRegistrationBean druidServletRegistration() {

? ? ? ? ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet());

? ? ? ? registration.addUrlMappings("/druid/*");

? ? ? ? return registration;

? ? }

? ? /**

? ? * druid監(jiān)控 配置URI攔截策略

? ? *

? ? * @return

? ? */

? ? @Bean

? ? public FilterRegistrationBean druidStatFilter() {

? ? ? ? FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());

? ? ? ? // 添加過濾規(guī)則.

? ? ? ? filterRegistrationBean.addUrlPatterns("/*");

? ? ? ? // 添加不需要忽略的格式信息.

? ? ? ? filterRegistrationBean.addInitParameter("exclusions", "/web_frontend/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid,/druid/*,/error,/login*");

? ? ? ? // 用于session監(jiān)控頁面的用戶名顯示 需要登錄后主動(dòng)將username注入到session里

? ? ? ? filterRegistrationBean.addInitParameter("principalSessionName", "username");

? ? ? ? return filterRegistrationBean;

? ? }

? ? /**

? ? * druid數(shù)據(jù)庫連接池監(jiān)控

? ? */

? ? @Bean

? ? public DruidStatInterceptor druidStatInterceptor() {

? ? ? ? return new DruidStatInterceptor();

? ? }

? ? /**

? ? * druid數(shù)據(jù)庫連接池監(jiān)控

? ? */

? ? @Bean

? ? public BeanTypeAutoProxyCreator beanTypeAutoProxyCreator() {

? ? ? ? BeanTypeAutoProxyCreator beanTypeAutoProxyCreator = new BeanTypeAutoProxyCreator();

? ? ? ? beanTypeAutoProxyCreator.setTargetBeanType(DruidDataSource.class);

? ? ? ? beanTypeAutoProxyCreator.setInterceptorNames("druidStatInterceptor");

? ? ? ? return beanTypeAutoProxyCreator;

? ? }

? ? /**

? ? * RequestContextListener注冊

? ? */

? ? @Bean

? ? public ServletListenerRegistrationBean<RequestContextListener> requestContextListenerRegistration() {

? ? ? ? return new ServletListenerRegistrationBean<>(new RequestContextListener());

? ? }

? ? /**

? ? * 將swagger-ui.html 添加 到 resources目錄下

? ? *

? ? * @param registry

? ? */

? ? @Override

? ? public void addResourceHandlers(ResourceHandlerRegistry registry) {

? ? ? ? registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");

? ? ? ? registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");

? ? ? ? registry.addResourceHandler("/web_frontend/**").addResourceLocations("classpath:/web_frontend/");

? ? }

}





?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末租漂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子颊糜,更是在濱河造成了極大的恐慌哩治,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衬鱼,死亡現(xiàn)場離奇詭異业筏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鸟赫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門蒜胖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來消别,“玉大人,你說我怎么就攤上這事台谢⊙翱瘢” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵朋沮,是天一觀的道長蛇券。 經(jīng)常有香客問我,道長樊拓,這世上最難降的妖魔是什么纠亚? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮骑脱,結(jié)果婚禮上菜枷,老公的妹妹穿的比我還像新娘。我一直安慰自己叁丧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布岳瞭。 她就那樣靜靜地躺著拥娄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瞳筏。 梳的紋絲不亂的頭發(fā)上稚瘾,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音姚炕,去河邊找鬼摊欠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛柱宦,可吹牛的內(nèi)容都是我干的些椒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼掸刊,長吁一口氣:“原來是場噩夢啊……” “哼免糕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起忧侧,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤石窑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后蚓炬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體松逊,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年肯夏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了经宏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片楼咳。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖烛恤,靈堂內(nèi)的尸體忽然破棺而出母怜,到底是詐尸還是另有隱情,我是刑警寧澤缚柏,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布苹熏,位于F島的核電站,受9級特大地震影響币喧,放射性物質(zhì)發(fā)生泄漏轨域。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一杀餐、第九天 我趴在偏房一處隱蔽的房頂上張望干发。 院中可真熱鬧,春花似錦史翘、人聲如沸枉长。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽必峰。三九已至,卻和暖如春钻蹬,著一層夾襖步出監(jiān)牢的瞬間吼蚁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工问欠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肝匆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓顺献,卻偏偏與公主長得像旗国,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子滚澜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容