SpringBoot如何設(shè)置404、500返回統(tǒng)一格式j(luò)son
SpringBoot默認(rèn)訪問不存在資源就會(huì)出現(xiàn)404
解決后:
主要是添加下面配置:
# 自定義 #出現(xiàn)錯(cuò)誤時(shí), 直接拋出異常 spring.mvc.throw-exception-if-no-handler-found=true #不要為我們工程中的資源文件建立映射 spring.web.resources.add-mappings=false
全局處理異常:
package com.qykhhr.dujiaoshouservice.exceptionhandler; import com.qykhhr.dujiaoshouservice.util.R; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import java.sql.SQLIntegrityConstraintViolationException; /** * 異常處理機(jī)制 * 先找到特定異常處理機(jī)制,如果沒有就會(huì)調(diào)用Exception異常處理機(jī)制 */ @ControllerAdvice @Slf4j public class GlobalExceptionHandler { /** * 指定出現(xiàn)什么異常來執(zhí)行這個(gè)方法 * @param e * @return */ @ExceptionHandler(Exception.class) @ResponseBody public R error(Exception e){ e.printStackTrace(); if (e instanceof SQLIntegrityConstraintViolationException){ return R.error().message("數(shù)據(jù)庫主鍵沖突,如是本人,請(qǐng)聯(lián)系管理員"); }else if (e instanceof org.springframework.web.servlet.NoHandlerFoundException){ return R.error().message("找不到資源,/(ㄒoㄒ)/~~"); } return R.error().message("內(nèi)部服務(wù)器錯(cuò)誤,/(ㄒoㄒ)/~~!"); } /** * 自定義異常處理 * @param e * @return */ @ExceptionHandler(DujiaoshouException.class) @ResponseBody public R error(DujiaoshouException e){ log.error(e.getMessage()); e.printStackTrace(); return R.error().code(e.getCode()).message(e.getMsg()); } }
統(tǒng)一結(jié)果返回:
package com.qykhhr.dujiaoshouservice.util; import lombok.Data; import java.util.HashMap; import java.util.Map; /** * 統(tǒng)一返回結(jié)果的類 * @author 雨林 */ @Data public class R { private Boolean success; private Integer code; private String message; private Map<String,Object> data = new HashMap<>(); // 把構(gòu)造方法私有化,只能使用提供的靜態(tài)方法 private R(){ } // 成功靜態(tài)方法 public static R ok(){ R r = new R(); r.setSuccess(true); r.setCode(ResultCode.SUCCESS); r.setMessage("成功"); return r; } // 失敗靜態(tài)方法 public static R error(){ R r = new R(); r.setSuccess(false); r.setCode(ResultCode.ERROR); r.setMessage("失敗"); return r; } public R message(String message){ this.setMessage(message); return this; } public R code(Integer code){ this.setCode(code); return this; } public R data(Map<String, Object> map){ this.setData(map); return this; } public R data(String key, Object value){ this.data.put(key, value); return this; } }
我有發(fā)現(xiàn)了一個(gè)問題,因?yàn)槲遗渲昧擞成洌?dāng)我訪問upload請(qǐng)求找不到文件時(shí),依舊返回了SpingBoot的默認(rèn)404頁面。
我的理解就是訪問/upload請(qǐng)求時(shí),SpringBoot會(huì)自動(dòng)到映射的文件夾里面去尋找文件,就會(huì)以為這個(gè)請(qǐng)求已經(jīng)被處理了,就不會(huì)報(bào)找不到處理的異常。而是報(bào)除了/error請(qǐng)求的錯(cuò)誤。
upload.image.path=/util/images/ upload.apk.path=/util/apk/ upload.crash.exception.file.path=/util/crash/
/** * 資源映射路徑,只能配置一個(gè)映射 */ @Configuration public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter { @Value("${upload.file.path}") private String uploadPath; @Value("${upload.image.path}") private String uploadImagePath; @Value("${upload.crash.exception.file.path}") private String uploadCrashExceptionFilePath; @Value("${upload.apk.path}") private String uploadApkPath; /** * 將D:\\upload下的文件映射到當(dāng)前項(xiàng)目/upload/下 * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/favicon.ico").addResourceLocations("classpath:/static/"); //addResourceHandler()里配置需要映射的文件夾,此處代表映射文件夾user下的所有資源。 //addResourceLocations()配置文件夾在系統(tǒng)中的路徑,使用絕對(duì)路徑,格式為“file:你的路徑/” 后面的 / 必須加上,否則映射失效 // registry.addResourceHandler("/upload/**").addResourceLocations("file:D:/dujiaoshouapp/"); // registry.addResourceHandler("/upload/**").addResourceLocations("file:"+uploadPath); registry.addResourceHandler("/upload/images/**").addResourceLocations("file:"+uploadImagePath); registry.addResourceHandler("/upload/crash/**").addResourceLocations("file:"+uploadCrashExceptionFilePath); registry.addResourceHandler("/upload/apk/**").addResourceLocations("file:"+uploadApkPath); } }
解決
可以看到SpringBoot最終保留了/error請(qǐng)求作為后備,未解決的請(qǐng)求都會(huì)走到/error路徑里面,我們可以定義一個(gè)攔截器,攔截這個(gè)/error請(qǐng)求,轉(zhuǎn)到我們自己定義的請(qǐng)求里面。
@Component public class ExceptionInterceptor implements HandlerInterceptor { @Autowired private RedisTemplate redisTemplate; @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (modelAndView != null){ // 防止出現(xiàn)空指針 // 請(qǐng)求轉(zhuǎn)到 / modelAndView.setViewName("/"); } } }
然后在WebConfig里面配置上攔截器
@Configuration public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter { @Autowired private ExceptionInterceptor exceptionInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(exceptionInterceptor); super.addInterceptors(registry); }
最后再定義一個(gè)Controller,處理 / 請(qǐng)求
package com.qykhhr.dujiaoshouservice.controller; import com.qykhhr.dujiaoshouservice.util.R; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j public class ExceptionController { @RequestMapping("/") public R error() { log.info("處理 /error 請(qǐng)求"); return R.error().message("訪問資源無效!"); } }
可以看到訪問的結(jié)果:
OK,我們現(xiàn)在完全是統(tǒng)一的返回格式了~!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
各種格式的編碼解碼工具類分享(hex解碼 base64編碼)
這篇文章主要介紹了各種格式的編碼解碼工具類,集成Commons-Codec、Commons-Lang及JDK提供的編解碼方法2014-01-01springboot自定義starter方法及注解實(shí)例
這篇文章主要為大家介紹了springboot自定義starter方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08