调用接口:http://localhost:8080/user/delete?userId=2
由于小B的账号只有查询权限,没有删除权限,所以返回403错误页
2. 自定义Filter中异常的处理注意:在调试之前需要在application.yml或application.properties配置文件中增加一个配置:server.error.whitelabel.enabled=false
这个配置的意思是是否启用默认的错误页面,这里我们自己写了一套错误页,所以不需要框架自带的配置了。
由于@ControllerAdvice注解无法捕获自定义Filter中抛出的异常,这里我们就需要使用另外一种方法进行处理:ErrorController接口。
(1) 原理解释Spring Boot的ErrorController是一个接口,用于定义处理应用程序中发生的错误的自定义逻辑。它允许开发人员以更灵活的方式处理和响应异常,而不是依赖于默认的错误处理机制。:
- 定制错误页面:通过实现ErrorController接口,可以自定义应用程序的错误页面,以提供更好的用户体验。可以根据不同的异常类型和HTTP状态码提供不同的错误页面或错误信息。
- 记录错误日志:ErrorController可以用于捕获和记录应用程序中的异常,并将其记录到日志中。这对于问题追踪和排查非常有帮助,可以了解应用程序中发生的错误和异常的详细信息。
- 重定向或转发请求:通过ErrorController,可以根据错误的类型或其他条件,将请求重定向到不同的URL或转发到其他控制器方法。这对于根据错误情况做出不同的处理非常有用,例如重定向到自定义的错误页面或执行特定的错误处理逻辑。
使用方法直接看看我的代码就知道了。
CustomErrorController.java
package com.summo.demo.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class CustomErrorController implements ErrorController {
@RequestMapping("/error")
public ModelAndView handleError(HttpServletRequest request, HttpServletResponse response) {
//获取当前响应返回的状态码
int statusCode = response.getStatus();
//如果响应头中存在statusCode,则默认使用这个statusCode
if (StringUtils.isNotBlank(response.getHeader("statusCode"))) {
statusCode = Integer.valueOf(response.getHeader("statusCode"));
}
if (statusCode == HttpServletResponse.SC_FOUND) {
// 获取Location响应头的值,进行重定向
String redirectLocation = response.getHeader("Location");
return new ModelAndView("redirect:" redirectLocation);
} else if (statusCode == HttpServletResponse.SC_UNAUTHORIZED) {
// 重定向到登录页
return new ModelAndView("redirect:/login");
} else if (statusCode == HttpServletResponse.SC_FORBIDDEN) {
// 返回403页面
return new ModelAndView("403");
} else if (statusCode == HttpServletResponse.SC_NOT_FOUND) {
// 返回404页面
return new ModelAndView("404");
} else if (statusCode == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
// 返回500页面,并传递errorMsg和errorCode到模板
ModelAndView modelAndView = new ModelAndView("500");
modelAndView.addObject("errorMsg", response.getHeader("errorMsg"));
modelAndView.addObject("errorCode", response.getHeader("errorCode"));
return modelAndView;
} else {
// 返回其他错误页面
return new ModelAndView("error");
}
}
}
(3) 测试效果a、404错误页,接口找不到第一步、打开登录页细心的读者可能会看到,statusCode来自于两个地方,第一个是response.getStatus();第二个是response.getHeader("statusCode")。这两者的区别是第一个是框架自动设置的,第二个则是我根据业务逻辑设置的。
原因是在WebFilter中一旦抛出了异常,response.getStatus()一定会是500,即使这个异常是因为用户身份失效导致的。但异常又不得不抛出,所以我通过自定义response的header的方式设置了错误码,传递到/error接口。
访问链接:http://localhost:8080/login
输入账号、密码,点击登录进入首页