springboot2.x系列(五)-搭建非前后端分离的单体系统搭建

本文介绍非前后端分离系统的优势,详细讲解静态资源管理、热启动配置、Freemarker模板集成及自定义函数等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现在流行的前后端分离架构,但在一些小的,简单的系统,非分离的单体系统在开发效率和维护性上实际更具优势

本文讲解非前后端系统的搭建及Freemarker模板技术和springboot的集成。

一、静态资源的存放地址

静态资源如js,img,css等

(1)公共js通过pom文件引用

通过webjars的方式引入第三方资源
访问其官网: https://www.webjars.org/
找到对应需要引入的静态资源:bootstrap、Jquery等,选择maven方式,把相应配置文件复制到我们项目的pom.xml文件中。
 
 
源代码解析:
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration自动配置类
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (! this.resourceProperties.isAddMappings()) {
logger.debug( "Default resource handling disabled");
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern( "/webjars/**")) {
this .customizeResourceHandlerRegistration(registry.addResourceHandler( new String[]{ "/webjars/**" }).addResourceLocations( new String[]{ "classpath:/META-INF/resources/webjars/" }).setCachePeriod( this .getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
 
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler( new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations( this.resourceProperties.getStaticLocations())).setCachePeriod( this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
 
}
}
 
 
1.maven
<!-- jar 的方式引入 query-->
< dependency>
< groupId>org.webjars</ groupId>
< artifactId>jquery</ artifactId>
< version>3.2.0</ version>
</ dependency>
2.查看jar结构
观察其js路径为
resource/webjars/jquery/3.2.0/jqery.js
3.调用
注意:其网络lur路径为
/webjars/jquery/3.2.0/jqery.js

 

(2)自己写静态资源放在springboot路径
    也可以自己打成jar包,但太麻烦。
推荐:springboot约定将一些目录设置为静态资源的存放地
 
springboot有默认的几个静态资源存放路径
项目下的:
JAVA、RESOURCES都是classpath
classpath:/META-INF/resources/
//下面这个几个文件夹是在resources子文件夹里,resources是maven的资源标志,不是文件路径
classpath:/resources/
classpath:/static/
classpath:/public/
/ 项目根路径
springboot为以上所有路径都默认映射了起始面文件:index.html,即如果这些目录中有index.html时,访问这个目录时,页面会显示index.html的内容。
有相同资源时文件时,优先级: resouce>static>public
 
注意:
 这个是maven路径,不是class里面的路径哈
访问:
 
注意:访问不得加resource/public/static这些路径哈,他们相当于WEBAPP
resources这些路径下可加子路径
 
源码解析
org.springframework.boot.autoconfigure.web.ResourceProperties类里约定了几个可以存放静态文件的目录
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = 
new String[]{
"classpath:/META-INF/resources/" , "classpath:/resources/" , "classpath:/static/" , "classpath:/public/" };
 
(3)设置欢迎页
 传统在web.xml里面配置欢迎页,
在spring boot默认在资源文件跟节点的resouce/static/public的index.html下即可
 
 
访问:
注意:如果跟Controller里冲突,以Controller里为准
@RestController
public class IndexControl {
WebMvcAutoConfiguration g;
@Autowired
private Person person;
@RequestMapping( "/")
public String index(){
)
 
源码解析
org.springframework.boot.autoconfigure.web.servlet. WebMvcAutoConfiguration
(4)设置网页标签里的favicon.ico
 
只要把favicon.ico保存到任何静态资源的目录下即可
 
源码解析
org.springframework.boot.autoconfigure.web.servlet. WebMvcAutoConfiguration
HTML
<head>
<meta charset= "UTF-8" >
<link rel= "icon" href= "favicon.ico" >
</head>
 
注意事项:
  放在resources/static/public三个文件夹里,通过URL都可以直接访问,所以基本用来放js,img,css,静态html等文件,
freemark模板文件这些不能放到这些文件夹里,没有安全性
 
(5)热启动
静态页面和java类修改后可立即热启动
 
1.pom配置
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
</dependency>
 
2.idea配置
(1)File-Settings-Compiler-Build Project automatically
(2)ctrl + shift + alt + /,选择Registry,勾上 Compiler autoMake allow when app running【没有找到】
 
3.属性文件 application.properties中配置
好像不配置也可以
#热部署生效
spring.devtools.restart.enabled: true
#设置重启的目录
#spring.devtools.restart.additional-paths: src/main/java
#classpath目录下的WEB-INF文件夹内容修改不重启
spring.devtools.restart.exclude: WEB-INF/**
 

二、 springboot2集成freemarker

1.pom.xml

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-freemarker</artifactId>

</dependency>

2.

(1)配置application.properties配置文件

# 是否允许HttpServletRequest属性覆盖(隐藏)控制器生成的同名模型属性。

spring.freemarker.allow-request-override=false

# 是否允许HttpSession属性覆盖(隐藏)控制器生成的同名模型属性。

spring.freemarker.allow-session-override=false

# 是否启用模板缓存。

spring.freemarker.cache=false

# 模板编码。

spring.freemarker.charset=UTF-8

# 是否检查模板位置是否存在。

spring.freemarker.check-template-location=true

# Content-Type value.

spring.freemarker.content-type=text/html

# 是否启用freemarker

spring.freemarker.enabled=true

# 设定所有request的属性在merge到模板的时候,是否要都添加到model中.

spring.freemarker.expose-request-attributes=false

# 是否在merge模板的时候,将HttpSession属性都添加到model中

spring.freemarker.expose-session-attributes=false

# 设定是否以springMacroRequestContext的形式暴露RequestContext给Spring’s macro library使用

spring.freemarker.expose-spring-macro-helpers=true

# 是否优先从文件系统加载template,以支持热加载,默认为true

spring.freemarker.prefer-file-system-access=true

# 设定模板的后缀.

spring.freemarker.suffix=.ftl

# 设定模板的加载路径,多个以逗号分隔,默认:

spring.freemarker.template-loader-path=classpath:/templates/

# 设定FreeMarker keys.

spring.freemarker.settings.template_update_delay=0

spring.freemarker.settings.default_encoding=UTF-8

spring.freemarker.settings.classic_compatible=true

spring.freemarker.settings.datetime_format=yyyy-MM-dd HH:mm:ss

spring.freemarker.settings.date_format=yyyy-MM-dd

spring.freemarker.settings.time_format=HH:mm:ss

#可采用<#或者[#作为标签

spring.freemarker.settings.tag_syntax=auto_detect

(2)application.properties文件可能不是非常的强大,可用bean配置freemarker.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:p="http://www.springframework.org/schema/p"

       xmlns:context="http://www.springframework.org/schema/context"

       xmlns:mvc="http://www.springframework.org/schema/mvc"

       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">



    <!-- springmvc 与freemarker绑定的配置 -->
    <bean id="freemarkerConfig"
          class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        <property name="templateLoaderPath" value="classpath:/templates/" /><!--模板文件存放的根路径-  -->
        <property name="defaultEncoding" value="utf-8" />
        <property name="freemarkerSettings">
            <props>
                <prop key="tag_syntax">auto_detect</prop><!-- <改成[符号 -->
                <prop key="template_update_delay">10</prop>
                <prop key="locale">zh_CN</prop>
                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                <prop key="date_format">yyyy-MM-dd</prop>
                <prop key="number_format">#.##</prop>
                <!-- 配置自定义的freemarker异常处理-->
<!--
                <prop key = "template_exception_handler">com.xbsoft.comm.freemark.FreemarkerExceptionHandler</prop>
-->
            </props>
        </property>

    </bean>

    <!-- FreeMarker视图解析   在这里配置后缀名ftl和视图解析器。。-->
    <bean id="viewResolver"  class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">

        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
        <property name="suffix" value=".html" />
        <property name="contentType" value="text/html;charset=utf-8" />
        <property name="exposeRequestAttributes" value="true" />
        <property name="exposeSessionAttributes" value="true" />
        <property name="exposeSpringMacroHelpers" value="true" />
        <property name="attributesMap">
            <!-- 自定义方法和宏注入 -->
            <map>
              <!--
                <entry key="to_date" > <bean class=" com.xbsoft.comm.freemark.ToDateMethod" /></entry>

                <entry key="to_dateTime" > <bean class=" com.xbsoft.comm.freemark.ToDateTimeMethod" /></entry>

                <entry key="dict_show" > <bean class=" com.xbsoft.comm.freemark.DictMethod" /></entry>
                <entry key="formDict" > <bean class=" com.xbsoft.comm.freemark.SRCDirective" /></entry>

-->
            </map>
        </property>
    </bean>

</beans>

在启动类引入

//启动入口注解
@ImportResource(locations = {"classpath:config/freemarker.xml"})
@SpringBootApplication
public class GirlApplication {

    public static void main(String[] args) {
        //应用启动
        SpringApplication.run(GirlApplication.class, args);
    }
}

freemarker模板一般放在templates文件目录下

三、freemarker基础语法

1.打印

1.eg

${user.address!}

 

2、null判断

    特别注意,如果属性从map取出来为null,不处理将会出错,

    所以一般输出加!

        ${user.name},异常

    ${(user.name)!},显示空白 等价${book.name?if_exists } //用于判断如果存在,就输出这个值

    ${user.name!'vakin'},若user.name不为空则显示本身的值,否则显示vakin

    ${user.name?default('vakin')},同上

3.时间展示

 

${(obj.birthday?string("yyyy-MM-dd"))!}

${(obj.tt?string("yyyy-MM-dd HH:mm:ss"))!}

注意是整个值括起来加!,这样为null才不出错

 

4.在if里面判断

<#if user.xueli??>  #如果user.xueli不为空

user.xueli存在值

</#if>

2.if语法

 

<#if user.name?? && user.name=="蒋增奎">  //注意判断时都要加user.name?? 属性存在的前提

       真鸡巴帅

    </#if>

    注意:

     <#if... #号和if必须挨着,不用有空格

 

     <#if condition>...

    <#elseif condition2>...

    <#elseif condition3>......

    <#else>...

    </#if>

 

<#assign age=23>

<#if (age>60)>老年人

<#elseif (age>40)>中年人

<#elseif (age>20)>青年人

<#else> 少年人

</#if>

3.switch语句

<#switch value>

    <#case refValue1>

     ...

     <#break>    //break退出

    <#case refValue2>

    ...

    <#break>

    ...

    <#case refValueN>

     ...

     <#break>

    <#default>

     ...

  </#switch>

4.list语法

<#list users as user>  //usaer是迭代对象里面的别名

 

</#list>

users即可以是一个list对象,也可以是个数组

     List<User> list=new Vector<User>();

     或者

     <@my.list  items=["mouse", "elephant", "python"] title="Animals"/>

list还有数组循环如

<#macro repeat count=5>

         <#list 1..count as x>

                 <li>${x}</li>

         </#list>

</#macro>

 

判断list是否有值

   [#if newss?size==0]

    机构暂无新闻

[/#if]

 

 

  List指令还隐含了两个循环变量:

item_index:当前迭代项在所有迭代项中的位置,是数字值。

item_has_next:用于判断当前迭代项是否是所有迭代项中的最后一项。

注意:在使用上述两个循环变量时,一定要将item换成你自己定义的循环变量名,item其实就是前缀罢了。

例如,如果你使用<# list list as l>..</#list>定义,那么就要使用l_index,l_has_next。

   

   在循环过程中,如果您想跳出循环,那么可以使用结合break指令,即<#break>来完成。

 

   注意:boolean不是直接用${}输出,只能用于判断

<#if user_has_next>

还有下一个

</#if>

这样写是错的${user_has_next} ;

这样写可以:${user_has_next?String("yes","no")}

include和import包含文件

include指令的作用类似于JSP的包含指令,用于包含指定页,include指令的语法格式如下

         <#include filename [options]

          在上面的语法格式中,两个参数的解释如下

          a、filename:该参数指定被包含的模板文件

          b、options:该参数可以省略,指定包含时的选项,包含encoding和parse两个选项,encoding指定包含页面时所使用的解码集,而parse指定被

             包含是否作为FTL文件来解析。如果省略了parse选项值,则该选项值默认是true

      例:<#include   "inc.ftl">

 

 

<#include "/inc/inc1.ftl">

<#include "/inc/inc2.ftl">

${username}

两个里面都有相同变量,则将实现先后覆盖

 

出现这种情况,在两个模版中都分别存在变量名都相同的变量的时候,include包含进来,会进行覆盖,include只时候将其公共的静态文件进行包含,而里面不涉及到内部函数以及变量声明之类的,当涉及到这种问题,我们就要用import进行导入

 

 

注意1:controller里面的绑定数据,在include里面也可以读取

 

@RequestMapping("/include")

public String include(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception{

User user=new User(1,"jzk",new Date(),new BigDecimal("34.56"));

 

model.addAttribute("user",user);

return "main";

}

 

在包含文件里:

${user.userName!}

 

注意2:include会把包含页面的所有html代码读取过来,不仅仅是显示值

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

老子有敢抢:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

</head>

<body>

jzk

</body>

</html></body>

</html>

 

而里面不涉及到内部函数以及变量声明之类的,当涉及到这种问题,我们就要用import进行导入
会在主命名空间中创建两个变量. 如果再引入同名的变量时就会被后引入的或者新定义的覆盖.这样就不是很好,因为只想让它们在"My Test Library"命名空间中.就需要用 import代替include了
 
 
1. my_test.ftl
< #macro copyright date >
< p > Copyright (C) ${date} Julia Smith. All rights reserved.
< br > Email: ${mail} </ p >
</ #macro >
 
2.new file
< #import "/lib/my_test.ftl" as my >
< #assign mail =" fred@acme.com " >
< @my .copyright date ="1999-2002" />
${my.mail}
${mail}
 
输出:
<p>
Copyright (C) 1999-2002 Julia Smith.All rights reserved.
 
  <br>Email : jsmith@acme.com
 
</p>
 
 
7、宏定义
 
 
宏的定义
宏就是可以反复使用的代码块,类似其他语言的函数或者方法
 
<#--第一个参数[name]表示这个macro的name,后面为参数,可以N个-->
<#macro name param1,param2,param3,....>
    $ {param1}
    $ {param2}
</#macro>
 
 
注意:
使用的参数一定要事先定义;
 
定义的参数在使用的时候一定要进行赋值,除非在创建macro的时候给参数默认值;
 
参数所能赋予的值不一定是字符串,也可以是其他类型,还可以是一个预运算表达式
 
  在使用的时候,对参数赋值顺序不确定,可随意
 
参数是局部变量,只能在宏定义中有效
如果变量没有默认值,则要放在有默认值的变量前面,否则要出错
如:
宏的基本案例-code
 
[#macro greet]
< font size= "+2" > Hello Joe! </ font >
[/#macro]
 
[#macro greet person]
< font size= "+2" > Hello ${person}! </ font >
[/#macro]
 
[#macro user name address]
< font size= "+2" > Hello ${name},your address:${address}! </ font >
[/#macro]
 
[#macro emp name address=" 九眼桥 "]
< font size= "+2" > Hello ${name},your address:${address}! </ font >
[/#macro]
 
 
[#macro border]
< table border= 4 cellspacing= 0 cellpadding= 4 >< tr >< td >
[#nested]
</ tr ></ td ></ table >
[/#macro]
 
 
1. 不带参数的宏 < br >
[@greet][/@greet]
< p ></ p >
2. 带参数的宏 < br >
[@greet person=" 蒋增奎 "/]
< p ></ p >
3. 带多参数的宏 , 参数顺序无所谓 < br >
[@user address=" 天府大道 " name=" 蒋增奎 "/]
< p ></ p >
 
4. 可以指定默认值 < br >
[@emp address=" 天府大道 " name=" 蒋增奎 "/]
< p ></ p >
不传递参数,则使用默认值 < br >
[@emp name=" 蒋增奎 "/]
< p ></ p >
5. 宏可以嵌套内容 ,nested < br >
[@border] 我才你吗 [/@border]
< p ></ p >
生成html
1.不带参数的宏<br>
<font size="+2">Hello !</font>
<p></p>
 
2.带参数的宏<br>
<font size="+2">Hello 蒋增奎!</font>
<p></p>
 
3.带多参数的宏,参数顺序无所谓<br>
<font size="+2">Hello 蒋增奎,your address:天府大道!</font>
<p></p>
 
4.可以指定默认值<br>
<font size="+2">Hello 蒋增奎,your address:天府大道!</font>
<p></p>
不传递参数,则使用默认值<br>
<font size="+2">Hello 蒋增奎,your address:九眼桥!</font>
<p></p>
 
5.宏可以嵌套内容<br>
<table border=4 cellspacing=0 cellpadding=4><tr><td>
我才你吗</tr></td></table>
<p></p>
 
名字空间
 
 
  <#macro copyright date> 
    <p>Copyright (C) ${date} Julia Smith. All rights reserved. 
    <br>Email: ${mail}</p> 
  </#macro>  
  <#assign mail = " jsmith@acme.com "> 
 
使用import指令导入库到模板中,Freemarker会为导入的库创建新的名字空间,并可以通过import指令中指定的散列变量访问库中的变量: 
 
  <#import "/lib/my_test.ftl" as my > 
  <#assign mail=" fred@acme.com "> 
  <@my.copyright date="1999-2002"/> 
  ${my.mail} 
  ${mail} 
 
输出结果: 
 
<p>Copyright (C) 1999-2002 Julia Smith. All rights reserved. 
    <br>Email: jsmith@acme.com </p> 
注意
宏的参数不一定是字符串,一定非得有初始值
 
 
8.宏复杂传参对象
 
 
Java
 
@RequestMapping ( "/macro" )
public String macro(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception{
 
List<User> list= new ArrayList<User>();
User user1= new User( 1 , "jzk1" , new Date(), new BigDecimal( "34.56" ));
list.add(user1);
User user2= new User( 1 , "jzk2" , new Date(), new BigDecimal( "34.56" ));
list.add(user2);
User user3= new User( 1 , "jzk3" , new Date(), new BigDecimal( "34.56" ));
list.add(user3);
model.addAttribute( "userList1" ,list);
model.addAttribute( "tblId1" , "3" );
return "macro" ;
}
macro.html
<!--定义宏-->
 
[#macro usertTbl userList id]
< table border= 1 cellspacing= 0 cellpadding= 4 style= " width : 100 % " id= "${id}" >
< tr >< td > id </ td >< td > name </ td >< td > birth </ td >< td > age </ td ></ tr >
[#list userList as user]
< tr >
< td > ${user.userId!} </ td >
< td > ${user.userName!} </ td >
< td > ${(user.birth?string("yyyy-MM-dd"))!} </ td >
< td > ${user.age!} </ td >
</ tr >
[/#list]
</ table >
[/#macro]
 
<!--展示-->
 
6. 宏复杂参数 < br >
[@usertTbl userList=userList1 id=tblId1][/@usertTbl]
 
 
 
输出代码
 
<table border=1 cellspacing=0 cellpadding=4 style="width:100%" id="3">
    <tr><td>id</td><td>name</td><td>birth</td><td>age</td></tr>
    <tr>
        <td>1</td>
        <td>jzk1</td>
        <td>2020-05-03</td>
        <td>34.56</td>
    </tr>
    <tr>
        <td>1</td>
        <td>jzk2</td>
        <td>2020-05-03</td>
        <td>34.56</td>
    </tr>
    <tr>
        <td>1</td>
        <td>jzk3</td>
        <td>2020-05-03</td>
        <td>34.56</td>
    </tr>
</table>
 
 
说明
1.参数可以没有初始值及类型,根据传入参数而定
[#macro usertTbl userList id]
 
2.在引用宏的时候,参数变量就是后端的定义变量,不需要加${}符号
[@usertTbl userList=userList1 id=tblId1][/@usertTbl]
 
3.在宏定义里面使用变量,首先去找对应的后台使用有这个变量名,如果有的话会自动匹配,其次才找传递参数
 
[#macro usertTbl userList id]
< table border= 1 cellspacing= 0 cellpadding= 4 style= " width : 100 % " id= "${id}" >
< tr >< td > id </ td >< td > name </ td >< td > birth </ td >< td > age </ td ></ tr >
[#list userList as user]
。。。
 
如果对应java类里有 userList变量,则能直接使用
注意
 
定义的参数在使用的时候一定要进行赋值,除非在创建macro的时候给参数默认值;
 
参数所能赋予的值不一定是字符串,也可以是其他类型,还可以是一个预运算表达式
 
  在使用的时候,对参数赋值顺序不确定,可随意
 
参数是局部变量,只能在宏定义中有效
如果变量没有默认值,则要放在有默认值的变量前面,否则要出错
如:
<#macro  radio    name=""  dicts xxx    val=""  >会报错
正确写法
 
<#macro  radio dicts xxx   name=""      val=""  >
 
9.自定义函数
 
 
自定义类
 
要继承 freemarker.template.TemplateMethodModelEx类,实现 exec方法
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
 
import java.util.List;
 
/**
* @class: com.jyj.controll.ToDate
* @author: jiangzengkui
* @company: 教育家
* @create: 2020-05-03 09:41
* @description:
* @updateRemark:
*/
public class ToDate implements TemplateMethodModelEx {
 
@Override
public Object exec(List params) throws TemplateModelException {
String ret = " 返回值 " ;
 
return ret;
 
}
 
}
自定义绑定
1.单页面使用
 
如果在一个页面使用,可以直接在ctroller对应方法里绑定
model.addAttribute( "dictShow" , new com.jyj.controll.ToDate());
 
2.设置成全局变量
 
springmvc的xml配置
 
    <!-- FreeMarker视图解析   在这里配置后缀名ftl和视图解析器。。-->
<bean id="viewResolver"  class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
  
  <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
  <property name="suffix" value=".html" />
  <property name="contentType" value="text/html;charset=utf-8" />
  <property name="exposeRequestAttributes" value="true" />
  <property name="exposeSessionAttributes" value="true" />
  <property name="exposeSpringMacroHelpers" value="true" />
      <property name="attributesMap">
      <!-- 自定义方法和宏注入 -->
           <map>
          <!-- 把日期类型显示成yyyy-mm-dd格式 -->
            <entry key="to_date" > <bean class=" com.xbsoft.comm.freemark.ToDateMethod " /></entry>
            <!-- 把日期类型显示成yyyy-mm-dd HH:mm:ss格式 -->
             <entry key="to_dateTime" > <bean class=" com.xbsoft.comm.freemark.ToDateTimeMethod " /></entry>
            <!-- 把数据字典的编码显示成对应中文 -->
            <entry key="dict_show" > <bean class=" com.xbsoft.comm.freemark.DictMethod " /></entry>
          </map>
        </property>
</bean>
 
3.springBoot2集成全局变量
 
 
import org.springframework.context.annotation. Bean ;
import org.springframework.context.annotation. Configuration ;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
 
import javax.annotation. PostConstruct ;
import java.util.HashMap;
import java.util.Map;
 
/**
* @class: com.jyj.config.FreemarkerConfig
* @author: jiangzengkui
* @company: 教育家
* @create: 2020-05-03 10:52
* @description:
* @updateRemark:
*/
@Configuration
public class FreemarkerConfig {
/**
* 增加自定义视图变量和方法
*
* @return
*/
@Bean
public CommandLineRunner customFreemarker(FreeMarkerViewResolver resolver) {
return new CommandLineRunner() {
@Override
public void run(String... strings) throws Exception {
 
Map map = resolver .getAttributesMap();
 
//把自定义函数压入map
map.put("dictShow", new com.jyj.controll.ToDate());
}
};
}
}
 
 
 
页面使用
直接用${声明的行数名(参数.......)}即可
${dictShow()}
 
实例
 
 
自定义函数
import java.util.*;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModelException;
/**
 * 数据字典自定义函数
* @author   jiangzengkui
* @date 2016年9月2日 下午11:02:36
* @Description :  显示编码对应的中文值
* 调用如:${dict_show("BM044",form.service_type!)}
*
 */
public class DictMethod implements TemplateMethodModelEx  {
             /**
             * params [0]=字典名称:,如:BM - 001
             * params1]=字典编码 如1
             */
             @Override
             public Object exec( List params) throws TemplateModelException {
                        String ret= "";
                        String dictName= ""; //字典名称:,如:BM-001
                        String dictCode= ""; //字典编码 如1
                         if( params== null || params.size()<2){
                                     throw new TemplateModelException( "参数个数不够");
                        }
                        Object obj1= params.get(0); //参数1
                        Object obj2= params.get(1); //参数2
                         if( "freemarker.core.DefaultToExpression$EmptyStringAndSequence".equals( obj2.getClass().getName())){
                                     return ret;
                        }
                         if( obj2== null || obj2.toString().trim().length()==0){ //如果没有编码值,则直接返回
                                     return ret;
                        }
                        
                         if( obj1== null || obj1.toString().trim().length()==0)
                                     throw new TemplateModelException( "必须传递数据字典值");
                        
         dictName= obj1.toString().trim();
         dictCode= obj2.toString().trim();
                ret=(String)DictManager. getInstance().getDictShow( dictName, dictCode);
                        
                        
                         return  ret;
            }
            
}
绑定
  <!-- FreeMarker视图解析   在这里配置后缀名 ftl 和视图解析器。。-->
  < bean id= "viewResolver"  class= "org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" >
 
  < property name= "viewClass" value= "org.springframework.web.servlet.view.freemarker.FreeMarkerView" ></ property >
  < property name= "suffix" value= ".html" />
  < property name= "contentType" value= "text/html;charset=utf-8" />
  < property name= "exposeRequestAttributes" value= "true" />
  < property name= "exposeSessionAttributes" value= "true" />
  < property name= "exposeSpringMacroHelpers" value= "true" />
      < property name= "attributesMap" >
      <!-- 自定义方法和宏注入 -->
          < map >
          <!-- 把日期类型显示成 yyyy - mm - dd 格式 -->
            < entry key= "to_date" > < bean class= " com.xbsoft.comm.freemark.ToDateMethod " /></ entry >
            <!-- 把日期类型显示成 yyyy - mm - dd HH:mm:ss格式 -->
             < entry key= "to_dateTime" > < bean class= " com.xbsoft.comm.freemark.ToDateTimeMethod " /></ entry >
            <!-- 把数据字典的编码显示成对应中文 -->
            < entry key = "dict_show" > < bean class = " com.xbsoft.comm.freemark.DictMethod " /></ entry >
            < entry key= "formDict" > < bean class= " com.xbsoft.comm.freemark.SRCDirective " /></ entry >
            <!-- 机构课程的选择 业务通用类 -->
            < entry key= "courseDict" > < bean class= " com.xbsoft.xqb.comm.OrgCourseDirective " /></ entry >
             < entry key= "addressDict" > < bean class= " com.xbsoft.xqb.comm.OrgAddressDirective " /></ entry >
             < entry key= "teaDict" > < bean class= " com.xbsoft.xqb.comm.OrgTeaDirective " /></ entry >
              < entry key= "tgDict" > < bean class= " com.xbsoft.xqb.comm.TgDirective " /></ entry >
              < entry key= "pcDict" > < bean class= " com.xbsoft.xqb.comm.PbCourseDirective " /></ entry >
             
          </ map >
        </ property >
  </ bean >
HTML
 ${dict_show("BM202",car.biansu_type!"")}
注意
在html里面传递参数,直接从ctroller里的绑定变量名即可,不需要用${}等
 
 
10.自定义标签 TemplateDirectiveModel
 
TemplateDirectiveModel
这个类和TemplateMethodModelEx 作用类似,都是用于自定义标签,但其扩展性更好
 
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
 
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Map;
 
/**
* @author: jiangzengkui
* @company: 教育家
* @create: 2020-05-03 16:33
* @description:
* @updateRemark:
*/
public class TestDirectiveModel implements TemplateDirectiveModel {
/**
*
* @param env 运行环境
* @param params 标签传递过来的参数
* @param loopVars
* @param body
* @throws TemplateException
* @throws IOException
*/
@Override
public void execute(Environment env, Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException {
String out= "" ; // 向页面输出内容
 
out= " 输出内容 " ;
 
/**
* 打印输入的标签参数测试
*/
Iterator<Map.Entry<String, Object>> it = params.entrySet().iterator();
while (it.hasNext()){
Map.Entry<String, Object> entry = it.next();
System. out .println( "key:" +entry.getKey()+ " val:" +entry.getValue());
}
 
 
// 内容输出到页面
Writer print=env.getOut();
print.write(out);
}
}
绑定
绑定方法和 TemplateMethodModelEx一致
 
@Bean
public CommandLineRunner customFreemarker(FreeMarkerViewResolver resolver) {
return new CommandLineRunner() {
@Override
public void run(String... strings) throws Exception {
 
Map map = resolver .getAttributesMap();
map.put( "dictShow" , new com.jyj.controll.ToDate());
map.put( "to_date" , new com.jyj.comm.ToDateMethod());
map.put( "testTag" , new com.jyj.comm.TestDirectiveModel());
}
};
}
页面引用,和其他freemarker标签一致
[@标签名  参数....]
 
[@formDict etype="select" dictName="BM031"  name="class_week" id="${t.class_week!}"  value="${t.class_week!}" isEmpty="true"  class="input_text"  /]
 
注意:这里传递值需要用${}取出来,这个和自定义函数不一样
 
11.运算符
 
比较运算符号

 

1  =或者==:判断两个值是否相等. 
2  !=:判断两个值是否不等. 
3  >或者gt:判断左边值是否大于右边值 
4  >=或者gte:判断左边值是否大于等于右边值 
5  <或者lt:判断左边值是否小于右边值 
6  <=或者lte:判断左边值是否小于等于右边值 
注意 :  =和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,"x","x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)> 
并且或者或者
 
逻辑与:&& 
逻辑或:|| 
逻辑非:! 
逻辑运算符只能作用于布尔值,否则将产生错误 
 
<#if user.name?? && user.name=="蒋增奎">  //注意判断时都要加user.name?? 属性存在的前提
[#if newsList?size==0]  //list长度等于零
 
<#if user.name??> 变量是否存在
 
</#if>
 
 [#if form.role_code??  && form.role_code !=""]
存在并且不等于空
[/#if]
 
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值