Spring boot 使用freemarker ftl 引入静态资源

出处:https://www.jianshu.com/p/861b8e9e2c79

我们知道在传统的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中配置静态资源文件夹的几种方式,这里做个记录。



作者:Harry_ZH_Wang
链接:https://www.jianshu.com/p/861b8e9e2c79
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值