1、使用freemarker实现网页静态化
a)Freemarker的使用方法
b)Freemarker的模板的语法
c)Freemarker整合springmvc
2、ActiveMq同步生成静态网页
3、SSO单点登录
访问pojo中的属性
public class Student {
private int id;
private String name;
private int age;
private String address;
//省略了空参数和有参数的构造方法,以及set和get方法
}
@Test
public void testFreemarker() throws Exception{
Configuration configuration=new Configuration(Configuration.getVersion());
configuration.setDirectoryForTemplateLoading(new File("E:/20200520/e3-item-web/src/main/webapp/WEB-INF/ftl"));
configuration.setDefaultEncoding("utf-8");
Template template=configuration.getTemplate("student.ftl");
Map map=new HashMap<>();
Student stu=new Student(1, "zhangsan", 18, "Shanghai");
map.put("stu", stu);
Writer out=new FileWriter(new File("E:\\freemarker\\stu.html"));
template.process(map, out);
out.close();
}
取集合中的数据
<#list studentList as stu>
${stu.id}/${stu.name}
</#list>
@Test
public void testFreemarker() throws Exception{
Configuration configuration=new Configuration(Configuration.getVersion());
configuration.setDirectoryForTemplateLoading(new File("E:/20200520/e3-item-web/src/main/webapp/WEB-INF/ftl"));
configuration.setDefaultEncoding("utf-8");
Template template=configuration.getTemplate("student.ftl");
Map map=new HashMap<>();
List<Student> stuList=new ArrayList<Student>();
stuList.add(new Student(10, "zhangsan", 11, "Shanghai1"));
stuList.add(new Student(20, "zhangsan", 12, "Shanghai"));
stuList.add(new Student(30, "zhangsan", 13, "Shanghai3"));
map.put("studentList", stuList);
Writer out=new FileWriter(new File("E:\\freemarker\\stu.html"));
template.process(map, out);
out.close();
}
取循环中的下标
<#list studentList as stu>
${stu_index}
</#list>
判断
<#if student_index % 2 == 0>
<#else>
</#if>
日期类型格式化
Null值的处理
!表示默认值 后面不写和写""效果一样
判断 ?? 判断这个值是否为空 如果为空走else
判断不为空
Include标签(注意这个模板名称要相对路径可以找到)
<#include “模板名称”>
Freemarker整合springMVC
引入jar包:
Freemarker的jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
创建整合spring的配置文件(springmvc.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:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置freemarker -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
</beans>
编写Controller进行测试
商品详情页面静态化
分析:
生成的时机:添加商品生成静态页面
静态页面保存的位置:保存到磁盘的任意目录
静态页面的访问:使用nginx访问静态页面
商品id+“.html”
把jsp改造成freemarker模板
将e3-item-web下的复制到ftl文件夹,并将后缀jsp改成ftl,打开item.ftl删除jsp相关的内容(记得header.jsp里面jsp内容也要删除,并且要改成header.ftl)
item.ftl中的fmt要删除
变成这样
变成
添加商品发消息这个功能已经实现了,因此只需要在e3-item-web中订阅话题就可以了
配置activemq的客户端
添加activemq的jar包
创建一个MessageListener的实现类
配置spring和Activemq整合
我们要接收消息,从消息中将商品id取出来,生成对应的静态页面
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
</dependency>
//监听商品添加消息,生成对应的静态页面
public class MyMessageListener implements MessageListener{
@Autowired
private ItemService itemService;
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@Value("${HTML_GEN_PATH}")
private String HTML_GEN_PATH;
@Override
public void onMessage(Message message) {
try {
//创建一个模板,参考jsp
//从消息中取商品id
TextMessage textMessage=(TextMessage) message;
String text = textMessage.getText();
Long itemId=new Long(text);
//等待事务提交
Thread.sleep(1000);
//根据商品id查询商品信息,商品基本信息和商品描述
TbItem tbItem = itemService.findTbItemById(itemId);
//把TbItem转换成Item对象
Item item=new Item(tbItem);
//根据商品id查询商品描述
TbItemDesc tbItemDesc = itemService.getTbItemDescById(itemId);
//创建一个数据集,把商品数据封装
Map data=new HashMap<>();
data.put("item", item);
data.put("itemDesc", tbItemDesc);
//加载模板对象
Configuration configuration = freeMarkerConfigurer.getConfiguration();
Template template = configuration.getTemplate("item.ftl");
//创建一个输出流,指定输出的目录及文件名 这里的目录不能写死,写在配置文件中
Writer out=new FileWriter(new File(HTML_GEN_PATH +itemId+".html"));
//生成静态页面
template.process(data, out);
//关闭流
out.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
配置文件applicationContext-activemq.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.0.246:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!--这个是主题目的地,一对多的 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="itemAddTopic" />
</bean>
<!-- 监听商品添加消息,同步索引库 -->
<bean id="myMessageListener" class="cn.e3mall.item.listener.MyMessageListener"/>
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicDestination" />
<property name="messageListener" ref="myMessageListener" />
</bean>
</beans>
测试,从后台添加商品后,到生成的静态页面打开这个生成的html就可以了
通过nginx来访问这个文件(直接打开window版本的nginx)
修改好配置后,启动nginx(已经启动过了,因此重启nginx.exe -s reload)
访问路径
将e3-item-web下的静态资源复制过来,效果如图
什么是sso系统
SSO:单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
集群环境下会出现要求用户多次登录的情况。
解决方案:
- 配置tomcat集群。配置tomcat的Session复制。节点数不要超过5个。
- 可以使用Session服务器,保存Session信息,使每个节点是无状态。需要模拟Session。
单点登录系统是使用redis模拟Session,实现Session的统一管理。
什么是集群
同一套代码部署好多台服务器
什么是分布式
把我们的项目拆成若干个工程,每个工程只实现一部分功能,要完成整个业务功能,需要多个系统之间相互配合
需要创建一个sso服务工程,可以参考e3-content创建。
e3-sso(pom聚合工程)
|--e3-sso-interface(jar)
|--e3-sso-service(war)
e3-sso-web
e3-sso的pom.xml里面的的端口是8087
e3-sso-interface直接复制过去
e3-sso-service依赖e3-sso-interface
复制e3-content-service的配置文件
删除resource.properties里面的内容
修改applicationContext-service.xml里面的内容
修改applicationContext-trans.xml里面的内容
复制web.xml过来
e3-sso-web参考e3-portal-web
pom.xml
删除resource.properties里面的内容,修改springmvc.xml
复制e3-portal-web的web.xml,修改里面的内容
静态文件
由于web.xml里面的url是/,因此需要在springmvc.xml里面配置
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
测试是否搭建完成
//用户注册
@Controller
public class RegisterController {
@RequestMapping("/page/register")
public String showRegister(){
return "register";
}
}