如何更改自动添加的 spring mvc 处理程序的默认处理程序顺序

发布于 2024-12-15 07:18:38 字数 7162 浏览 2 评论 0原文

在实现我的项目时,我发现使用 @RequestMapping(value = "/**") 设置控制器后 无法工作> 和@RequestMapping(method=RequestMethod.GET)

看来带注释的控制器比 SimpleURLHandler 具有更高的优先级。

有没有人可以解决这个问题?我需要那个控制器,但无法删除它。

提前致谢!

以下是我如何设置项目以及有关问题的详细信息:

Web.xml

<servlet>
  <servlet-name>Test</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/webmvc-config.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>Test</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

webmvc-config.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <!-- The controllers are autodetected POJOs labeled with the @Controller annotation. -->
    <context:component-scan base-package="com.web.test" use-default-filters="false">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>

    <!-- Turns on support for mapping requests to Spring MVC @Controller methods
         Also registers default Formatters and Validators for use across all @Controllers -->
    <mvc:annotation-driven conversion-service="applicationConversionService"/>
    <bean class="com.web.test.web.ApplicationConversionServiceFactoryBean" id="applicationConversionService"/>

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources -->
    <mvc:resources location="classpath:/META-INF/web-resources/, /WEB-INF/views/" mapping="/resources/**" cache-period="0" order="0"/>

    <!-- Allows for mapping the DispatcherServlet to "/" by forwarding static resource requests to the container's default Servlet -->
    <mvc:default-servlet-handler/>

            <!-- selects a static view for rendering without the need for an explicit controller -->
            <mvc:view-controller path="/" view-name="index"/>

            <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" id="resourceBundleViewResolver" p:basename="META-INF/view/wicket-views" p:order="1"/>

    <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
        <property name="order" value="2"/>
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
    </bean>
    <bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/views/layouts/layouts.xml</value>
                <value>classpath:/META-INF/view/tiles-views.xml</value>
            </list>
        </property>
    </bean>
... ...
</beans>

ApplicationController.java

@Controller
@RequestMapping(method=RequestMethod.GET)
public class ApplicationController {

    @RequestMapping(value = "/**")
    public ModelAndView handleRequest(HttpServletRequest request){


        ModelAndView mav = new ModelAndView("index");   

        return mav;
    }
}

运行日志。 (正如你在这里看到的,资源请求是由带注释的控制器处理的,而不是ResourceHttpRequestHandler)。

