404 状态和 url 模式的 Spring 控制器异常处理
Posted
技术标签:
【中文标题】404 状态和 url 模式的 Spring 控制器异常处理【英文标题】:Spring controller exception handling for 404 statuses and url pattern 【发布时间】:2020-09-22 03:14:44 【问题描述】:是否可以处理特定 url 模式的 404 状态? 如果有人访问“localhost:8080/login/other”,但没有“login/other”的请求映射,我想显示登录页面。控制器类如下:
@RequestMapping("/login")
@Controller
public class UserManagerController
@RequestMapping("/", "")
public String getLoginPage()
return "login.html";
我无法添加“/login/**”,因为这与我的静态内容匹配,并且对 js 或 css 的任何请求都与该端点匹配。示例html:
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
...
<script src="/login/some.js"</script>
</html>
【问题讨论】:
你可以做 URL 重定向。看一下这个。 ***.com/a/43954350/13528037 【参考方案1】:你可以这样使用:
import java.util.Objects;
import javax.servlet.http.HttpServletRequest;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class GlobalErrorController implements ErrorController
@RequestMapping("/error")
public String handleError(HttpServletRequest request, Model model)
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
model.addAttribute("errorMessage", exception);
model.addAttribute("statusCode", statusCode);
if (Objects.nonNull(statusCode)
&& HttpStatus.NOT_FOUND.value() == statusCode)
return "resource-not-found";// in your case you should use: return "redirect:/login";
return "exception";
@Override
public String getErrorPath()
return "/error";
该代码会打开“未找到资源”页面,以防用户打开无效的 url,例如 localhost:8080/invalid-page
对于您的情况,您可以使用方法“handleError()”返回“redirect:/login”;如果 statusCode 是 404
在我的项目中,我认为打开“未找到资源”页面和将用户重定向到主页的按钮会更合乎逻辑,您可以在此处查看它的工作原理: https://macari-home-finance.herokuapp.com/login/invalid-url 这是我的项目https://github.com/ruslanMacari/HomeFinance
希望对你有帮助
【讨论】:
【参考方案2】:我找到了使用过滤器和 HttpServletResponseWrapper 为定义的 url 模式重定向 http 404 响应的解决方案。
在 Spring Boot 中为模式定义过滤器。
@Bean
public FilterRegistrationBean<LoginFilter> loginFilter()
FilterRegistrationBean<LoginFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new LoginFilter());
registrationBean.addUrlPatterns("/login/*");
return registrationBean;
在过滤器实例中创建 HttpServletResponseWrapper 并覆盖 sendError 的方法来重定向所有 404 响应。过滤器如下所示:
public class LoginFilter implements Filter
@Override
public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException
HttpServletResponseWrapper servletResponseWrapper = new HttpServletResponseWrapper((HttpServletResponse) servletResponse)
@Override
public void sendError(int sc, String msg) throws IOException
if (sc == 404)
sendRedirect();
else
super.sendError(sc, msg);
@Override
public void sendError(int sc) throws IOException
if (sc == 404)
sendRedirect();
else
super.sendError(sc);
private void sendRedirect() throws IOException
((HttpServletResponse)getResponse()).sendRedirect("/login");
;
chain.doFilter(servletRequest, servletResponseWrapper);
【讨论】:
以上是关于404 状态和 url 模式的 Spring 控制器异常处理的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Spring Boot 中的 REST 控制器返回 HTTP 状态 404 – 未找到
spring 控制器返回 404 并带有 post 和 file 以生成响应实体
Spring 问题:出现意外错误(类型=未找到,状态=404)