- 前端页面的发展过程
1) JSP:Html+java代码组成要一个大的Servlet类,然后放到容器中执行
缺点:繁杂而不利与维护
本质上是“模板” 通过规则和标签抽象出来的
2) 模板引擎:
著名的模板引擎有:
Freemarker velocity thymeleaf beetl(国人开创的,据说性能很高)
3) 基于api的前后端分离 (Tomcat+nginx)
将前端的代码部署到web服务器上,将后端的代码部署到应用服务器上,web
服务器通过ajax访问应用服务器
Web服务器:解析静态资源的 如:nginx apache
应用服务器:解析静态和动态资源 如:Tomcat jetty
两者的关系:(web服务器是前台接待—是外网访问,应用服务器是核心
价值提供者----是内网访问的) - 模板引擎的原理
模板的诞生是为了将显示与数据分离,其本质是将模板文件和数据通过模板引擎生成最终的html代码,模板引擎的实现方式,是利用正则表达式识别模板标识,然后将数据替换其中的标识 - 引擎的执行过程
利用正则表达式分解出普通字符串和模板标识符
将模板标识符转换成普通的语言表达式
生成待执行语句,
将数据填入执行,生成最终的字符串
FreeMarker是一款模板引擎:即一种基于模板和要改变的数据,并用来生成输出文本(HTML页面,电子邮件,配置文件,源代码等)的通用工具,他不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件
特点:
FreeMarker并不关心数据的来源,只是根据模板的内容,将数据模型在模板中显示并输出文件(通常为Html,也可以生成其它格式的文本文件)
freeMarker作为Springmvc一种视图格式,默认情况下SpirngMvc支持freeMarker试图格式。需要创建Spring Booot-Freemarker工程用于测试模板
- 引入FreeMarker启动器依赖spring-boot-starter-freemarker
org.springframework.boot spring-boot-starter-freemarker 2.4.5
- 在priperties或yaml中配置视图的路径(也可不配置,默认如下)
#设置spirngmvc模板的位置
spring:
mvc:
view: #有两大属性,prefix:前缀 suffix:后缀
prefix: /templates/ #templates不能修改名称
suffix: .ftlh #freeMarker的后缀是 .ftlh
注:低版本后缀名为.ftl
server:
port: 8888
mybatis:
type-aliases-package: com.zuxia.entity
mapper-locations: classpath:mapper/*.xml
# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/userdb?useUnicode=true&characterEncoding=utf-8
username: root
# 1.配置生成的password
password: 123456
# Druid数据源配置
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECt 1 FROM DUAL
#申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
testWhileIdle: true
#配置从连接池获取连接时,是否检查连接有效性,true每次都检查;false不检查。做了这个配置会降低性能。
testOnBorrow: false
#配置向连接池归还连接时,是否检查连接有效性,true每次都检查;false不检查。做了这个配置会降低性能。
testOnReturn: false
#打开PsCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
#合并多个DruidDatasource的监控数据
useGlobalDataSourceStat: true
#通过connectProperties属性来打开mergesql功能罗慢sQL记录
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500;
#配置DruidStatFilter
web-view-servlet:
enabled: true
url-pattern: "/*"
exclusions: ".js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
# 配置 DruidStatViewServlet
stat-view-servlet:
url-pattern: "/druid/*"
# IP 白名单,没有配置或者为空,则允许所有访问
allow: 127.0.0.1
# IP 黑名单,若白名单也存在,则优先使用
deny: 192.168.31.253
# 禁用 HTML 中 Reset All 按钮
reset-enable: false
# 登录用户名/密码
login-username: root
login-password: 123
#设置springmvc模板的位置
mvc:
view:
suffix: /templates/
prefix: .ftlh
- 前端页面 index.ftlh
Title
${name}欢迎登陆
- Controller中
package com.zuxia.controller;
import com.zuxia.entity.User;
import com.zuxia.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/User")
public class UserController {
@RequestMapping("/tofreemker")
public String FreemkerPage(Map map){
System.out.println("===========");
map.put("name","zhangsan"); //页面可以用${key}来获取值
return "index";
}
}
FreeMarker指令
一:遍历List集合
a)注释:即<#- - 注释的内容- ->,介于其之间的内容会被FreeMarker忽略
b)取值:即${…},freeMarker会用真实的值代替${…}
c)FTL指令:和HTML标记类似,名字前面加#予以区分,FreeMarker会解析标签中的表达式或逻辑,如:<#list key值 as 别名> #list>和
d)文本,仅文本信息,这些不是FreeMarker的注释、插值、FTL指令的内容会被FreeMarker忽略解析,直接输出内容
如遍历所有的用户信息
前端页面
用户信息展示
| 索引 | 编号 | 登录名 | 登录密码 | 真实名字 | 电话 | <#list userList as user>|
| <#--注意:_index:得到循环的下标,使用方法是在user之后加“_index”,它的值是从0开始的--> | ${user_index} | ${user.uid} | ${user.loginname} | ${user.loginpwd} | ${user.uname} | ${user.uphone} |
注意:_index:得到循环的下标,使用方法是在user之后加“_index”,它的值是从0开始的
Controller类中
package com.zuxia.controller;
import com.zuxia.entity.User;
import com.zuxia.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/User")
public class UserController {
@Autowired
private IUserService iUserService;
@RequestMapping("/Allfind")
//查询所有的用户信息
public ModelAndView Allfind(){
ModelAndView mv=new ModelAndView();
List userList= iUserService.selectALl();
mv.addObject("userList",userList);
mv.setViewName("showUser");
return mv;
}
}
二:遍历Map集合
a)查看Map集合中单独一个元素:${集合名[key].属性名}
b)遍历所有的key :<#list userMap ? keys as k> #list> keys为固定的,k可以随便起
前端页面
用户信息展示
<#--查看Map集合中单独一个元素:${集合名[key].属性名}-->
查看1号用户的信息
登录名:${userMap['2'].uname}
| 索引 | 编号 | 登录名 | 登录密码 | 真实名字 | 电话 | <#list userMap ? keys as k><#--相当于遍历所有的key-->||
| <#--注意:_index:得到循环的下标,使用方法是在user之后加“_index”,它的值是从0开始的--> | ${k_index} | ${userMap[k].uid} | <#-- 也可以写${k} | ,因为k就是用户编号-->${userMap[k].loginname} | ${userMap[k].loginpwd} | ${userMap[k].uname} | ${userMap[k].uphone} |
controller类
package com.zuxia.controller;
import com.zuxia.entity.User;
import com.zuxia.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/User")
public class UserController {
@Autowired
private IUserService iUserService;
//以Map形式遍历用户信息
@RequestMapping("/AllfindMap")
public ModelAndView AllfindMap(){
ModelAndView mv=new ModelAndView();
List userList= iUserService.selectALl();
Map userMap=new HashMap<>();
//将List集合转换为Map
for(User user:userList){
userMap.put(user.getUid().toString(),user);
}
mv.addObject("userMap",userMap);
mv.setViewName("showUserMap");
return mv;
}
}
注:FreeMarker在遍历map集合时,key必须是String
三:if指令
if指令即为判断指令,是常用的FTL指令,FreeMarker在解析时遇到if会判断,条件为真则执行if中间的内容,否则跳过内容不输出
a)判断某变量是否存在使用“??”,用法为:<#if 变量名??>#if> ,如果该变量存在,返回true,否则返回false
如:判断传递过来的userList是否为空,则用
<#if userList??> <#--如果userList为空,则为false,则不执行里面的内容-->
<#list userList as user>
<#--注意:_index:得到循环的下标,使用方法是在user之后加“_index”,它的值是从0开始的-->
............
#list>
#if>
b)缺失变量默认值使用"!",使用!要指定一个默认值,当变量为空时显示默认值。
如判断身份证号是否为空
<#if userList??> <#--如果userList为空,则为false,则不执行里面的内容-->
<#list userList as user>
<#--注意:_index:得到循环的下标,使用方法是在user之后加“_index”,它的值是从0开始的-->
${user_index}
。。。。。。。。。
${user.rid ! '无'} <#--如果为空,则显示无-->
。。。。。。。。。。
#list>
#if>
if中支持的运算符
a) 算数运算符FreeMarker表达式完全支持算术运算,FreeMarker支持的算术运算包括+,-,*,/,%
b) 逻辑运算符有符合如下几个:逻辑与:&& 逻辑非:! 逻辑或:|| 逻辑运算符只能作用与布尔值,否则将产生错误
c) 比较运算符有如下几个:=或==、!=、>或gt、>=或gte、<或lt、<=或lte
注:=和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,最好使用英文的
如:如果用户名为张三,则改变字体颜色
#if>>${user.uname}
四:内置函数
内置函数语法格式:变量+?+函数名称
- 内置函数获取某个集合的大小:${集合名?函数名} 如:${today?date}
- 内置函数日期化格式化
显示年月日:${today?date}
显示时分秒:${today?time}
显示日期+时间:${today?datetime}
自定义时间格式:${today?string(“yyyy年MM月dd日”)}
如:
${user.hiredate?date} ${user.hiredate?string("yyyy年MM月dd日")} <#--string()可以指定输入格式-->
- 内置函数将JSON字符串转换为对象,其中用到了assign标签,assign的作用是定义一个变量
如:
<#assign text="{'name':'zhangsan','address':'兰州'}"/>
<#assign data=text?eval/>
用户名:${data.name} 地址:${data.address}
<#--
相当于JS中的 var=text="{'name':'zhangsan','address':'兰州'}"
eval(text)//进行解析text
-->



