SpringBoot中自定义错误页面4xx或5xx

1、只要在templates文件夹下面加上error文件夹,然后将html文件名字命名为状态码就可以出现自己定制的错误页面了

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
出现了404错误<br>
timestamp:<span th:text="${timestamp}"></span><br>
status:<span th:text="${status}"></span><br>
error:<span th:text="${error}"></span><br>
message:<span th:text="${message}"></span><br>
</body>
</html>

去访问一个项目中不存在的地址
在这里插入图片描述

2、如果是5xx的错误类似下面这个例子

1、创建一个Exception用来待会抛出异常
package org.xjj.demo98001.exception;

public class MyException extends RuntimeException{
    public MyException() {
        super("出现了异常");
    }
}
2、controller,当传值为123的时候手动抛出异常
package org.xjj.demo98001.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.xjj.demo98001.exception.MyException;

@Controller
public class MyController {
    @RequestMapping("/toException")
    public String toException(@RequestParam int id){
        if(id==123)
            throw new MyException();
        return "success";
    }
}
3、在5xx的页面上输出相关信息(但是在SpringBoot2中要对application.properties进行配置,否则不会出现exception)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
出现了500错误<br>
timestamp:<span th:text="${timestamp}"></span><br>
status:<span th:text="${status}"></span><br>
exception:<span th:text="${exception}"></span><br>
message:<span th:text="${message}"></span><br>
</body>
</html>
4、对application.properties的配置
#用来配置错误页面的时候可以拿到exception
server.error.include-exception=true

去发送controller中定制好的请求 http://localhost:8080/toException?id=123

在这里插入图片描述

3、原理:对于错误页面的配置都在ErrorMvcAutoConfiguration(以下四个bean是对错误页面的主要配置)

1、ErrorPageCustomizer
@Bean
public ErrorMvcAutoConfiguration.ErrorPageCustomizer errorPageCustomizer() {
    return new ErrorMvcAutoConfiguration.ErrorPageCustomizer(this.serverProperties, this.dispatcherServletPath);//1、要返回ErrorPageCustomizer这个内部类
}
private static class ErrorPageCustomizer implements ErrorPageRegistrar, Ordered {
    private final ServerProperties properties;
    private final DispatcherServletPath dispatcherServletPath;

    protected ErrorPageCustomizer(ServerProperties properties, DispatcherServletPath dispatcherServletPath) {//2、需要获得跳转的路径
        this.properties = properties;
        this.dispatcherServletPath = dispatcherServletPath;
    }

    public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
        ErrorPage errorPage = new ErrorPage(this.dispatcherServletPath.getRelativePath(this.properties.getError().getPath()));//3、getPath用来获得跳转路径
        errorPageRegistry.addErrorPages(new ErrorPage[]{errorPage});
    }

    public int getOrder() {
        return 0;
    }
}
public class ErrorProperties {
    @Value("${error.path:/error}")
    private String path = "/error";//4、获取跳转路径是在error文件夹下
}
2、BasicErrorController
@Bean
@ConditionalOnMissingBean(
    value = {ErrorController.class},
    search = SearchStrategy.CURRENT
)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
    return new BasicErrorController(errorAttributes, this.serverProperties.getError(), this.errorViewResolvers);//5、要返回这个new的类
}
@Controller//这是一个controller就是相当于每个error请求也就是通过controller跳转的
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class BasicErrorController extends AbstractErrorController {
	@RequestMapping(produces = {"text/html"})
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        HttpStatus status = this.getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);//6、依靠这个方法去返回一个错误视图界面,如果视图不为空就直接返回,为空就返回默认的
        return modelAndView != null ? modelAndView : new ModelAndView("error", model);
    }
}
protected ModelAndView resolveErrorView(HttpServletRequest request, HttpServletResponse response, HttpStatus status, Map<String, Object> model) {
    Iterator var5 = this.errorViewResolvers.iterator();

    ModelAndView modelAndView;
    do {
        if (!var5.hasNext()) {
            return null;
        }

        ErrorViewResolver resolver = (ErrorViewResolver)var5.next();
        modelAndView = resolver.resolveErrorView(request, status, model);//7、遍历容器中所有的错误视图解析器,如果没有符合条件的就为空
    } while(modelAndView == null);

    return modelAndView;
}
3、DefaultErrorViewResovler
@Configuration
static class DefaultErrorViewResolverConfiguration {
    private final ApplicationContext applicationContext;
    private final ResourceProperties resourceProperties;

    DefaultErrorViewResolverConfiguration(ApplicationContext applicationContext, ResourceProperties resourceProperties) {
        this.applicationContext = applicationContext;
        this.resourceProperties = resourceProperties;
    }

    @Bean
    @ConditionalOnBean({DispatcherServlet.class})
    @ConditionalOnMissingBean
    public DefaultErrorViewResolver conventionErrorViewResolver() {//9、由它来解析得到跳转的路径
        return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties);
    }
}
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
    ModelAndView modelAndView = this.resolve(String.valueOf(status.value()), model);
    if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
        modelAndView = this.resolve((String)SERIES_VIEWS.get(status.series()), model);
    }

    return modelAndView;
}

