【问题标题】:Spring controller exception handling for 404 statuses and url pattern404 状态和 url 模式的 Spring 控制器异常处理
【发布时间】: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>

【问题讨论】:

标签: java spring spring-boot spring-mvc model-view-controller


【解决方案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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-11
      • 1970-01-01
      • 2020-01-18
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多