统一异常拦截及自定义错误跳转

master
barney 2 years ago
parent a8bb79c3e8
commit 16e0687b4e
  1. 0
      cache/.ehcache-diskstore.lock
  2. BIN
      cache/blog-cache.data
  3. 8
      src/main/java/cc/bnblogs/Exception/CustomException.java
  4. 33
      src/main/java/cc/bnblogs/config/ExceptionConfig.java
  5. 21
      src/main/java/cc/bnblogs/config/WebConfig.java
  6. 57
      src/main/java/cc/bnblogs/controller/IndexController.java
  7. 20
      src/main/java/cc/bnblogs/enums/ErrorCodeEnum.java
  8. 4
      src/main/resources/static/css/error.css
  9. 11
      src/main/resources/templates/fail.html

Binary file not shown.

@ -0,0 +1,8 @@
package cc.bnblogs.Exception;
/**
* @author zfp@bnblogs.cc
* @createTime: 2022/10/23
*/
public class CustomException extends Exception{
}

@ -1,10 +1,16 @@
package cc.bnblogs.config; package cc.bnblogs.config;
import cc.bnblogs.Exception.CustomException;
import cc.bnblogs.common.Result; import cc.bnblogs.common.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/** /**
* @author zfp@bnblogs.cc * @author zfp@bnblogs.cc
@ -14,11 +20,30 @@ import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice @ControllerAdvice
public class ExceptionConfig { public class ExceptionConfig {
@ResponseBody
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public Result<String> defaultException(Exception e) { public void defaultException(Exception e, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
e.printStackTrace();
log.error(e.getMessage(), e);
// 返回的是页面
if (request.getRequestURI().endsWith(".html")) {
request.getRequestDispatcher("/error/500.html").forward(request, response);
} else {
// 返回的是json
response.setCharacterEncoding("utf-8");
response.getWriter().print(new ObjectMapper().writeValueAsString(Result.error()));
}
}
/**
* http状态码虽然是200当业务上有错误(比如访问的文章分类标签不存在时)
* 当业务上存在404时统一转发到/error/404.html
* @param e 自定义错误异常类
* @return 404.html
*/
@ExceptionHandler(CustomException.class)
public String notFoundException(CustomException e) {
e.printStackTrace(); e.printStackTrace();
log.error(e.getMessage(),e); log.error(e.getMessage(),e);
return Result.error(); return "forward:/error/404.html";
} }
} }

