简体   繁体   English

Spring controller 404 状态和 url 模式的异常处理

[英]Spring controller exception handling for 404 statuses and url pattern

Is it possible to handle 404 status for particular url pattern?是否可以处理特定 url 模式的 404 状态? I would like display login page if someone go to 'localhost:8080/login/other' but there is no request mapping for 'login/other'.如果有人 go 到 'localhost:8080/login/other' 但没有针对 'login/other' 的请求映射,我想显示登录页面。 Controller class is as follow: Controller class如下:

@RequestMapping("/login")
@Controller
public class UserManagerController {

    @RequestMapping({"/", ""})
    public String getLoginPage() {
        return "login.html";
    }

}

I cannot add '/login/**' because this match my static content and any request for js or css match that endpoint.我无法添加“/login/**”,因为这与我的 static 内容匹配,并且对 js 或 css 的任何请求都与该端点匹配。 Example html:示例 html:

<!DOCTYPE html>
<html lang="en">
  <head>
    ...
</head>
    ...
  <script src="/login/some.js"</script>
</html>

You can use something like this:你可以使用这样的东西:

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";
  }
}

That code opens the 'resource-not-found' page in case that user will open an invalid url, for instance localhost:8080/invalid-page该代码会打开“未找到资源”页面,以防用户打开无效的 url,例如 localhost:8080/invalid-page

For your case you could use the method 'handleError()' to return "redirect:/login";对于您的情况,您可以使用方法 'handleError()' 返回 "redirect:/login"; if statusCode is 404如果状态码是 404

In my project I thought that it will be more logical to open a 'resource-not-found' page and a button that will redirect the user to home page, you can look how it works here: https://macari-home-finance.herokuapp.com/login/invalid-url and here is my project https://github.com/ruslanMacari/HomeFinance在我的项目中,我认为打开“未找到资源”页面和将用户重定向到主页的按钮会更合乎逻辑,您可以在这里查看它的工作原理: https://macari-home- Finance.herokuapp.com/login/invalid-url这是我的项目https://github.com/ruslanMacari/HomeFinance

hope it will help you希望对你有帮助

I found solutions to redirect http 404 responses for defined url pattern using Filters and HttpServletResponseWrapper.我找到了使用过滤器和 HttpServletResponseWrapper 为定义的 url 模式重定向 http 404 响应的解决方案。

In spring boot define filter for pattern.在 spring 引导中为模式定义过滤器。

@Bean
    public FilterRegistrationBean<LoginFilter> loginFilter(){
        FilterRegistrationBean<LoginFilter> registrationBean = new FilterRegistrationBean<>();

        registrationBean.setFilter(new LoginFilter());
        registrationBean.addUrlPatterns("/login/*");

        return registrationBean;
    }

In filter instance create HttpServletResponseWrapper and override sendError's methods to redirect all 404 responses.在过滤器实例中创建 HttpServletResponseWrapper 并覆盖 sendError 的方法以重定向所有 404 响应。 Filters look as follow:过滤器如下所示:

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM