网站开发如何报价,wordpress修改文章页面模板,网站后台多附件上传,摄影大赛官网文章目录一.页面静态化流程二.数据模型1.轮播图DataUrl接口1#xff09;需求分析2#xff09;接口定义3#xff09;Dao4#xff09;Service5#xff09;Controller6#xff09;测试2.远程请求接口1#xff09;添加依赖2#xff09;配置RestTemplate3#xff09;测试Re…
文章目录一.页面静态化流程二.数据模型1.轮播图DataUrl接口1需求分析2接口定义3Dao4Service5Controller6测试2.远程请求接口1添加依赖2配置RestTemplate3测试RestTemplate三.模板管理1.模板管理业务流程2.模板制作1编写模板文件2模板测试3.GridFS研究124.模板存储12四.静态化测试1.填写页面DataUrl1修改页面管理前端的page_edit.vue2修改页面管理服务端PageService2.静态化程序一.页面静态化流程
页面静态化需要准备数据模型和模板先知道数据模型的结构才可以编写模板因为在模板中要引用数据模型中的数据本节将系统讲解CMS页面数据模型获取、模板管理及静态化的过程。
下边讨论一个问题如何获取页面的数据模型
CMS管理了各种页面CMS对页面进行静态化时需要数据模型但是CMS并不知道每个页面的数据模型的具体内 容它只管执行静态化程序便可对页面进行静态化所以CMS静态化程序需要通过一种通用的方法来获取数据模 型。
在编辑页面信息时指定一个DataUrl此DataUrl便是获取数据模型的Url它基于Http方式CMS对页面进行静态 化时会从页面信息中读取DataUrl通过Http远程调用的方法请求DataUrl获取数据模型。
管理员怎么知道DataUrl的内容呢举例说明 此页面是轮播图页面它的DataUrl由开发轮播图管理的程序员提供。 此页面是精品课程推荐页面它的DataUrl由精品课程推荐的程序员提供。 此页面是课程详情页面它的DataUrl由课程管理的程序员提供。
页面静态化流程如下图 1、静态化程序首先读取页面获取DataUrl。 2、静态化程序远程请求DataUrl得到数据模型。 3、获取页面模板。 4、执行页面静态化。 二.数据模型
1.轮播图DataUrl接口
1需求分析
CMS中有轮播图管理、精品课程推荐的功能以轮播图管理为例说明轮播图管理是通过可视化的操作界面由管理员指定轮播图图片地址最后将轮播图图片地址保存在cms_config集合中下边是轮播图数据模型 针对首页的轮播图信息、精品推荐等信息的获取统一提供一个Url供静态化程序调用这样我们就知道了轮播图页面、精品课程推荐页面的DataUrl管理员在页面配置中将此Url配置在页面信息中。
本小节开发一个查询轮播图、精品推荐信息的接口此接口供静态化程序调用获取数据模型。
2接口定义
轮播图信息、精品推荐等信息存储在MongoDB的cms_config集合中 cms_config有固定的数据结构如下
文件位置xcEduService01\xc-framework-model\src\main\java\com\xuecheng\framework\domain\cms\CmsConfig.java
package com.xuecheng.framework.domain.cms;import lombok.Data;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.List;Data
ToString
Document(collection cms_config)
public class CmsConfig {Idprivate String id;private String name;private ListCmsConfigModel model;}数据模型项目内容如下
文件位置xcEduService01\xc-framework-model\src\main\java\com\xuecheng\framework\domain\cms\CmsConfigModel.java
package com.xuecheng.framework.domain.cms;import lombok.Data;
import lombok.ToString;import java.util.Map;Data
ToString
public class CmsConfigModel {private String key;private String name;private String url;private Map mapValue;private String value;
}上边的模型结构可以对照cms_config中的数据进行分析。其中在mapValue 中可以存储一些复杂的数据模型内容。 根据配置信息Id查询配置信息定义接口如下
文件位置xcEduService01\xc-service-api\src\main\java\com\xuecheng\api\cms\CmsConfigControllerApi.java
package com.xuecheng.api.cms;import com.xuecheng.framework.domain.cms.CmsConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;Api(valuecms配置管理接口,description cms配置管理接口提供数据模型的管理、查询接口)
public interface CmsConfigControllerApi {ApiOperation(根据id查询CMS配置信息)public CmsConfig getmodel(String id);
}3Dao
定义CmsConfig的dao接口
文件位置xcEduService01\xc-service-manage-cms\src\main\java\com\xuecheng\manage_cms\dao\CmsConfigRepository.java
package com.xuecheng.manage_cms.dao;import com.xuecheng.framework.domain.cms.CmsConfig;
import org.springframework.data.mongodb.repository.MongoRepository;public interface CmsConfigRepository extends MongoRepositoryCmsConfig,String {
}4Service
定义Service实现根据id查询CmsConfig信息
文件位置xcEduService01\xc-service-manage-cms\src\main\java\com\xuecheng\manage_cms\service\PageService.java //根据id查询cmsConfigpublic CmsConfig getConfigById(String id){OptionalCmsConfig optional cmsConfigRepository.findById(id);if(optional.isPresent()){CmsConfig cmsConfig optional.get();return cmsConfig;}return null;}5Controller
文件位置xcEduService01\xc-service-manage-cms\src\main\java\com\xuecheng\manage_cms\controller\CmsConfigController.java
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;RestController
RequestMapping(/cms/config)
public class CmsConfigController implements CmsConfigControllerApi {AutowiredPageService pageService;OverrideGetMapping(/getmodel/{id})public CmsConfig getmodel(PathVariable(id) String id) {return pageService.getConfigById(id);}
}
6测试
使用postman测试接口 get请求http://localhost:31001/cms/config/getmodel/5a791725dd573c3574ee333f 轮播图信息
2.远程请求接口
SpringMVC提供 RestTemplate请求http接口RestTemplate的底层可以使用第三方的http客户端工具实现http 的 请求常用的http客户端工具有Apache HttpClient、OkHttpClient等本项目使用OkHttpClient完成http请求 原因也是因为它的性能比较出众。
1添加依赖
文件位置xcEduService01\xc-service-manage-cms\pom.xml
dependencygroupIdcom.squareup.okhttp3/groupIdartifactIdokhttp/artifactId
/dependency2配置RestTemplate
在SpringBoot启动类中配置 RestTemplate 文件位置xcEduService01\xc-service-manage-cms\src\main\java\com\xuecheng\manage_cms\ManageCmsApplication.java
...
public class ManageCmsApplication {
public static void main(String[] args) {
SpringApplication.run(ManageCmsApplication.class,args);
}
Bean
public RestTemplate restTemplate() {
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
}3测试RestTemplate
根据url获取数据并转为map格式
文件位置xcEduService01\xc-service-manage-cms\src\test\java\com\xuecheng\manage_cms\RestTemplateTest.java
Test
public void testRestTemplate(){
ResponseEntityMap forEntity
restTemplate.getForEntity(http://localhost:31001/cms/config/get/5a791725dd573c3574ee333f, Map.class);
System.out.println(forEntity);
}三.模板管理
1.模板管理业务流程
CMS提供模板管理功能业务流程如下
1要增加新模板首先需要制作模板模板的内容就是Freemarker ftl模板内容。 2通过模板管理模块功能新增模板、修改模板、删除模板。 3模板信息存储在MongoDB数据库其中模板信息存储在cms_template集合中模板文件存储在GridFS文件系 统中。
cms_template集合 下边是一个模板的例子其中templateFileId是模板文件的ID此ID对应GridFS文件系统中文件ID。
2.模板制作
1编写模板文件
1、轮播图页面原型 在门户的静态工程目录有轮播图的静态页面路径是/include/index_banner.html
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/titlelink relstylesheet href/plugins/normalize-css/normalize.css /link relstylesheet href/plugins/bootstrap/dist/css/bootstrap.css /link relstylesheet href/css/page-learing-index.css /link relstylesheet href/css/page-header.css /
/head
body
div classbanner-rolldiv classbanner-itemdiv classitem stylebackground-image: url(../img/widget-bannerB.jpg);/divdiv classitem stylebackground-image: url(../img/widget-bannerA.jpg);/divdiv classitem stylebackground-image: url(../img/widget-banner3.png);/divdiv classitem stylebackground-image: url(../img/widget-bannerB.jpg);/divdiv classitem stylebackground-image: url(../img/widget-bannerA.jpg);/divdiv classitem stylebackground-image: url(../img/widget-banner3.png);/div/divdiv classindicators/div
/div
script typetext/javascript src/plugins/jquery/dist/jquery.js/script
script typetext/javascript src/plugins/bootstrap/dist/js/bootstrap.js/script
script typetext/javascriptvar tg $(.banner-item .item);var num 0;for (i 0; i tg.length; i) {$(.indicators).append(span/span);$(.indicators).find(span).eq(num).addClass(active);}function roll() {tg.eq(num).animate({opacity: 1,z-index: num}, 1000).siblings().animate({opacity: 0,z-index: 0}, 1000);$(.indicators).find(span).eq(num).addClass(active).siblings().removeClass(active);if (num tg.length - 1) {num 0;} else {num;}}$(.indicators).find(span).click(function() {num $(this).index();roll();});var timer setInterval(roll, 3000);$(.banner-item).mouseover(function() {clearInterval(timer)});$(.banner-item).mouseout(function() {timer setInterval(roll, 3000)});
/script
/body
/html2、数据模型为 通过http 获取到数据模型如下 下图数据模型的图片路径改成可以浏览的正确路径。
{ _id : ObjectId(5a791725dd573c3574ee333f), _class : com.xuecheng.framework.domain.cms.CmsConfig, name : 轮播图, model : [{key : banner1, name : 轮播图1地址, value : http://192.168.101.64/group1/M00/00/01/wKhlQFp5wnCAG-kAAATMXxpSaMg864.png}, {key : banner2, name : 轮播图2地址, value : http://192.168.101.64/group1/M00/00/01/wKhlQVp5wqyALcrGAAGUeHA3nvU867.jpg}, {key : banner3, name : 轮播图3地址, value : http://192.168.101.64/group1/M00/00/01/wKhlQFp5wtWAWNY2AAIkOHlpWcs395.jpg}]
}3、编写模板 在freemarker测试工程中新建模板index_banner.ftl复制index_banner.html并修改。 文件位置xcEduService01\test-freemarker\src\main\resources\templates\index_banner.ftl
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/titlelink relstylesheet hrefhttp://www.xuecheng.com/plugins/normalize-css/normalize.css /link relstylesheet hrefhttp://www.xuecheng.com/plugins/bootstrap/dist/css/bootstrap.css /link relstylesheet hrefhttp://www.xuecheng.com/css/page-learing-index.css /link relstylesheet hrefhttp://www.xuecheng.com/css/page-header.css /
/head
body
div classbanner-rolldiv classbanner-item#--div classitem stylebackground-image: url(http://www.xuecheng.com/img/widget-bannerB.jpg);/divdiv classitem stylebackground-image: url(http://www.xuecheng.com/img/widget-bannerA.jpg);/divdiv classitem stylebackground-image: url(http://www.xuecheng.com/img/widget-banner3.png);/divdiv classitem stylebackground-image: url(http://www.xuecheng.com/img/widget-bannerB.jpg);/divdiv classitem stylebackground-image: url(http://www.xuecheng.com/img/widget-bannerA.jpg);/divdiv classitem stylebackground-image: url(http://www.xuecheng.com/img/widget-banner3.png);/div--#if model??#list model as itemdiv classitem stylebackground-image: url(${item.value});/div/#list/#if/divdiv classindicators/div
/div
script typetext/javascript srchttp://www.xuecheng.com/plugins/jquery/dist/jquery.js/script
script typetext/javascript srchttp://www.xuecheng.com/plugins/bootstrap/dist/js/bootstrap.js/script
script typetext/javascriptvar tg $(.banner-item .item);var num 0;for (i 0; i tg.length; i) {$(.indicators).append(span/span);$(.indicators).find(span).eq(num).addClass(active);}function roll() {tg.eq(num).animate({opacity: 1,z-index: num}, 1000).siblings().animate({opacity: 0,z-index: 0}, 1000);$(.indicators).find(span).eq(num).addClass(active).siblings().removeClass(active);if (num tg.length - 1) {num 0;} else {num;}}$(.indicators).find(span).click(function() {num $(this).index();roll();});var timer setInterval(roll, 3000);$(.banner-item).mouseover(function() {clearInterval(timer)});$(.banner-item).mouseout(function() {timer setInterval(roll, 3000)});
/script
/body
/html2模板测试
在freemarker测试工程编写一个方法测试轮播图模板代码如下 文件位置xcEduService01\test-freemarker\src\main\java\com\xuecheng\test\freemarker\controller\FreemarkerController.java
Autowired
RestTemplate restTemplate;RequestMapping(/banner)
public String index_banner(MapString, Object map){
String dataUrl http://localhost:31001/cms/config/getmodel/5a791725dd573c3574ee333f;
ResponseEntityMap forEntity restTemplate.getForEntity(dataUrl, Map.class);
Map body forEntity.getBody();
map.putAll(body);
return index_banner;
}请求http://localhost:8088/freemarker/banner
3.GridFS研究
1
2
4.模板存储
1
2
四.静态化测试
上边章节完成了数据模型和模板管理的测试下边测试整个页面静态化的流程流程如下 1填写页面DataUrl 在编辑cms页面信息界面page_edit.vue中添加DataUrl并将此字段保存到cms_page集合中。 2静态化程序获取页面的DataUrl 3静态化程序远程请求DataUrl获取数据模型。 4静态化程序获取页面的模板信息 5执行页面静态化
1.填写页面DataUrl
修改页面管理模板代码实现编辑页面DataUrl。 注意此地址由程序员提供给系统管理员由系统管理员录入到系统中。 下边实现页面修改界面录入DataUrl
1修改页面管理前端的page_edit.vue
首先来看一下cms_page的模型代码: 文件位置:\xcEduService01\xc-framework-model\src\main\java\com\xuecheng\framework\domain\cms\CmsPage.java
package com.xuecheng.framework.domain.cms;import lombok.Data;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.Date;
import java.util.List;Data
ToString
Document(collection cms_page)
public class CmsPage {/*** 页面名称、别名、访问地址、类型静态/动态、页面模版、状态*///站点IDprivate String siteId;//页面IDIdprivate String pageId;//页面名称private String pageName;//别名private String pageAliase;//访问地址private String pageWebPath;//参数private String pageParameter;//物理路径private String pagePhysicalPath;//类型静态/动态private String pageType;//页面模版private String pageTemplate;//页面静态化内容private String pageHtml;//状态private String pageStatus;//创建时间private Date pageCreateTime;//模版idprivate String templateId;//参数列表private ListCmsPageParam pageParams;//模版文件Idprivate String templateFileId;//静态文件Idprivate String htmlFileId;//数据Urlprivate String dataUrl;}
接下来在首页表单中添加dataUrl输入框 文件位置xc-ui-pc-sysmanage\src\module\cms\page\page_edit.vue
el‐form‐item label数据Url propdataUrl
el‐input v‐modelpageForm.dataUrl auto‐completeoff /el‐input
/el‐form‐item2修改页面管理服务端PageService
在更新cmsPage数据代码中添加
//更新dataUrl
one.setDataUrl(cmsPage.getDataUrl()添加后如下 文件位置xcEduService01\xc-service-manage-cms\src\main\java\com\xuecheng\manage_cms\service\PageService.java public CmsPageResult update(String id,CmsPage cmsPage){//根据id从数据库查询页面信息CmsPage one this.getById(id);if(one!null){//准备更新数据//设置要修改的数据//更新模板idone.setTemplateId(cmsPage.getTemplateId());//更新所属站点one.setSiteId(cmsPage.getSiteId());//更新页面别名one.setPageAliase(cmsPage.getPageAliase());//更新页面名称one.setPageName(cmsPage.getPageName());//更新访问路径one.setPageWebPath(cmsPage.getPageWebPath());//更新物理路径one.setPagePhysicalPath(cmsPage.getPagePhysicalPath());//更新dataUrlone.setDataUrl(cmsPage.getDataUrl());//提交修改cmsPageRepository.save(one);return new CmsPageResult(CommonCode.SUCCESS,one);}//修改失败return new CmsPageResult(CommonCode.FAIL,null);}2.静态化程序
在PageService中定义页面静态化方法如下 文件位置xcEduService01\xc-service-manage-cms\src\main\java\com\xuecheng\manage_cms\service\PageService.java //页面静态化方法/*** 静态化程序获取页面的DataUrl** 静态化程序远程请求DataUrl获取数据模型。** 静态化程序获取页面的模板信息** 执行页面静态化*/public String getPageHtml(String pageId){//获取数据模型Map model getModelByPageId(pageId);if(model null){//数据模型获取不到ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_DATAISNULL);}//获取页面的模板信息String template getTemplateByPageId(pageId);if(StringUtils.isEmpty(template)){ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_TEMPLATEISNULL);}//执行静态化String html generateHtml(template, model);return html;}//执行静态化private String generateHtml(String templateContent,Map model ){//创建配置对象Configuration configuration new Configuration(Configuration.getVersion());//创建模板加载器StringTemplateLoader stringTemplateLoader new StringTemplateLoader();stringTemplateLoader.putTemplate(template,templateContent);//向configuration配置模板加载器configuration.setTemplateLoader(stringTemplateLoader);//获取模板try {Template template configuration.getTemplate(template);//调用api进行静态化String content FreeMarkerTemplateUtils.processTemplateIntoString(template, model);return content;} catch (Exception e) {e.printStackTrace();}return null;}//获取页面的模板信息private String getTemplateByPageId(String pageId){//取出页面的信息CmsPage cmsPage this.getById(pageId);if(cmsPage null){//页面不存在ExceptionCast.cast(CmsCode.CMS_PAGE_NOTEXISTS);}//获取页面的模板idString templateId cmsPage.getTemplateId();if(StringUtils.isEmpty(templateId)){ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_TEMPLATEISNULL);}//查询模板信息OptionalCmsTemplate optional cmsTemplateRepository.findById(templateId);if(optional.isPresent()){CmsTemplate cmsTemplate optional.get();//获取模板文件idString templateFileId cmsTemplate.getTemplateFileId();//从GridFS中取模板文件内容//根据文件id查询文件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;}//获取数据模型private Map getModelByPageId(String pageId){//取出页面的信息CmsPage cmsPage this.getById(pageId);if(cmsPage null){//页面不存在ExceptionCast.cast(CmsCode.CMS_PAGE_NOTEXISTS);}//取出页面的dataUrlString dataUrl cmsPage.getDataUrl();if(StringUtils.isEmpty(dataUrl)){//页面dataUrl为空ExceptionCast.cast(CmsCode.CMS_GENERATEHTML_DATAURLISNULL);}//通过restTemplate请求dataUrl获取数据ResponseEntityMap forEntity restTemplate.getForEntity(dataUrl, Map.class);Map body forEntity.getBody();return body;}单元测试getPageHtml方法过程略。