Spring Boot学习(一) 配置自定义错误页面的几种方式
第一种 实现ErrorPageRegistrar
创建配置类 ,注册错误页面
@Configuration
public class ErrorCodePageHandler implements ErrorPageRegistrar {
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
ErrorPage[] errorPages = new ErrorPage[2];
// 添加错误页面进行映射 当404时会跳转到/error/404的请求
errorPages[0] = new ErrorPage(HttpStatus.NOT_FOUND,"/error/404");
errorPages[1] = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
registry.addErrorPages(errorPages);
}
}
在控制器中添加处理
package com.learn.security.func.app.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Slf4j
@Controller
@EnableConfigurationProperties({ServerProperties.class})
public class ErrorPagesController implements ErrorController{
private final ErrorAttributes errorAttributes;
private final ServerProperties serverProperties;
public ErrorPagesController(ErrorAttributes errorAttributes, ServerProperties serverProperties) {
this.errorAttributes=errorAttributes;
this.serverProperties=serverProperties;
}
@RequestMapping("/404")
public ModelAndView errorHtml404(HttpServletRequest request, HttpServletResponse response, WebRequest webRequest) {
response.setStatus(HttpStatus.NOT_FOUND.value());
Map<String, Object> model = getErrorAttributes(webRequest, getErrorAttributeOptions());
model.put("queryString", request.getQueryString());
return new ModelAndView("error/404", model);
}
@RequestMapping("/403")
public ModelAndView errorHtml403(HttpServletRequest request, HttpServletResponse response, WebRequest webRequest) {
response.setStatus(HttpStatus.FORBIDDEN.value());
Map<String, Object> model = getErrorAttributes(webRequest, getErrorAttributeOptions());
model.put("queryString", request.getQueryString());
if (!String.valueOf(model.get("path")).contains(".")) {
model.put("status", HttpStatus.FORBIDDEN.value());
}
return new ModelAndView("error/403", model);
}
@RequestMapping("/400")
public ModelAndView errorHtml400(HttpServletRequest request, HttpServletResponse response, WebRequest webRequest) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
Map<String, Object> model = getErrorAttributes(webRequest, getErrorAttributeOptions());
model.put("queryString", request.getQueryString());
return new ModelAndView("error/400", model);
}
@RequestMapping("/401")
public ModelAndView errorHtml401(HttpServletRequest request, HttpServletResponse response, WebRequest webRequest) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
Map<String, Object> model = getErrorAttributes(webRequest, getErrorAttributeOptions());
model.put("queryString", request.getQueryString());
return new ModelAndView("error/401", model);
}
@RequestMapping("/500")
public ModelAndView errorHtml500(HttpServletRequest request, HttpServletResponse response, WebRequest webRequest) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
Map<String, Object> model = getErrorAttributes(webRequest, getErrorAttributeOptions());
model.put("queryString", request.getQueryString());
return new ModelAndView("error/500", model);
}
/**
*
* @return ErrorAttributeOptions
*/
protected ErrorAttributeOptions getErrorAttributeOptions() {
Set<ErrorAttributeOptions.Include> includes = new HashSet<>();
ErrorProperties error = this.serverProperties.getError();
if (error.getIncludeStacktrace() == ErrorProperties.IncludeAttribute.ALWAYS) {
includes.add(ErrorAttributeOptions.Include.STACK_TRACE);
}
if(error.getIncludeMessage() == ErrorProperties.IncludeAttribute.ALWAYS){
includes.add(ErrorAttributeOptions.Include.MESSAGE);
}
if(error.isIncludeException()){
includes.add(ErrorAttributeOptions.Include.EXCEPTION);
}
if(error.getIncludeBindingErrors() == ErrorProperties.IncludeAttribute.ALWAYS){
includes.add(ErrorAttributeOptions.Include.BINDING_ERRORS);
}
return ErrorAttributeOptions.of(includes);
}
/**
* 获取错误的信息
*
* @param webRequest
* web请求
* @param options
* 错误参数选项
* @return Map 错误参数
*/
private Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
return this.errorAttributes.getErrorAttributes(webRequest, options);
}
}
第二种 使用BasicErrorController
方式一,使用默认的路径
在templates下创建error.html界面即可
方式二,使用自定义路径,继承BasicErrorController重写errorHtml方法使其映射到自己定义的视图
mport lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Map;
@Slf4j
@Controller
@EnableConfigurationProperties({ServerProperties.class})
public class ErrorPagesController extends BasicErrorController{
@Autowired
public ErrorPagesController(ErrorAttributes errorAttributes, ServerProperties serverProperties) {
super(errorAttributes, serverProperties.getError());
}
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = this.getStatus(request);
// 获取内置信息,包含timestamp,status,message,exception,trace,errors
Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
int code = status.value();
response.setStatus(code);
ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
// 使用模版引擎,根据错误代码映射错误页面。如 404 会跳转到/error/404.html页面500会跳到/error/500.html页面
return modelAndView != null ? modelAndView : new ModelAndView("error/"+code, model);
}
}
第三种 继承HandlerInterceptorAdapter
/**
* @author hgs
* @version ErrorPageInterceptor.java, v 0.1 2018/03/04 20:52 hgs Exp $
* <p>
* 错误页面拦截器
* 替代EmbeddedServletContainerCustomizer在war中不起作用的方法
*/
@Component
public class ErrorPageInterceptor extends HandlerInterceptorAdapter {
private List<Integer> errorCodeList = Arrays.asList(404, 403, 500, 501);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
Exception {
if (errorCodeList.contains(response.getStatus())) {
response.sendRedirect("/error/" + response.getStatus());
return false;
}
return super.preHandle(request, response, handler);
}
}
// 原文: https://blog.csdn.net/lh87270202/article/details/79925951
在配置类中添加拦截
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(errorPageInterceptor);//.addPathPatterns("/action/**", "/mine/**");默认所有
super.addInterceptors(registry);
}
}
第四种 配置EmbeddedServletContainerCustomizer
注册错误页面
/**
* 配置默认错误页面(仅用于内嵌tomcat启动时)
* 使用这种方式,在打包为war后不起作用
* @return
*/
@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer () {
return container -> {
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404");
ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500");
container.addErrorPages(error404Page, error500Page);
};
// 原文: https://blog.csdn.net/lh87270202/article/details/79925951
在控制器中添加处理, 可以参考第一种
参考:
https://blog.csdn.net/TreeShu321/article/details/117391210
https://blog.csdn.net/lh87270202/article/details/79925951

浙公网安备 33010602011771号