2011-11-15 17:21:09,821 [http-8080-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.tiles2.TilesView: name 'index'; URL [index]] in DispatcherServlet with name 'Test'
2011-11-15 17:21:09,821 [http-8080-2] DEBUG org.apache.tiles.impl.BasicTilesContainer - Render request recieved for definition 'index'
2011-11-15 17:21:09,821 [http-8080-4] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'Test' processing GET request for [/Test/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js]
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Matching patterns for request [/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js] are [/**/, /**]
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - URI Template variables for request [/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js] are {}
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapping [/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js] to HandlerExecutionChain with handler [com.web.Test.web.ApplicationController@1a57c9e4] and 4 interceptors
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/Test/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js] is: -1
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.bind.annotation.support.HandlerMethodInvoker - Invoking request handler method: public org.springframework.web.servlet.ModelAndView com.web.Test.web.ApplicationController.handleRequest(javax.servlet.http.HttpServletRequest)

如果我删除 ApplicationController,则可以访问静态资源。

2011-11-15 17:48:16,784 [http-8080-2] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'Test' processing GET request for [/Test/resources/styles/application-common.css]
2011-11-15 17:48:16,784 [http-8080-2] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Matching patterns for request [/resources/styles/application-common.css] are [/resources/**]
2011-11-15 17:48:16,785 [http-8080-2] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - URI Template variables for request [/resources/styles/application-common.css] are {}
2011-11-15 17:48:16,785 [http-8080-2] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapping [/resources/styles/application-common.css] to HandlerExecutionChain with handler [org.springframework.web.servlet.resource.ResourceHttpRequestHandler@6cc5cbab] and 4 interceptors

While implementing my project, I found that <mvc:resources/> was not working after I set up the controller using @RequestMapping(value = "/**") and @RequestMapping(method=RequestMethod.GET).

It seems that the annotated controller get a higher priority than the SimpleURLHandler.

Is there anybody who can solve this problem? I need that controller and cannot remove it.

Thanks in advance!

Here is how I set up the project and the details about the problem:

Web.xml

<servlet>
  <servlet-name>Test</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/webmvc-config.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>Test</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

webmvc-config.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <!-- The controllers are autodetected POJOs labeled with the @Controller annotation. -->
    <context:component-scan base-package="com.web.test" use-default-filters="false">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>

    <!-- Turns on support for mapping requests to Spring MVC @Controller methods
         Also registers default Formatters and Validators for use across all @Controllers -->
    <mvc:annotation-driven conversion-service="applicationConversionService"/>
    <bean class="com.web.test.web.ApplicationConversionServiceFactoryBean" id="applicationConversionService"/>

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources -->
    <mvc:resources location="classpath:/META-INF/web-resources/, /WEB-INF/views/" mapping="/resources/**" cache-period="0" order="0"/>

    <!-- Allows for mapping the DispatcherServlet to "/" by forwarding static resource requests to the container's default Servlet -->
    <mvc:default-servlet-handler/>

            <!-- selects a static view for rendering without the need for an explicit controller -->
            <mvc:view-controller path="/" view-name="index"/>

            <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" id="resourceBundleViewResolver" p:basename="META-INF/view/wicket-views" p:order="1"/>

    <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" id="tilesViewResolver">
        <property name="order" value="2"/>
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
    </bean>
    <bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" id="tilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/views/layouts/layouts.xml</value>
                <value>classpath:/META-INF/view/tiles-views.xml</value>
            </list>
        </property>
    </bean>
... ...
</beans>

ApplicationController.java

@Controller
@RequestMapping(method=RequestMethod.GET)
public class ApplicationController {

    @RequestMapping(value = "/**")
    public ModelAndView handleRequest(HttpServletRequest request){


        ModelAndView mav = new ModelAndView("index");   

        return mav;
    }
}

Running log. (As you can see here, the resource request is processed by annotated controller, not the ResourceHttpRequestHandler).

2011-11-15 17:21:09,821 [http-8080-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Rendering view [org.springframework.web.servlet.view.tiles2.TilesView: name 'index'; URL [index]] in DispatcherServlet with name 'Test'
2011-11-15 17:21:09,821 [http-8080-2] DEBUG org.apache.tiles.impl.BasicTilesContainer - Render request recieved for definition 'index'
2011-11-15 17:21:09,821 [http-8080-4] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'Test' processing GET request for [/Test/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js]
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Matching patterns for request [/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js] are [/**/, /**]
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - URI Template variables for request [/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js] are {}
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping - Mapping [/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js] to HandlerExecutionChain with handler [com.web.Test.web.ApplicationController@1a57c9e4] and 4 interceptors
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.servlet.DispatcherServlet - Last-Modified value for [/Test/resources/javascripts/jQuery/jquery-ui-1.8.16.custom.min.js] is: -1
2011-11-15 17:21:09,823 [http-8080-4] DEBUG org.springframework.web.bind.annotation.support.HandlerMethodInvoker - Invoking request handler method: public org.springframework.web.servlet.ModelAndView com.web.Test.web.ApplicationController.handleRequest(javax.servlet.http.HttpServletRequest)

And if I remove the ApplicationController, the static resources can be reached.

2011-11-15 17:48:16,784 [http-8080-2] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'Test' processing GET request for [/Test/resources/styles/application-common.css]
2011-11-15 17:48:16,784 [http-8080-2] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Matching patterns for request [/resources/styles/application-common.css] are [/resources/**]
2011-11-15 17:48:16,785 [http-8080-2] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - URI Template variables for request [/resources/styles/application-common.css] are {}
2011-11-15 17:48:16,785 [http-8080-2] DEBUG org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapping [/resources/styles/application-common.css] to HandlerExecutionChain with handler [org.springframework.web.servlet.resource.ResourceHttpRequestHandler@6cc5cbab] and 4 interceptors

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绝情姑娘 2024-12-22 07:18:38

通过使用 value = "/**",您的 ApplicationController 将处理绝对所有请求的 URL。

只需指定一个更严格的模式,您的静态内容将不匹配,它就会像您希望的那样工作;示例:

  • value = "/dynamic/**"
  • value = "/**/*.html"
  • value = "/pages/**" code>

选择取决于你,但“RESTful”风格现在非常流行,所以我会遵循 风格指南

By using value = "/**" you're saying your ApplicationController will handle absolutely all requested URLs.

Just specify a more restrictive pattern that your static content won't match and it'll work like you want it to; examples:

  • value = "/dynamic/**"
  • value = "/**/*.html"
  • value = "/pages/**"

The choice is up to you but the "RESTful" style is very hot these days, so I'd follow that style guide.

你的笑 2024-12-22 07:18:38

我也有同样的要求。
我在 Spring Boot 应用程序中捆绑了一个 React 应用程序,但我希望所有静态资源请求都具有最高优先级,然后回退到带注释的控制器。

这样,所有实际上不是静态文件的 URL 都将解析为我的 React 应用程序的索引/根页面。

例如-
/admin/css/style.css 应解析为静态文件。
但是 React 路由应该解析根索引页面/视图。
/admin/sub/path 应解析为视图。

这是通过映射带注释的控制器中的所有路径来实现的 -

@Controller
public class DefaultMvcController {

    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

    @GetMapping({ "", "/"})
    public String index() throws IOException {
        return "index";
    }

    @RequestMapping(path = {"/admin", "/admin/**"}, method = RequestMethod.GET)
    public String admin() throws IOException {

        return "admin/index";
    }

}

并将静态文件处理程序映射的顺序更改为 1 小于带注释的控制器映射的优先级

@Configuration
@ComponentScan(basePackages = "net.savantly.sprout.controllers")
@RequiredArgsConstructor
public class SproutWebMvcConfigurer extends  WebMvcConfigurationSupport {

    @Bean
    @Override
    public HandlerMapping resourceHandlerMapping(UrlPathHelper urlPathHelper, PathMatcher pathMatcher,
            ContentNegotiationManager contentNegotiationManager, FormattingConversionService conversionService,
            ResourceUrlProvider resourceUrlProvider) {
        HandlerMapping mapping = super.resourceHandlerMapping(urlPathHelper, pathMatcher, contentNegotiationManager, conversionService,
                resourceUrlProvider);
        ((AbstractHandlerMapping)mapping).setOrder(-1);
        return mapping;
    }

}

此处完整源代码 - https://github.com/savantly-net/sprout-platform/tree/development/spring/sprout-spring-boot-starter

I had the same requirement.
I'm bundling a React app inside my Spring Boot app, but I want all the static resource requests to take highest priority, then fall-back to annotated controllers.

This way all urls that aren't actually static files will resolve to the index/root page of my React app.

For example -
/admin/css/style.css should resolve to a static file.
But a React route should resolve the root index page/view.
/admin/sub/path should resolve to a view.

This works by mapping all the paths in my annotated controller -

@Controller
public class DefaultMvcController {

    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

    @GetMapping({ "", "/"})
    public String index() throws IOException {
        return "index";
    }

    @RequestMapping(path = {"/admin", "/admin/**"}, method = RequestMethod.GET)
    public String admin() throws IOException {

        return "admin/index";
    }

}

And changing the order of the static file handler mapping to 1 less than the priority of the annotated controller mapping

@Configuration
@ComponentScan(basePackages = "net.savantly.sprout.controllers")
@RequiredArgsConstructor
public class SproutWebMvcConfigurer extends  WebMvcConfigurationSupport {

    @Bean
    @Override
    public HandlerMapping resourceHandlerMapping(UrlPathHelper urlPathHelper, PathMatcher pathMatcher,
            ContentNegotiationManager contentNegotiationManager, FormattingConversionService conversionService,
            ResourceUrlProvider resourceUrlProvider) {
        HandlerMapping mapping = super.resourceHandlerMapping(urlPathHelper, pathMatcher, contentNegotiationManager, conversionService,
                resourceUrlProvider);
        ((AbstractHandlerMapping)mapping).setOrder(-1);
        return mapping;
    }

}

Full source code here - https://github.com/savantly-net/sprout-platform/tree/development/spring/sprout-spring-boot-starter

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文