private ModelAndView resolve(String viewName, Map<String, Object> model) {
    String errorViewName = "error/" + viewName;//8、跳转路径为templates下的error文件夹
    TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName, this.applicationContext);
    return provider != null ? new ModelAndView(errorViewName, model) : this.resolveResource(errorViewName, model);
}

private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
    String[] var3 = this.resourceProperties.getStaticLocations();
    int var4 = var3.length;

    for(int var5 = 0; var5 < var4; ++var5) {
        String location = var3[var5];

        try {
            Resource resource = this.applicationContext.getResource(location);
            resource = resource.createRelative(viewName + ".html");//拼接视图解析器
            if (resource.exists()) {
                return new ModelAndView(new DefaultErrorViewResolver.HtmlResourceView(resource), model);
            }
        } catch (Exception var8) {
        }
    }

    return null;
}
4、DefaultErrorAttributes
@Bean
@ConditionalOnMissingBean(
    value = {ErrorAttributes.class},
    search = SearchStrategy.CURRENT
)
public DefaultErrorAttributes errorAttributes() {
    return new DefaultErrorAttributes(this.serverProperties.getError().isIncludeException());//用来获取错误页面的信息
}
public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver, Ordered {
    private static final String ERROR_ATTRIBUTE = DefaultErrorAttributes.class.getName() + ".ERROR";
     public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
        Map<String, Object> errorAttributes = new LinkedHashMap();
        errorAttributes.put("timestamp", new Date());
        this.addStatus(errorAttributes, webRequest);
        this.addErrorDetails(errorAttributes, webRequest, includeStackTrace);
        this.addPath(errorAttributes, webRequest);
        return errorAttributes;
    }

    private void addStatus(Map<String, Object> errorAttributes, RequestAttributes requestAttributes) {
        Integer status = (Integer)this.getAttribute(requestAttributes, "javax.servlet.error.status_code");
        if (status == null) {
            errorAttributes.put("status", 999);
            errorAttributes.put("error", "None");
        } else {
            errorAttributes.put("status", status);

            try {
                errorAttributes.put("error", HttpStatus.valueOf(status).getReasonPhrase());
            } catch (Exception var5) {
                errorAttributes.put("error", "Http Status " + status);
            }

        }
    }

    private void addErrorDetails(Map<String, Object> errorAttributes, WebRequest webRequest, boolean includeStackTrace) {
        Throwable error = this.getError(webRequest);
        if (error != null) {
            while(true) {
                if (!(error instanceof ServletException) || error.getCause() == null) {
                    if (this.includeException) {
                        errorAttributes.put("exception", error.getClass().getName());
                    }

                    this.addErrorMessage(errorAttributes, error);
                    if (includeStackTrace) {
                        this.addStackTrace(errorAttributes, error);
                    }
                    break;
                }

                error = error.getCause();
            }
        }

        Object message = this.getAttribute(webRequest, "javax.servlet.error.message");
        if ((!StringUtils.isEmpty(message) || errorAttributes.get("message") == null) && !(error instanceof BindingResult)) {
            errorAttributes.put("message", StringUtils.isEmpty(message) ? "No message available" : message);
        }

    }
}

, “javax.servlet.error.message”);
if ((!StringUtils.isEmpty(message) || errorAttributes.get(“message”) == null) && !(error instanceof BindingResult)) {
errorAttributes.put(“message”, StringUtils.isEmpty(message) ? “No message available” : message);
}

}

}


#### 
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你在使用 Thymeleaf 时遇到了页面报错,可以查看控制台输出的错误信息,找到具体的问题所在。常见的错误包括语法错误、模板引用错误、标签使用错误等等。 如果你想利用 Thymeleaf 自定义错误页面,可以按照以下步骤进行: 1. 首先在 `src/main/resources/templates` 目录下创建一个 `error` 目录。在该目录下创建一个名为 `error.html` 的 Thymeleaf 模板文件。 2. 在 `application.properties` 文件配置错误处理的地址: ``` server.error.path=/error ``` 3. 创建一个名为 `ErrorController` 的控制器类,用于处理错误请求: ```java @Controller public class ErrorController implements org.springframework.boot.web.servlet.error.ErrorController { @RequestMapping("/error") public String handleError(HttpServletRequest request, HttpServletResponse response) { // 获取错误状态码 Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); // 根据状态码返回不同的错误页面 if (statusCode == 404) { return "error/404"; } else { return "error/500"; } } @Override public String getErrorPath() { return "/error"; } } ``` 4. 在 `error` 目录下创建 `404.html` 和 `500.html` 两个 Thymeleaf 模板文件,用于显示不同类型的错误页面。 例如,`404.html` 可以这样编写: ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>404 Not Found</title> </head> <body> <h1>404 Not Found</h1> <p>您请求的页面不存在,请检查您输入的地址是否正确。</p> </body> </html> ``` 5. 访问不存在的页面,尝试触发 404 错误,可以看到自定义错误页面。 如果你想测试 500 错误,可以在控制器抛出一个异常,例如: ```java @RequestMapping("/test") public String test() { throw new RuntimeException("测试错误"); } ``` 然后访问 `/test` 地址即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值