大家都知道淘宝、天猫、京东以及聚美之类的电商网站,她们的商品页会存在多套模板,各套模板的元数据是一样的,只是展示方式不一样。特别是对于店主而言商品详情页个性化需求非常多,就商品单页各个维度信息来说,数据来源也是非常多的。这时候,如果我们再实时的去查询各个数据源组织数据,对于数据库来说开销是巨大的,秒杀更是如此。
在这里我们就做一个简单商品详情页静态页生成,大家工作中根据实际情况做调整优化。后面如果大家对商品详情页架构感兴趣,可以去了解下《亿级流量网站架构核心技术》书中的如何构建需求响应式亿级商品详情页,毕竟前人栽树后人乘凉,里面还是有很多大家可以借鉴的地方。
我们选用freemarker做模板,pom.xml引入:
<!-- freemarker 模版 生成静态页 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
application.properties配置相关参数:
#freemarker(用于商品静态页生成简化版) spring.freemarker.template-loader-path=classpath:/static/template/ spring.freemarker.suffix=.flt spring.freemarker.enabled=true spring.freemarker.cache=false spring.freemarker.charset=UTF-8 spring.freemarker.content-type=text/html spring.freemarker.allow-request-override=false spring.freemarker.check-template-location=true spring.freemarker.expose-request-attributes=false spring.freemarker.expose-session-attributes=false spring.freemarker.expose-spring-macro-helpers=false #商品静态页 spring.freemarker.html.path = D://file//
goods.flt定义商品单页模板:
# 模板太大了,这里不做展示,请自行参考源码 static/template/goods.flt
ICreateHtmlService静态化接口:
/** * 生成商品静态页 * 创建者 小柒2012 */ public interface ICreateHtmlService { Result createAllHtml(); }
CreateHtmlServiceImpl静态化实现:
@Service public class CreateHtmlServiceImpl implements ICreateHtmlService { private static int corePoolSize = Runtime.getRuntime().availableProcessors(); //多线程生成静态页面 private static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize+1, 10l, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(1000)); @Autowired public Configuration configuration; @Autowired private SeckillRepository seckillRepository; @Value("${spring.freemarker.html.path}") private String path; @Override public Result createAllHtml() { List<Seckill> list = seckillRepository.findAll(); final List<Future<String>> resultList = new ArrayList<Future<String>>(); for(Seckill seckill:list){ resultList.add(executor.submit(new createhtml(seckill))); } for (Future<String> fs : resultList) { try { System.out.println(fs.get());//打印各个线任务执行的结果,调用future.get() 阻塞主线程,获取异步任务的返回结果 } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } return Result.ok(); } class createhtml implements Callable<String> { Seckill seckill; public createhtml(Seckill seckill) { this.seckill = seckill; } @Override public String call() throws Exception { Template template = configuration.getTemplate("goods.flt"); File file= new File(path+seckill.getSeckillId()+".html"); Writer writer = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); template.process(seckill, writer); return "success"; } } }
最后通过swagger-ui页面执行以下生成商品页操作,不出意外目录下会生成四个商品页面,打开如下图所示: