【问题标题】:Spring - addResourceHandlers not resolving the static resources with Rest ControllerSpring - addResourceHandlers 不使用 Rest Controller 解析静态资源
【发布时间】:2019-09-06 09:32:23
【问题描述】:

我有以下问题。当使用 ResourceHandlers 配置我的 Spring WebMVC 应用程序并拥有一个带有特殊 @RequestMapping 的 RestController 类时,将不会提供静态资源,而是调用 RestController。

代码如下:

@Configuration
@ServletComponentScan
@EnableWebMvc
public class Main extends SpringBootServletInitializer implements ServletContextAware, WebMvcConfigurer {

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(new Class[]{Main.class, Initializer.class, ContainerInitializer.class});
    }

    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new FacesServlet(), "*.jsf");
        servletRegistrationBean.setName("JSF Faces Servlet");
        servletRegistrationBean.setLoadOnStartup(1);
        return servletRegistrationBean;
    }

    @Bean
    public ServletRegistrationBean facesServletRegistratiton() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new FacesServlet(), new String[]{"*.xhtml"});
        servletRegistrationBean.setName("XHTML Faces Servlet");
        servletRegistrationBean.setLoadOnStartup(1);
        return servletRegistrationBean;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

       // Register resource handler for CSS and JS
       registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/")
            .setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic())
            .resourceChain(true)
            .addResolver(new PathResourceResolver());

       // Register resource handler for images
       registry.addResourceHandler("/images/**").addResourceLocations("/WEB-INF/images/")
            .setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic())
            .resourceChain(true)
            .addResolver(new PathResourceResolver());
    }
}

所以我有两个资源处理程序用于在资源文件夹中提供静态资源(如 css、js 文件)和用于我的静态图像的图像文件夹。

我的 RestController 类的代码如下所示:

@RestController
@Component
public class Clownfish {
   @GetMapping(path = "/{name}/**")
   public void universalGet(@PathVariable("name") String name, @Context HttpServletRequest request, @Context HttpServletResponse response) {
         String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
         if (name.compareToIgnoreCase(path) != 0) {
             name = path.substring(1);
         }
    }
}

当使用 http://localhost:8080/images/foo.png 调用我的资源时,正在调用 RestController。 如果我将 @GetMapping(path = "/{name}/**") 更改为 @GetMapping(path = "/{name}") 它可以正常工作。但我需要通配符来处理特殊调用。

我在配置中做错了什么? TIA

【问题讨论】:

  • 阅读文档并不能解决我的问题。正如我所写,我需要通配符。 name 是在我的 CMS 中获取站点的通用部分,并且还需要通配符来为该站点提供别名。我认为可能有一些东西使 ResourceHandler 比 REST Controller 具有更高的优先级。如果没有任何帮助,我还需要直接在我的 REST 控制器中处理我的静态内容。
  • 好的。我解决了。将 ResourceHandler 优先级设置为 -1 即可完成这项工作。 registry.setOrder(-1);

标签: java spring spring-mvc


【解决方案1】:

我找到了一种设置 ResourceHandler 优先级的方法。

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

       // Register resource handler for CSS and JS
       registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/")
            .setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic())
            .resourceChain(true)
            .addResolver(new PathResourceResolver());

       // Register resource handler for images
       registry.addResourceHandler("/images/**").addResourceLocations("/WEB-INF/images/")
            .setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic())
            .resourceChain(true)
            .addResolver(new PathResourceResolver());
       registry.setOrder(-1);  // This will set the priority lower to the default handler (that is by default 0)
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 2012-11-30
    • 2017-12-05
    • 2016-10-01
    相关资源
    最近更新 更多