@ -1,13 +1,22 @@
package cc.bnblogs.config; package cc.bnblogs.config;
import cc.bnblogs.common.LRUCache; import cc.bnblogs.common.LRUCache;
import cc.bnblogs.common.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
/** /**
@ -41,6 +50,18 @@ public class WebConfig implements WebMvcConfigurer {
// 记住在absolutePath前加一个'/',否则本地图片读取不出来(重要的事情说三遍) // 记住在absolutePath前加一个'/',否则本地图片读取不出来(重要的事情说三遍)
registry.addResourceHandler("/upload/**").addResourceLocations("file://" + '/' + absolutePath); registry.addResourceHandler("/upload/**").addResourceLocations("file://" + '/' + absolutePath);
} }
/**
* 错误页面配置是根据HTTP请求返回的状态码决定的(Http异常)
* Controller层的报错是thymeleaf渲染页面时报错的(业务异常)
* @return 跳转到对应的error页面
*/
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> webServerFactoryCustomizer() {
return factory -> factory.addErrorPages(
new ErrorPage(HttpStatus.NOT_FOUND, "/error/404.html"),
new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500.html"));
}
@Bean @Bean
public LRUCache lruCache() { public LRUCache lruCache() {
return new LRUCache(MAX_LRU_CACHE_SIZE); return new LRUCache(MAX_LRU_CACHE_SIZE);

@ -1,7 +1,9 @@
package cc.bnblogs.controller; package cc.bnblogs.controller;
import cc.bnblogs.Exception.CustomException;
import cc.bnblogs.common.*; import cc.bnblogs.common.*;
import cc.bnblogs.config.WebConfig; import cc.bnblogs.config.WebConfig;
import cc.bnblogs.enums.ErrorCodeEnum;
import cc.bnblogs.enums.ResultEnum; import cc.bnblogs.enums.ResultEnum;
import cc.bnblogs.pojo.Article; import cc.bnblogs.pojo.Article;
import cc.bnblogs.pojo.Category; import cc.bnblogs.pojo.Category;
@ -99,10 +101,13 @@ public class IndexController {
@GetMapping("/tag/{id}.html") @GetMapping("/tag/{id}.html")
public String tagList(@PathVariable Integer id, public String tagList(@PathVariable Integer id,
@RequestParam(required = false,defaultValue = "1") Integer pageNumber, @RequestParam(required = false,defaultValue = "1") Integer pageNumber,
Model model){ Model model) throws CustomException {
Tag tag = tagService.detail(id); Tag tag = tagService.detail(id);
if (Objects.isNull(tag)) {
throw new CustomException();
}
model.addAttribute("tag",tag); model.addAttribute("tag",tag);
// todo id不存在时要特殊处理
ArticleSearch articleSearch = ArticleSearch.indexSearch(pageNumber,5); ArticleSearch articleSearch = ArticleSearch.indexSearch(pageNumber,5);
articleSearch.setTid(id); articleSearch.setTid(id);
PageHelper<Article> articlePage = articleService.search(articleSearch); PageHelper<Article> articlePage = articleService.search(articleSearch);
@ -123,10 +128,12 @@ public class IndexController {
@GetMapping("/category/{id}.html") @GetMapping("/category/{id}.html")
public String categoryList(@PathVariable Integer id, public String categoryList(@PathVariable Integer id,
@RequestParam(required = false,defaultValue = "1") Integer pageNumber, @RequestParam(required = false,defaultValue = "1") Integer pageNumber,
Model model){ Model model) throws CustomException {
Category category = categoryService.detail(id); Category category = categoryService.detail(id);
if (Objects.isNull(category)) {
throw new CustomException();
}
model.addAttribute("category",category); model.addAttribute("category",category);
// todo 分类不存在时要特殊处理
ArticleSearch articleSearch = ArticleSearch.indexSearch(pageNumber,5); ArticleSearch articleSearch = ArticleSearch.indexSearch(pageNumber,5);
articleSearch.setCid(id); articleSearch.setCid(id);
PageHelper<Article> articlePage = articleService.search(articleSearch); PageHelper<Article> articlePage = articleService.search(articleSearch);
@ -178,22 +185,54 @@ public class IndexController {
return "tags"; return "tags";
} }
@GetMapping("/error") /**
public String error() { * 404错误请求
return "error"; * @param model MVC model
* @return 错误页
*/
@GetMapping("/error/404.html")
public String error404(Model model) {
model.addAttribute("error", ErrorCodeEnum.ERROR_404);
return "fail";
}
/**
* 500错误请求
* @param model MVC model
* @return 错误页
*/
@GetMapping("/error/500.html")
public String error500(Model model) {
model.addAttribute("error", ErrorCodeEnum.ERROR_500);
return "fail";
} }
/**
* 文章详情页
* @param id 文章id
* @param model MVC model
* @param request HttpServletRequest请求
* @param response HttpServletResponse响应
* @return
*/
@GetMapping("/{id}.html") @GetMapping("/{id}.html")
public String detail(@PathVariable Integer id, Model model, public String detail(@PathVariable Integer id, Model model,
HttpServletRequest request, HttpServletResponse response) { HttpServletRequest request, HttpServletResponse response)
throws CustomException {
Article article = articleService.detail(id); Article article = articleService.detail(id);
// 文章不存在
if (Objects.isNull(article)) {
throw new CustomException();
}
// 如果cookie不存在 // 如果cookie不存在
if (Objects.isNull(CookieUtil.getCookie(request,Article.VIEW_PREFIX + id))) { if (Objects.isNull(CookieUtil.getCookie(request,Article.VIEW_PREFIX + id))) {
// 更新文章浏览量 // 更新文章浏览量
articleService.viewArticle(id); articleService.viewArticle(id);
CookieUtil.setCookie(response,Article.VIEW_PREFIX + id,"true"); CookieUtil.setCookie(response,Article.VIEW_PREFIX + id,"true");
} }
// todo 文章内容不存在时应该抛出异常
model.addAttribute("article",article); model.addAttribute("article",article);
PageHelper<Comment> commentPage = commentService.show(id,1); PageHelper<Comment> commentPage = commentService.show(id,1);
// 返回第一页评论 // 返回第一页评论

@ -0,0 +1,20 @@
package cc.bnblogs.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author zfp@bnblogs.cc
* @createTime: 2022/10/22
*/
@Getter
@AllArgsConstructor
public enum ErrorCodeEnum {
// HTTP请求的状态码和返回信息
ERROR_404(404,"对不起,你请求的页面暂时未找到.<br>它或许已经被迁移至其它页面啦."),
ERROR_500(500,"您好,服务器暂时出发问题,请稍候访问.<br>或您也可以尝试联系站长."),;
private final Integer code;
private final String msg;
}

@ -247,7 +247,9 @@ sup {
display: block; display: block;
top: 3rem; top: 3rem;
left: 3rem; left: 3rem;
width: 5rem; width: 20rem;
font-weight: 500;
font-size: larger;
} }
.logo-link .logo { .logo-link .logo {
width: 100%; width: 100%;

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html" lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Title</title> <title>Title</title>
@ -13,7 +13,7 @@
<body class="flat"> <body class="flat">
<div id="particles-js"></div> <div id="particles-js"></div>
<a href="/" class="logo-link" title="返回首页" >冷文学习者</a> <a th:href="@{/}" class="logo-link" title="返回首页" ><th:block th:text="${@webSite.title}"></th:block></a>
<div class="content"> <div class="content">
@ -47,10 +47,9 @@
</div> </div>
<!-- Your text --> <!-- Your text -->
<h1>错误码:404</h1> <h1>错误码:<th:block th:text="${error.getCode()}"></th:block> </h1>
<p>对不起,你请求的页面暂时未找到.<br> <p th:utext="${error.getMsg()}"></p>
它或许已经被迁移至其它页面啦.</p>
</div> </div>
@ -59,7 +58,7 @@
<footer> <footer>
<ul> <ul>
<li><a href="/">首页</a></li> <li><a th:href="@{/}">首页</a></li>
<li><a href="javascript:window.history.back()">返回上一级</a></li> <li><a href="javascript:window.history.back()">返回上一级</a></li>
</ul> </ul>
Loading…
Cancel
Save