在一般项目中都会有400、500和404这种的异常页面,针对每个异常页面都会设计相应的页面布局和样式,也只有这样的错误页面才会让普通用户看着容易接受,而不是程序出错后将异常代码暴露在页面上,这种的用户体验...额,这种压根就没有用户体验这一说!
比如:
和:
相对来说第二种对用户来说就显得没那么"害怕"了。(原谅我用害怕这个词)
其实在Springboot中,SB是默认把异常的处理都集中到了一个ModelAndView中
上图是Springboot项目启动时各个路径的映射情况, 可以看到,默认是有两个error映射的,其中一个是针对json一个是针对html页面的。其中这些映射都是在BasicErrorController这个类下,如下图:
它是统一跳转到error这个页面了。
再来看下我们本地的controller
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {
@RequestMapping("/")
public String home(Model model) {
return "index";
}
@RequestMapping("/error500")
public void index() {
int a = 1 / 0;
System.out.println(a);
}
@RequestMapping("/error400/{id}")
public Object error400(@PathVariable("id") Integer id) {
System.out.println(id);
return id;
}
}
如上图,在访问error500的时候一定会报500,在访问error400/a时一定会报400,
添加error页面(在error页面中已经指定了"这是默认的error页面"),
那么在系统异常时就会跳到这个error页面:
切入正题,SpringBoot中有ConfigurableEmbeddedServletContainer接口(它继承自ErrorPageRegistry),
ErrorPageRegistry
上面两幅图是这个接口下的部分方法,可以看到,通过这个接口可以对SpringBoot程序进行很大程度的自定义控制,比如程序端口、session有效期等等。今天用到的就是上面最后一张图中的addErrorPages方法。
@Component
public class AppErrorPagesConfiguration {
/**
* 自定义异常处理路径
* @return
*/
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) {
configurableEmbeddedServletContainer.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"));
configurableEmbeddedServletContainer.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/error/400"));
configurableEmbeddedServletContainer.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"));
configurableEmbeddedServletContainer.addErrorPages(new ErrorPage(java.lang.Throwable.class, "/error/500"));
}
};
}
}
然后定义一个Controller去重写BasicErrorController的方法
/**
* 特别注意:这个类中的代码一定不能有问题,否则,你的程序可能会陷入死循环
*/
@Controller
@RequestMapping("/error")
@EnableConfigurationProperties({ServerProperties.class})
public class ErrorPageController implements ErrorController {
// 这儿只粘贴具体实现代码,关于项目源码会在最后附上git地址,需要的同学自行下载
/**
* 定义404的返回页面
*
* @param request
* @param response
* @return
*/
@RequestMapping(produces = "text/html", value = "404")
public ModelAndView errorHtml404(HttpServletRequest request,
HttpServletResponse response) {
response.setStatus(getStatus(request).value());
Map<String, Object> model = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.TEXT_HTML));
return new ModelAndView("error/404", model);
}
/**
* 定义400的返回页面
*
* @param request
* @param response
* @return
*/
@RequestMapping(produces = "text/html", value = "400")
public ModelAndView errorHtml400(HttpServletRequest request,
HttpServletResponse response) {
response.setStatus(getStatus(request).value());
Map<String, Object> model = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.TEXT_HTML));
return new ModelAndView("error/400", model);
}
/**
* 定义500的返回页面
*
* @param request
* @param response
* @return
*/
@RequestMapping(produces = "text/html", value = "500")
public ModelAndView errorHtml500(HttpServletRequest request,
HttpServletResponse response) {
response.setStatus(getStatus(request).value());
Map<String, Object> model = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.TEXT_HTML));
return new ModelAndView("error/500", model);
}
// 这儿只粘贴具体实现代码,关于项目源码会在最后附上git地址,需要的同学自行下载
}
然后新建三个页面,同时页面中分别标注一下具体的异常类型,如下图
此时看下项目结构
OK,测试访问效果
这就实现了异常页面的分离,以便于定制各个异常页面信息。
我可以对一个人无限的好,前提是值得。 ——慕冬雪
共同学习,写下你的评论
评论加载中...
作者其他优质文章