freemarker页面静态化/页面预览
项目结构图
配置文件
-
pom.xml
<!-- springboot 中自带的页面渲染工具为thymeleaf 还有freemarker 这两种模板引擎 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
-
application.yml
server: port: 31001 spring: application: name: xc‐service‐manage‐cms data: mongodb: uri: mongodb://root:123@localhost:27017 database: xc_cms # 添加freemarker配置 freemarker: cache: false # 关闭模板缓存, 方便测试 settings: template_update_delay: 0 # 立即刷新
配置类
-
MongoConfig
package com.xuecheng.manage_cms.config; import com.mongodb.MongoClient; import com.mongodb.client.MongoDatabase; import com.mongodb.client.gridfs.GridFSBucket; import com.mongodb.client.gridfs.GridFSBuckets; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @Author: 潇哥 * @DateTime: 2020/11/2 下午5:25 * @Description: GridFSBucket用于打开下载流对象 */ @Configuration public class MongoConfig { // 把application.yml中的配置信息赋值给db @Value("${spring.data.mongodb.database}") private String db; @Bean public GridFSBucket getGridFSBucket(MongoClient mongoClient) { // 获取数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase(db); // 获取打开下载流 GridFSBucket gridFSBucket = GridFSBuckets.create(mongoDatabase); return gridFSBucket; } }
Dao层
-
CmsPageRepository
package com.xuecheng.manage_cms.dao; import com.xuecheng.framework.domain.cms.CmsPage; import org.springframework.data.mongodb.repository.MongoRepository; /** * @Author: 潇哥 * @DateTime: 2020/10/18 下午2:35 * @Description: 这里使用的是 springframework.data.mongodb这个包 */ // MongoRepository: 第一个泛型实体类, 第二个泛型实体类中的id public interface CmsPageRepository extends MongoRepository<CmsPage, String> { }
-
CmsTemplateRepository
package com.xuecheng.manage_cms.dao; import com.xuecheng.framework.domain.cms.CmsTemplate; import org.springframework.data.mongodb.repository.MongoRepository; /** * @Author: 潇哥 * @DateTime: 2020/10/18 下午2:35 * @Description: 这里使用的是 springframework.data.mongodb这个包 */ // MongoRepository: 第一个泛型实体类, 第二个泛型实体类中的id public interface CmsTemplateRepository extends MongoRepository<CmsTemplate, String> { }
-
CmsConfigRepository
package com.xuecheng.manage_cms.dao; import com.xuecheng.framework.domain.cms.CmsConfig; import org.springframework.data.mongodb.repository.MongoRepository; /** * @Author: 潇哥 * @DateTime: 2020/10/18 下午2:35 * @Description: 这里使用的是 springframework.data.mongodb这个包 */ // MongoRepository: 第一个泛型实体类, 第二个泛型实体类中的id public interface CmsConfigRepository extends MongoRepository<CmsConfig, String> { }
Service层
-
PageServiceImpl----(页面静态化)
package com.xuecheng.manage_cms.service.impl; import com.mongodb.client.gridfs.GridFSBucket; import com.mongodb.client.gridfs.GridFSDownloadStream; import com.mongodb.client.gridfs.model.GridFSFile; import com.xuecheng.framework.domain.cms.CmsPage; import com.xuecheng.framework.domain.cms.CmsTemplate; import com.xuecheng.framework.domain.cms.response.CmsCode; import com.xuecheng.framework.exception.ExceptionCast; import com.xuecheng.manage_cms.dao.CmsPageRepository; import com.xuecheng.manage_cms.dao.CmsTemplateRepository; import com.xuecheng.manage_cms.service.PageService2; import freemarker.cache.StringTemplateLoader; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.gridfs.GridFsResource; import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.web.client.RestTemplate; import java.io.IOException; import java.util.Map; import java.util.Optional; /** * @Author: 潇哥 * @DateTime: 2020/10/18 下午3:27 * @Description: TODO */ @Service("pageService") public class PageServiceImpl implements PageService { @Autowired private CmsPageRepository cmsPageRepository; @Autowired private CmsTemplateRepository cmsTemplateRepository; @Autowired private GridFsTemplate gridFsTemplate; @Autowired private GridFSBucket gridFSBucket; @Autowired private RestTemplate restTemplate; /** * 根据配置id查询配置信息 * @param id * @return */ @Override public CmsConfig getConfigById(String id) { Optional<CmsConfig> optional = cmsConfigRepository.findById(id); // 判断结果是否为空 if (optional.isPresent()) { // 不为空返回查询的结果信息 return optional.get(); } return null; } /** * 根据页面id查询信息 * @param id * @return */ @Override public CmsPage findById(String id) { Optional<CmsPage> cmsPage = cmsPageRepository.findById(id); // 查询不到页面信息时 if (!cmsPage.isPresent()) { return null; } return cmsPage.get(); } /** * 根据页面id生成静态化页面 * @param pageId * @return */ @Override public String getPageHtml(String pageId) { // 获取数据模型 Map model = this.getModelByPageId(pageId); if (model == null) { ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_DATAISNULL); } // 获取模板文件 String template = this.getTemplateByPageId(pageId); if (template == null) { ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_TEMPLATEISNULL); } // 生成静态化 String html = this.generateHtml(template, model); if (html == null) { ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_TEMPLATEISNULL); } return html; } /** * 生成静态文件 * @param template * @param model * @return */ private String generateHtml(String template, Map model) { // 定义配置类 Configuration configuration = new Configuration(Configuration.getVersion()); // 使用模板加载器变为模板 StringTemplateLoader stringTemplateLoader = new StringTemplateLoader(); stringTemplateLoader.putTemplate("template", template); // 在配置中设置模板加速器 configuration.setTemplateLoader(stringTemplateLoader); try { // 获取模板的内容 Template template1 = configuration.getTemplate("template"); // 静态化 String html = FreeMarkerTemplateUtils.processTemplateIntoString(template1, model); return html; } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } return null; } /** * 获取页面模板 * @param pageId * @return */ private String getTemplateByPageId(String pageId) { // 查询页面信息 CmsPage cmsPage = this.findById(pageId); if (cmsPage == null) { // 页面不存在 ExceptionCast.cast(CmsCode.CMS_PAGE_NOT_FOUND); } // 获取模板id String templateId = cmsPage.getTemplateId(); if (templateId == null) { // 模板id不存在 ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_TEMPLATEISNULL); } // 查询模板信息 Optional<CmsTemplate> optional = cmsTemplateRepository.findById(templateId); if (!optional.isPresent()) { // 模板信息不存在 ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_TEMPLATEISNULL); } // 获取模板信息 CmsTemplate cmsTemplate = optional.get(); // 获取模板文件id String templateFileId = cmsTemplate.getTemplateFileId(); if (templateFileId == null) { // 模板文件id不存在 ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_TEMPLATEISNULL); } // 取出模板文件内容 GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(templateFileId))); // 打开下载流对象 GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId()); // 创建gridFsResource对象 GridFsResource gridFsResource = new GridFsResource(gridFSFile, gridFSDownloadStream); try { String content = IOUtils.toString(gridFsResource.getInputStream(), "utf-8"); return content; } catch (IOException e) { e.printStackTrace(); } return null; } /** * 获取数据模型 * @param pageId * @return */ private Map getModelByPageId(String pageId) { // 查询cmsPage CmsPage cmsPage = this.findById(pageId); if (cmsPage == null) { // 页面不存在 ExceptionCast.cast(CmsCode.CMS_PAGE_NOT_FOUND); } // 获取数据url String dataUrl = cmsPage.getDataUrl(); if (StringUtils.isBlank(dataUrl)) { // dataUrl不存在 ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_DATAURLISNULL); } // 远程访问dataUrl连接 ResponseEntity<Map> forEntity = restTemplate.getForEntity(dataUrl, Map.class); // 获取数据模型 Map body = forEntity.getBody(); return body; } }
Controller层
-
CmsConfigController
package com.xuecheng.manage_cms.controller; import com.xuecheng.api.cms.CmsConfigControllerApi; import com.xuecheng.framework.domain.cms.CmsConfig; import com.xuecheng.manage_cms.service.PageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @Author: 潇哥 * @DateTime: 2020/10/18 下午2:15 * @Description: TODO */ @RestController @RequestMapping("/cms/config") public class CmsConfigController implements CmsConfigControllerApi { @Autowired private PageService pageService; @GetMapping("/getmodel/{id}") @Override public CmsConfig getModel(@PathVariable("id") String id) { return pageService.getConfigById(id); } }
-
CmsPagePreviewController----(页面预览)
package com.xuecheng.manage_cms.controller; import com.xuecheng.framework.web.BaseController; import com.xuecheng.manage_cms.service.PageService; 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.RequestMethod; import javax.servlet.ServletOutputStream; /** * @Author: 潇哥 * @DateTime: 2020/11/3 下午8:32 * @Description: 预览文件 */ @Controller public class CmsPagePreviewController extends BaseController { @Autowired private PageService pageService; /** * 预览文件 * @param pageId * @throws Exception */ @RequestMapping(value = "/cms/preview/{pageId}", method = RequestMethod.GET) public void preview(@PathVariable("pageId") String pageId) throws Exception { // 获取静态化页面 String pageHtml = pageService.getPageHtml(pageId); // 获取输出流 ServletOutputStream outputStream = response.getOutputStream(); // 把静态化文件写回 outputStream.write(pageHtml.getBytes("utf-8")); } }
启动类
-
ManageCmsApplication
package com.xuecheng.manage_cms; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; /** * @Author: 潇哥 * @DateTime: 2020/10/16 下午11:13 * @Description: TODO */ // 扫描该包同级或以下的所有包 @SpringBootApplication // 扫描实体类 @EntityScan("com.xuecheng.framework.domain.cms") // 扫描接口 @ComponentScan(basePackages = {"com.xuecheng.api"}) // 扫描common包下的类 @ComponentScan(basePackages = {"com.xuecheng.framework"}) // 扫描本项目下的所有类, 不写也行, 我这里写的原因是方便别人看好维护 @ComponentScan(basePackages = {"com.xuecheng.manage_cms"}) public class ManageCmsApplication { public static void main(String[] args) { SpringApplication.run(ManageCmsApplication.class, args); } /** * 注入远程调用工具 RestTemplate * @return */ @Bean public RestTemplate restTemplate() { return new RestTemplate(new OkHttp3ClientHttpRequestFactory()); } }