springboot篇】二十一. 基于springboot电商项目 五 FreeMarker生成商品页面
程序员文章站
2022-07-14 08:18:14
...
springboot项目
中国加油,武汉加油!
篇幅较长,配合目录观看
案例准备
- 本案例基于springboot篇】二十一. 基于springboot电商项目 四 商品同步索引库和搜索列表实现
- gitee地址 https://gitee.com/springboot-dubbo/nz1904-springboot-shop-05
1. FreeMarker介绍
-
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写。
-
FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序。
-
虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据,简单来讲就是模板加数据模型,然后输出页面
2. Freemarker快速使用
2.1 shop-temp新建freemaker-demo(module-springboot)
2.2 导相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2.3 编写hello.ftl
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
username: ${username}
</body>
</html>
2.4 Test
package com.wpj;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest
@RunWith(SpringRunner.class)
class FreemarkerDemoApplicationTests {
@Autowired
private Configuration configuration;
@Test
public void contextLoads() throws IOException, TemplateException {
// 获取模板
Template template = configuration.getTemplate("hello.ftl");
// 设置数据
Map<String, Object> map = new HashMap<String, Object>();
map.put("username", "admin");
// 生成页面
Writer writer = new FileWriter("./hello.html");
template.process(map, writer);
writer.close();
}
}
2.5 访问
3. 生成商品静态页面
3.1 shop-web新建shop-item(module-springboot)
- Spring Boot DevTools
- Spring Web
- Apache FreeMarker
3.2 编写yml
server:
port: 8083
dubbo:
application:
name: item-web
registry:
address: zookeeper://192.168.59.100:2181
check: false
consumer:
check: false
retries: 3
3.3 编写 ftl
3.4 导入静态资源
3.5 Test
package com.wpj;
import com.alibaba.dubbo.config.annotation.Reference;
import com.wpj.entity.Goods;
import com.wpj.service.IGoodService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest
@RunWith(SpringRunner.class)
public class ShopItemApplicationTests {
@Reference
private IGoodService goodService;
@Autowired
private Configuration configuration;
@Test
public void createHtml() throws Exception{
Integer goodsId = 49;
// 1.先根据id查询商品信息
Goods goods = goodService.selectById(goodsId);
// 2.图片的集合
String[] split = goods.getGpic().split("\\|");
// 3.得到模板
Template template = configuration.getTemplate("goodsItem.ftl");
// 把数据放到Map中
Map<String,Object> map = new HashMap<>();
map.put("goods",goods);
map.put("picList",split);
map.put("contextPath","/");
// 4.设置静态页面输出的目录
String staticPath = ShopItemApplicationTests.class.getClassLoader().getResource("static").getPath();
File file = new File(staticPath+ File.separator+"goods");
// 不存在创建目录
if(!file.exists()){
file.mkdir();
}
// 生成页面
Writer writer = new FileWriter(file.getAbsolutePath()+File.separator+goodsId+".html");
template.process(map,writer);
writer.close();
}
}
3.6 启动程序入口访问
package com.wpj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(scanBasePackages = "com.wpj", exclude = DataSourceAutoConfiguration.class)
public class ShopItemApplication {
public static void main(String[] args) {
SpringApplication.run(ShopItemApplication.class, args);
}
}
3.7 编写Controller
package com.wpj.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.wpj.entity.Goods;
import com.wpj.service.IGoodService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.hibernate.validator.constraints.pl.REGON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
@Controller
@RequestMapping("/item")
public class ItemController {
@Reference
private IGoodService goodService;
@Autowired
private Configuration configuration;
@RequestMapping("/createHtml")
@ResponseBody
public String createHtml(Integer gid){
Goods goods = goodService.selectById(gid);
// 2.图片的集合
String[] split = goods.getGpic().split("\\|");
// 3.得到模板
Template template = null;
Writer writer = null;
try {
template = configuration.getTemplate("goodsItem.ftl");
// 把数据放到Map中
Map<String,Object> map = new HashMap<>();
map.put("goods",goods);
map.put("picList",split);
map.put("contextPath","/");
// 4.设置静态页面输出的目录
String staticPath = ItemController.class.getClassLoader().getResource("static").getPath();
File file = new File(staticPath+ File.separator+"goods");
// 不存在创建目录
if(!file.exists()){
file.mkdir();
}
// 生成页面
writer = new FileWriter(file.getAbsolutePath()+File.separator+gid+".html");
template.process(map,writer);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "ok";
}
}
3.7 重启程序入口访问
3.8 修改shop-search的searchGoodsList.html
<div class="li-top">
<a th:href="|http://localhost:8083/goods/${goods.id}.html|" class="li-top-tu"><img style="width: 95px;height: 100px" th:src="${#strings.listSplit(goods.gpic,'|')[0]}"/></a>
<p class="jiage"><span class="sp1" th:text="|¥${goods.gprice}|"></span><span class="sp2">¥209</span></p>
</div>
3.9 重启程序入口访问
3.10 shop-common编写工具类
package com.wpj.common.utils;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
public class HttpUtils {
public static String sendReq(String sendUrl){
StringBuffer buffer = new StringBuffer();
try {
// 创建url对象
URL url = new URL(sendUrl);
// 打开一个连接
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
// 设置属性
httpURLConnection.setRequestMethod("GET");
// 设置权限
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
// 判断是否请求成功
if(httpURLConnection.getResponseCode() == 200) {
InputStream is = httpURLConnection.getInputStream();
Scanner sc = new Scanner(is);
while (sc.hasNextLine()){
buffer.append(sc.next());
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer.toString();
}
}
3.11 goods-service导包
<dependency>
<groupId>com.wpj</groupId>
<artifactId>shop-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
3.12 goods-service修改GoodServiceImpl的方法
@Override
public int insert(Goods goods) {
int insert = super.insert(goods);
searchService.addGoods(goods);
//生成静态页面
HttpUtils.sendReq("http://localhost:8083/item/createHtml?gid="+goods.getId());
return insert;
}
3.13 校验
- localhost:8080 进去添加商品
- localhost:8081 进入查找商品
- 点进去新增的商品进入生成的页面
这三个没问题就代表代码没问题