springboot默认将错误的页面重定向到类路径下的/error目录下,我们需要在该目录下设置相应的状态码页面。无需配置springboot就会根据状态码找到相应的页面进行展示数据。在实现前后端分离的基础上我们选择thymeleaf模板引擎,类似于jsp但springboot不支持jsp的解析。
springboot对于thymeleaf模板解析时会自动到类路径下的/templates/下寻找资源。可以查看org.springframework.boot.autoconfigure.thymeleaf;
包下的默认配置文件,如下图
因此我们要想从模板引擎里面拿取数据,我们需要将/error/
文件夹放到/templates
下。左图是证明springboot默认的错误目录查找路径,右图是设置默认的错误页面。
首先执行请求,遇到错误后根据返回的状态码,在默认错误路径下找到相应的错误页面显示出来。
默认的路径是在类路径下的/error
下,如果我们不叫这个名字,我们可以在application.properties
里面写上
server.error.path=/newError
自己没有创建/error
目录时默认的错误页面模板是这样的,默认页面的代码在ErrorMvcAutoConfiguration
类中
在error目录下定制自己的异常页面
@Component //@component的意思是该类是springboot中的组件 添加上该组件后 springboot就会在运行时执行该组件
public class MyErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(webRequest,includeStackTrace);
map.put("company","sofency");
//这种方式添加的异常 是默认的异常,即程序中遇到的所有异常都可以取到company
return map;
}
}
4xx.html 凡是以4开头的状态码都会到该页面里面
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<h1>status:[[${status}]]h1>
<h1>timestamp:[[${timestamp}]]h1>
<h1>message:[[${message}]]h1>
<h1>company:[[${company}]]h1>
main>
错误的页面如下:成功取到company
• 需求2:处理指定类的异常并显示数据到页面中
自定义异常类userNotExistException
public class UserNotExistException extends RuntimeException {
public UserNotExistException(){
super("用户不存在");
}
}
发送查询用户aaa请求时,如果不等于aaa则抛出异常。
@ResponseBody
@RequestMapping("/hello")
public String helloworld(@RequestParam("user") String user){
if("aaa".equals(user)){
throw new UserNotExistException();
}
return "Hello world";
}
处理异常类
@ControllerAdvice
public class MyExceptionHandler {
//ExceptionHandler(异常类)
@ExceptionHandler(UserNotExistException.class)
public String handlerException(Exception e, HttpServletRequest request){
Map<String,Object> map = new HashMap<>();
request.setAttribute("javax.servlet.error.status_code",500);//自定义状态码
map.put("code","user.not exist");
map.put("message",e.getMessage());
request.setAttribute("ext",map);//是为了将自定义设置的数据显示在浏览器
return "forward:/error";//重定向到/error下,springboot会在该路径下根据状态吗选择页面进行展示
}
}
但是上述的map仅仅是将数据放在了请求域中,在页面上还是无法拿到数据 ,而request的作用域不能在html页面进行直接解析,因此需要被themeleaf解析,所以要像设置全局异常那样添加到map中
@Component //@component的意思是该类是springboot中的组件 添加上该组件后 springboot就会在运行时执行该组件
public class MyErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> map = super.getErrorAttributes(webRequest,includeStackTrace);
map.put("company","sofency");
//这种方式添加的异常 是默认的异常,即程序中遇到的所有异常都可以取到company
//这是自己比比编写的异常处理器捕捉的异常
Map<String,Object> ext = (Map<String,Object>) webRequest.getAttribute("ext",0);//0代表是request请求的
map.put("ext",ext);
return map;
}
}
5xx.html页面的取值操作
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<h1>status:[[${status}]]h1>
<h1>message:[[${message}]]h1>
<h1>company:[[${company}]]h1>
<h1>ext:[[${ext.code}]]h1>
<h1>ext:[[${ext.message}]]h1>
main>