美文网首页
Spring boot 使用freemarker ftl 引入静

Spring boot 使用freemarker ftl 引入静

作者: TryCatch菌 | 来源:发表于2018-10-05 01:09 被阅读0次

    我们知道在传统的Spring MVC项目中需要配置静态资源文件夹才能访问到静态文件,boot中同样如此,不过boot追求的少的配置,讲究开箱即用,所以boot给我们默认了几个静态文件路径

    classpath:/static
    classpath:/public
    classpath:/resources
    classpath:/META-INF/resources
    

    优先级:META-INF/resources > resources > static > public

    首先来示范一下默认的静态资源文件夹,这里就不做优先级展示了,有兴趣的可以自己建立几个文件夹,然后放不同图片且同名的文件试一下,这里就一个static文件夹


    image.png

    做一个简单的freemarker模板,然后一个简单的控制器跳转,特别说明一点,做WEB项目的时候如果静态资源放在自己的工程静态目录下,而没有用文件服务器之类的东西,一般不会直接写相对路径,什么../xxx.jpg这种,喜欢标记项目路径,在freemarker中也有很多方式直接获取到路径,这里暂时两种,一种是用spring.ftl,一种是在application.properties配置文件中配置,这里先展示下效果,再说下用法。

    package com.wzh.demo.controller;
    
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import com.wzh.demo.domain.UserBean;
    import com.wzh.demo.service.IUserService;
    
    @Controller
    @RequestMapping("/user")
    public class userTestController {
    
        @RequestMapping("/img.do")
        public String showImg(Model model)
        {
            model.addAttribute("imgName","test.png");
            return "/test/img";
        }
    }
    
    <#import "spring.ftl" as spring />
    <!DOCTYPE html>
    <html>
      <head>
        <title>MyHtml.html</title>
        
        <meta name="keywords" content="keyword1,keyword2,keyword3">
        <meta name="description" content="this is my page">
        <meta name="content-type" content="text/html; charset=UTF-8">
        
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
      </head>
      
      <body>
        <img src="<@spring.url'/imge/${imgName}'/>" width="300px"/>
        <img src="${request.contextPath }/imge/${imgName}" width="300px"/>
      </body>
    </html>
    
    

    展示效果


    image.png

    在img标签的src 中用了两种路径的标记,一种是@spring.url,一种是request.contextPath。
    @spring.url是基于spring-webmvc-4.3.6.RELEASE.jar中的spring.ftl文件实现的,其中调用rul宏的前缀可以自己定义,根据你import as 的别名

    <#import "spring.ftl" as spring />
    

    我们点开spring.ftl,可以找到定义url的方法,可以看出就是通过操作上下文获得的路径

    <#--
     * url
     *
     * Takes a relative URL and makes it absolute from the server root by
     * adding the context root for the web application.
     -->
    <#macro url relativeUrl extra...><#if extra?? && extra?size!=0>${springMacroRequestContext.getContextUrl(relativeUrl,extra)}<#else>${springMacroRequestContext.getContextUrl(relativeUrl)}</#if></#macro>
    
    <#--
    
    image.png

    第二种是配置文件中配置,本质也是通过上下文

    spring.freemarker.request-context-attribute=request
    

    同样的,在开发中因为这样那样的原因,我们需要自定义静态资源文件夹,下面就演示一下如何自定义静态资源文件夹,配置的方式有两种,一种是在代码中配置,还有一种是在application.properties中配置。
    为了区别之前的static文件夹,新建一个webStatic文件夹


    image.png

    这个时候webStatic路径并没有配置为静态资源文件夹,因为web的安全机制,我们是无法直接通过下面这种路径方式去访问的,会报404

     <img src="${request.contextPath }/pic/${imgName}" width="300px"/>
     <img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
    
    image.png

    通过代码配置,在配置注解上这里使用@Configuration注解,注意不要用MVC的@EnableWebMvc, @EnableWebMvc注解会使sping boot默认关于webmvc的配置都会失效

    package com.wzh.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    /**
     * Spring MVC 配置类,这里只配置静态资源
     * 这里使用的@Configuration注解,注意不要用MVC的@EnableWebMvc,
     * @EnableWebMvc注解会使sping boot默认关于webmvc的配置都会失效
     */
    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
        /**
         * 重写路径配置方法,添加自定义的路径
         * @param registry
         */
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            //将所有/webStatic/** 访问都映射到classpath:/webStatic/ 目录下
            registry.addResourceHandler("/webStatic/**").addResourceLocations("classpath:/webStatic/");
        }
    
    }
    
    

    测试访问


    image.png

    测试发现,static文件夹下的资源和我们自定义的webStatic下的资源都能访问,并不影响Spring Boot的默认映射,可以同时使用。
    不过如果如果我们将/webStatic/**修改为 /**与默认的相同时,则会覆盖系统的配置。

    package com.wzh.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    /**
     * Spring MVC 配置类,这里只配置静态资源
     * 这里使用的@Configuration注解,注意不要用MVC的@EnableWebMvc,
     * @EnableWebMvc注解会使sping boot默认关于webmvc的配置都会失效
     */
    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
        /**
         * 重写路径配置方法,添加自定义的路径
         * @param registry
         */
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            //将所有/** 访问都映射到classpath:/webStatic/ 目录下
            registry.addResourceHandler("/**").addResourceLocations("classpath:/webStatic/");
        }
    
    }
    
    

    因为都映射到了webStatic所以不需要文件夹前缀了

    <img src="<@spring.url'/imge/${imgName}'/>" width="300px"/>
        <img src="${request.contextPath }/pic/${imgName}" width="300px"/>
    

    测试访问发现默认配置失效了,所以/**的配置方式看实际项目情况权衡。

    image.png

    演示代码配置的路径只有一个,其实可以多次使用 addResourceLocations添加目录,优先级先添加的高于后添加的。
    查看源码就可以看出addResourceHandler和addResourceLocations的参数是动参,可以同时添加多个参数。

    public ResourceHandlerRegistration addResourceHandler(String... pathPatterns) {
            ResourceHandlerRegistration registration = new ResourceHandlerRegistration(this.applicationContext, pathPatterns);
            this.registrations.add(registration);
            return registration;
        }
    
    public ResourceHandlerRegistration addResourceLocations(String... resourceLocations) {
            String[] var2 = resourceLocations;
            int var3 = resourceLocations.length;
    
            for(int var4 = 0; var4 < var3; ++var4) {
                String location = var2[var4];
                this.locations.add(this.resourceLoader.getResource(location));
            }
    
            return this;
        }
    

    演示下配置不同的访问配置一个路径和同一个路径配置多个文件夹,先新建3个文件夹img1,img2,img3


    image.png

    配置映射路径

    package com.wzh.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    /**
     * Spring MVC 配置类,这里只配置静态资源
     * 这里使用的@Configuration注解,注意不要用MVC的@EnableWebMvc,
     * @EnableWebMvc注解会使sping boot默认关于webmvc的配置都会失效
     */
    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
        /**
         * 重写路径配置方法,添加自定义的路径
         * @param registry
         */
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            //将所有/webStatic/** 访问都映射到classpath:/webStatic/ 目录下
            registry.addResourceHandler("/webStatic/**").addResourceLocations("classpath:/webStatic/");
    
            //将所有/img/**访问路径映射到img1,img2,img这个文件夹实际是不存在的,这里只是做个路径映射
            registry.addResourceHandler("/img/**").addResourceLocations("classpath:/img1/","classpath:/img2/");
    
            //将所有/album1/**,/album2/**访问路径映射到img3,album这个文件夹实际是不存在的,这里只是做个路径映射
            registry.addResourceHandler("/album1/**","/album2/**").addResourceLocations("classpath:/img3/");
    
        }
    
    }
    
    

    页面

    <img src="<@spring.url'/imge/${imgName}'/>" width="300px"/>
        <img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
        <img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
        <img src="${request.contextPath }/img/test1.png" width="300px"/>
        <img src="${request.contextPath }/img/test2.png" width="300px"/>
        <img src="${request.contextPath }/album1/test3.png" width="300px"/>
        <img src="${request.contextPath }/album2/test3.png" width="300px"/>
    

    测试都能成功正常访问


    image.png

    通过配置文件配置访问路径,如果多个路径,和代码配置一样,逗号隔开

    #SpringMVC 配置静态资源路径
    spring.mvc.static-path-pattern=/img4/**
    spring.resources.static-locations=classpath:/img4/,classpath:/img5/
    

    页面

    <img src="<@spring.url'/imge/${imgName}'/>" width="300px"/>
        <img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
        <img src="${request.contextPath }/webStatic/pic/${imgName}" width="300px"/>
        <img src="${request.contextPath }/img/test1.png" width="300px"/>
        <img src="${request.contextPath }/img/test2.png" width="300px"/>
        <img src="${request.contextPath }/album1/test3.png" width="300px"/>
        <img src="${request.contextPath }/album2/test3.png" width="300px"/>
        <img src="${request.contextPath }/img4/test4.png" width="300px"/>
        <img src="${request.contextPath }/img4/test5.png" width="300px"/>
    

    运行测试,发现第一张图片,也就是我们使用系统默认的static文件夹路径的404了,因为当在配置文件中配置了spring.mvc.static-path-pattern就会使默认的路径失效。

    image.png

    同样,在项目比较大的时候我们处理静态文件一般有静态文件服务器,不过在项目比较小的时候文件和程序是放在一起的,这个时候一般有两种场景,第一种就是上面这种,项目文件夹在项目中,还有一种是在项目外面,通过绝对路径去访问。

    #SpringMVC 配置静态资源路径
    web.static-path=/Users/wzh/IdeaProjects/staticTest/
    spring.mvc.static-path-pattern=/img4/**
    spring.resources.static-locations=classpath:/img4/,classpath:/img5/,file:${web.static-path}
    

    web.static-path这个是自定义路径,在配置文件中自己定义的参数,名字可以自己取,因为配置的是路径,参数记得以/结尾,特别说明下这个路径,和项目的运行系统是有关系的,如果是windows 要写成D:/XX/XX/这种。
    spring.mvc.static-path-pattern配置的是静态资源的访问路径,等同于代码中的addResourceHandler方法。
    spring.resources.static-locations配置的是映射的路径的正式路径,等同于代码中的addResourceLocations方法,最末尾的file:${web.static-path}之所有要加file:是因为指定的是一个具体的硬盘路径,其他的使用classpath指的是系统环境变量,如果需要在代码中配置绝对路径,只需要classpath改为file就可以了,其他的都不变。

    以上就是在boot中配置静态资源文件夹的几种方式,这里做个记录。

    相关文章

      网友评论

          本文标题:Spring boot 使用freemarker ftl 引入静

          本文链接:https://www.haomeiwen.com/subject/wdbvoftx.html