1 自动根据常见错误信息找寻页面
在项目的temlates文件夹下建立error文件夹,并自定义404、500等常见错误,springboot会在发生相应错误时自动返回对应页面
建立一个controller,可以看出除以0会报错误500
package com.tq.myblog.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class IndexController {
@GetMapping("/")
public String index(){
int a=3/0;
return "index";
}
}
对应的500页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
5000错误aa
</body>
</html>
此时访问127.0.0.1:8080可以发现已经自动跳至我们实现的页面
2 自定义错误信息
如果我们想要自己定义一些错误信息和对应页面的关系又该怎么办呢?
首先建立一个异常处理类,他会拦截所有异常返回error页面
package com.tq.myblog.handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
* Created by limi on 2017/10/13.
*/
@ControllerAdvice
public class ControllerExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHander(HttpServletRequest request, Exception e) throws Exception {
logger.error("Requst URL : {},Exception : {}", request.getRequestURL(),e);
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception", e);
mv.setViewName("error/error");
return mv;
}
}
同样访问之前的地址,我们可以发现虽然是500错误,但最后都显示我们设计的error页面
error.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<div> 自定义错误</div>
<div>
<div th:utext="'<!--'" th:remove="tag"></div>
<div th:utext="'Failed Request URL : ' + ${url}" th:remove="tag"></div>
<div th:utext="'Exception message : ' + ${exception.message}" th:remove="tag"></div>
<ul th:remove="tag">
<li th:each="st : ${exception.stackTrace}" th:remove="tag"><span th:utext="${st}" th:remove="tag"></span></li>
</ul>
<div th:utext="'-->'" th:remove="tag"></div>
</div>
</body>
</html>
此时感觉还是不太对,都显示一个页面也不行,比如我们希望404还是可以转到专门的404页面,ControllerExceptionHandler类是拦截了所有的异常,我们只需要在该类里改进一下,加入判断处理,如果是对应类的注解为状态参数,更改后为
package com.lrm.handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
* Created by limi on 2017/10/13.
*/
@ControllerAdvice
public class ControllerExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@ExceptionHandler(Exception.class)
public ModelAndView exceptionHander(HttpServletRequest request, Exception e) throws Exception {
logger.error("Requst URL : {},Exception : {}", request.getRequestURL(),e);
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
throw e;
}
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception", e);
mv.setViewName("error/error");
return mv;
}
}
同时,我们需要创建一个exception类,然后在实际运行中抛出这个异常
package com.tq.myblog;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* Created by limi on 2017/10/13.
*/
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException {
public NotFoundException() {
}
public NotFoundException(String message) {
super(message);
}
public NotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
改变一下之前的indexController类,抛出我们定义的异常
package com.tq.myblog.web;
import ch.qos.logback.classic.spi.IThrowableProxy;
import com.sun.org.apache.bcel.internal.generic.ATHROW;
import com.tq.myblog.NotFoundException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class IndexController {
@GetMapping("/")
public String index(){
String str=null;
if(str==null){
throw new NotFoundException();
}
return "index";
}
}
此时运行后,可以发现非常神奇的又回到了404页面
问题的关键在于我们定义NotFoundException类时,加了注解@ResponseStatus(HttpStatus.NOT_FOUND),在进入 ControllerExceptionHandler后,注解被识别,并被抛出相应异常。