Spring 4 - addResourceHandlers not resolving the static resources

前端 未结 5 1661
孤独总比滥情好
孤独总比滥情好 2020-11-27 04:44

My maven spring project directory structure is shown below. I am using Spring-4 annotation based configuration. I configure the resources like below. I tried many ways that

相关标签:
5条回答
  • 2020-11-27 05:08

    this worked,

       registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    

    and in the jsp files I referred to the static resources like

    <link href="resources/css/bootstrap.css" rel="stylesheet" media="screen">
    
    0 讨论(0)
  • 2020-11-27 05:14

    I guess it's a bit late, however I was facing with a similar problem just recently. After several days of wrestling, finally it turned out that my DispatcherServlet was not configured to handle the request, therefore the resources were never looked up. So I hope others will find this answer useful.

    If the dispatcher servlet to that you give your config class above is mapped not to the root ("/") but to a top word (e.g. "/data/"), then you might face with the same problem.

    Suppose I have a mapping as "/data/*" for my dispatcher servlet. So my calls look like

    http://localhost:8080/myWebAppContext/data/command
    

    and I thought that if I have a resource mapping e.g. "/content/**/*", then I have access to it as

    http://localhost:8080/myWebAppContent/content/resourcePath
    

    but it's not true, I should use

    http://localhost:8080/myWebAppContent/data/content/resourcePath
    

    instead. This was not clear for me, and since most of the samples use the root "/" for the dispatcher servlet's mapping, therefore it was not an issue there. Upon considering later I should have known it earlier - /data/ tells that the DispatcherServlet should evaluate the call, and the content/ tells to the servlet that a resource handler is the "controller".

    But I want to make it very clear in my frontend (angularJs) whether I look for data (via the REST services) or a content (returning plain texts). The data comes from a database, but the content comes from files (e.g. pdf docs). Therefore, I decided to add two mappings to the dispatcher servlet:

    public class MidtierWebConfig implements WebApplicationInitializer {
    
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
    
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(MidtierAppConfig.class);
    
        servletContext.addListener(new ContextLoaderListener(rootContext));
    
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(MidtierDispatcherConfig.class);
    
        Dynamic netskolaDispatcher = servletContext.addServlet(
            "dispatcher",
            new DispatcherServlet(dispatcherContext)
        );
        netskolaDispatcher.setLoadOnStartup(1);
        netskolaDispatcher.addMapping("/data/*");
        netskolaDispatcher.addMapping("/content/*");
    }
    
    }
    

    The MidtierAppConfig class is empty, but the MidtierDispatcherConfig defines the static resources:

    @Configuration
    @ComponentScan("my.root.package")
    @EnableWebMvc
    public class MidtierDispatcherConfig extends WebMvcConfigurerAdapter {
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry
                .addResourceHandler("/courses/**/*")
                .addResourceLocations("/WEB-INF/classes/content/")
            ;
        }
    }
    

    Now when I want to have access to my @Controller's, I use the /data/ prefix, and when I want to access to my resources, I use the /content/ prefix. Caveat is that if I have a @RequestMapping("/app") class which has a @RequestMapping("/about") method, then both the data/app/about and the content/app/about will call just that method (and without actually trying I guess I might access the resources as /app/courses/whatEverPath too), because the dispatcher listends to both "data/" and "content/", and analyzes only the rest of the url ("app/about" in both cases) to find the proper @Controller.

    Regardless, the current solution I've reached is satisfactory enough for me, so I will leave it as it is.

    0 讨论(0)
  • I am using Spring Boot 2.2.1 and with "spring-boot-starter-web" and "spring-boot-starter-tomcat". In my case the Spring Boot only could find the "/resources/" folder when I use empty "classpath:/"

    My folder structure:

    My code:

    @Configuration
    @EnableWebMvc
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry
            .addResourceHandler("/resources/**")
            .addResourceLocations("classpath:/");
        }
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**");
        }
    }
    

    And using the browser I can find any file like:

    http://localhost:8080/resources/test.txt

    http://localhost:8080/resources/images/background-1.png

    0 讨论(0)
  • 2020-11-27 05:17

    It is possible to simplify the web page's URI just to contain the filename of a resource:
    <link href="bootstrap.css" rel="stylesheet" media="screen">
    An appropriate configuration might be as the following:

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

    Spring concatenates '/resources/css/' string with whatever filename extracted from URI to identify the actual location of a resource.

    0 讨论(0)
  • 2020-11-27 05:32

    This worked for me. Files available at /resources/js/select.js. Watch out that you are not missing @EnableWebMvc annotation....

    @EnableWebMvc
    @EnableTransactionManagement
    public class ApplicationContextConfig extends WebMvcConfigurerAdapter {
    
        @Bean(name = "viewResolver")
        public InternalResourceViewResolver getViewResolver() {
            InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            viewResolver.setPrefix("/WEB-INF/views/");
            viewResolver.setSuffix(".jsp");
            return viewResolver;
        }
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/resources/**")
            .addResourceLocations("/resources/");
        }
    }
    
    0 讨论(0)
提交回复
热议问题