【问题标题】:Excluding certain paths in a request mapping for a Spring MVC controller在 Spring MVC 控制器的请求映射中排除某些路径
【发布时间】:2017-03-21 19:39:44
【问题描述】:

我目前正在尝试创建一个控制器来全局处理所有未知 URL。所以我所做的是创建一个类似于下面的控制器

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/**")
public class UnknownUrlController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String getError404() {
        return "/error404";
    }
}

我的意图是确保不调用仅向浏览器返回字符串“未找到”的默认 servlet。此策略有效,因为所有未知 URL 均由该控制器处理。

但问题是控制器也被我在 WebMvcConfigurerAdapter 中配置的所有静态资源(图像、js 和 css 文件)调用,如下所示

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/css/**").addResourceLocations("/css/");
    registry.addResourceHandler("/js/**").addResourceLocations("/js/");
    registry.addResourceHandler("/img/**").addResourceLocations("/img/");
}

因此,我没有将静态文件提供给浏览器,而是将我的错误页面提供给它的位置。虽然我后来了解到控制器映射优先于来自 answer 的静态资源。这就是我想知道如何排除我的资源 url 映射不被这个控制器处理的原因,所以它只关心捕获未知的 URL。

在继续这个策略之前,我尝试了一些我无法开始工作的其他事情(我可能遗漏了一些东西)

  1. 将我的 DispatcherServletthrowExceptionIfNoHandlerFound 字段设置为 true,以便在找不到 URL 映射的处理程序时应抛出的异常,然后将其全局处理为描述here。但是,似乎总是为未知路径(/**)分配默认处理程序,因此不会引发异常。
  2. 创建了一个 application.properties 文件并设置 spring.mvc.throw-exception-if-no-handler-found=true。

我所有的配置都是基于 Java 的,没有任何 xml 文件,并且希望保持这种方式。

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    有一种更好的方法可以在 Spring 中编写自定义错误处理程序。见下文:

    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleResourceNotFoundException() {
        return "notfound";
    }
    

    It as a nice blog entry about exception handlers in Spring MVC.

    如果dispatcherServlet在404的情况下没有抛出异常,那么你应该使用DispatcherServlet的setThrowExceptionIfNoHandlerFound()方法开启它。

    Here you can find more information about, how to turn it on

    【讨论】:

    • 嗨,Sawo。我也通读了那个链接。如果你看看我说的我尝试过的第一件事,这里的链接实际上链接到同一篇文章。我实现该技术的问题是,当 URL 未映射到任何控制器时,Dispatcher Servlet 不会引发任何异常。所以不会抛出可以处理的异常。
    • 在dispatcherServlet中可以设置在404的情况下抛出异常。下面是控制它的方法:docs.spring.io/spring-framework/docs/current/javadoc-api/org/…
    • 嗨,Sawo。我也尝试过,但它并没有抛出异常,而是一直分配给默认的 Servlet,该 Servlet 只是将“未找到”返回给浏览器
    • Spring Boot 1.4+ 支持基于 HTTP 状态码的自定义错误页面,声明式:docs.spring.io/spring-boot/docs/current/reference/htmlsingle/…
    【解决方案2】:

    【讨论】:

    • 我试着像我在问题中所说的那样打开它。这是我尝试过的两件事中写的第一件事。那没起效。仍然从未抛出异常
    【解决方案3】:

    终于找到解决问题的方法了。解决方案是删除我的 Java 配置中的默认 servlet 处理程序。在我的 Java 配置类(扩展 WebMvcConfigurerAdapter)中,我之前启用了默认 Servlet,如下所示

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
    

    这会使用 /** 的 URL 映射配置 DefaultServletHttpRequestHandler,如 Spring mvc 文档的 section 中所述。这就是为什么即使我已将DispatcherServletthrowExceptionIfNoHandlerFoundthrowExceptionIfNoHandlerFound 设置为true,如我在问题中所述,当没有找到URL 处理程序时也没有抛出异常的原因。

    从我的班级中删除配置后。我创建了一个全局异常处理程序类并为NoHandlerFoundException 案例添加了一个方法。这是当没有为 URL 映射找到控制器处理程序时引发的异常。示例代码如下所示。这在 spring mvc 文档的 section 中也得到了很好的解释。

    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        @ExceptionHandler(NoHandlerFoundException.class)
        @ResponseStatus(HttpStatus.NOT_FOUND)
        @RequestMapping( value = {"/*","/**"},method = RequestMethod.GET)
        public String handle(HttpServletRequest request, NoHandlerFoundException ex) {
            return "error-404";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-30
      • 1970-01-01
      • 2014-03-13
      • 1970-01-01
      • 2015-06-21
      • 2020-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多