一起来学SpringBoot(六)web开发与错误的处理
在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,那该如何减少程序异常对用户体验的影响呢?其实方法很简单,对异常进行捕获,然后给予相应的处理即可,springboot 提供了比较方便的错误处理方式。
首先呢我们新建一个springboot项目,并且新建一个百分百会出错的controller
package com.maoxs.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/web")
public class TestController {
@RequestMapping("/show")
public String show() throws Exception {
int i = 1 / 0;
return "成功";
}
}
下面来看错误的处理
ErrorController
package com.maoxs.controller;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyErrorController implements ErrorController {
@Override
public String getErrorPath() {
return "/error";
}
@RequestMapping
@ResponseBody
public String doHandleError() {
return "出错了ErrorController";
}
}
然后哪启动项目用postman测试
可以看到 出错返回了
ControllerAdvice
package com.maoxs.controller;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpServletRequest;
@ControllerAdvice
@ResponseBody
public class MyExceptionHandler {
@ExceptionHandler(Exception.class)
public String handleException(HttpServletRequest req, Exception e) throws Exception {
e.printStackTrace();
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
throw e;
}
return "出错了ExceptionHandler";
}
}
然后就可以了依然用postman进行测试
依然达到效果。
不过呢做个说明,这个控制器不能识别是不是ajax,但是可以巧妙的通过异常类来区分,
只需要更改@ExceptionHandler(value = 自定义异常.class)即可。
BasicErrorController
BasicErrorController,这个是SpringBoot的默认错误处理,也是一种全局处理方式。咱们可以模仿这种处理方式自定义自己的全局错误处理 下面定义了一个自己的BasicErrorController,可以根据自己的需求自定义errorHtml()和error()的返回值。
package com.maoxs.controller;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
@Controller
public class MyBasicErrorController extends BasicErrorController {
public MyBasicErrorController(ServerProperties serverProperties) {
super(new DefaultErrorAttributes(), serverProperties.getError());
}
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
//请求的状态
HttpStatus status = getStatus(request);
response.setStatus(getStatus(request).value());
Map<String, Object> model = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.TEXT_HTML));
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
//指定自定义的视图
return (modelAndView == null ? new ModelAndView("error/error", model) : modelAndView);
}
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.ALL));
HttpStatus status = getStatus(request);
//输出自定义的Json格式
Map<String, Object> map = new HashMap<>();
map.put("status", false);
map.put("msg", "出错了出错了");
return new ResponseEntity<>(map, status);
}
}
切记要加controller 否则不会被扫描到注册
然后进行测试先试试页面好使不
没问题在试试 ajax调用
也没问题
自定义错误页面
在spring2.x后 自定义错误页面变的更简单只需要实现ErrorViewResolver即可
package com.maoxs.controller;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Controller
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
if (status.value() == 400) {
return new ModelAndView("error/400");
}
return new ModelAndView("error/500");
}
}
映射Spring MVC之外的错误页面
添加如下配置即可
@Bean
public ErrorPageRegistrar errorPageRegistrar() {
return new MyErrorPageRegistrar();
}
private static class MyErrorPageRegistrar implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "具体你的path"));
registry.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "具体你的path"));
}
}
具体呢各种方法有各种方法的用途,我个人比较喜欢第继承BasicErrorController更灵活的处理还可以扩展。
ControllerAdvice
处理有一定的局限性只有进入 Controller
层的错误,才会由 @ControllerAdvice
处理。
本博文是基于springboot2.x 如果有什么不对的请在下方留言。
相关连接:
个人博客地址 : www.fulinlin.com
****博客地址:https://blog.****.net/qq_32867467
集合源码地址 : https://gitee.com/Maoxs/springboot-test
交流群:826953936
个人qq: 1670245232
注:如果不对联系本宝宝及时改正~~