CMS内容管理系统之文章信息模块的实现
一、显示文章列表
- 对文章列表进行展示的时候可以使用GridManager表格插件,能够更加方便的展示列表数据,不需要像传统的方式进行拼接或使用jstl+el表达式进行拿值,而且传统的方式太麻烦,也很容易拼接错误。
- columnData里面的key值就是文章信息实体类中对应的字段,text为每列数据对应的标题名。通过ajax向后台发送获取所有的文章信息的请求,前台拿到文章的所有信息就可以让数据在列表中展示出来。
注意:GridManager表格插件接收后台返回的数据格式必须是data和totals的格式,这个时候后台可以返回一个Map<String,Object>格式或者是将data和totals单独封装成一个类然后后台直接返回一个实体类对象。
前台页面列表展示:
<!-- 存放table列表 -->
<table id='table-demo-ajaxPageCode'></table>
document.querySelector('#table-demo-ajaxPageCode').GM({
gridManagerName: 'demo-ajaxPageCode',
ajaxData: '/system/article/findAll',
ajaxType: 'POST',
supportAjaxPage: true,//是否支持分页
sizeData:[5,10,15,20],//每页显示条数的下拉框
pageSize:5,//初始时每页显示的条数
currentPageKey:'currentPage',//当前页的键值
pageSizeKey:'pageCount',//每页条数的键值
height:"100%",//表格显示的高度为百分百
columnData: [
{
key: 'title',
text: '标题',
align: 'center'//文字居中显示
},{
key: 'url',
text: '地址'
},{
key: 'type',
text: '分类',
template: function(cell, row, index, key){
return cell.name;
},
align: 'center'
},{
key: 'clickCount',
text: '点击量',
align: 'center'
},{
key:'enable',
text:'状态',
template: function(cell, row, index, key){
return cell?"<font color='blue'>启用</font>":"<font color='red'>禁用</font>";
},
align: 'center'
},{
key: 'createDate',
text: '创建时间',
align: 'center'
},{
key: 'id',
text: '操作 <a href="javascript:;" id="add">添加 </a>',
width: '100px',
fixed: 'right',
align: 'center',
template: function(cell, row, index, key){
//row能够获取每行对象的所有信息
var data=JSON.stringify(row);
return "<a href='javascript:;' data-id='"+cell+"' class='del'>删除 </a> "+"<a href='javascript:;' id='edit' data-row='"+data+"' class='edit'>修改</a>";
}
}
],
});
二、文章信息列表分页的实现
- 使用GridManager自带的分页功能,为了实现分页效果,我们只需要配置分页相关的属性。
a. supportAjaxPage: true,//显示分页条
b. sizeData:[5,10,15,20],//每页显示条数的下拉框
c. pageSize:5,//初始时每页显示的条数
d. currentPageKey:‘currentPage’,//当前页的key键值
e. pageSizeKey:‘pageCount’,//每页条数的key键值 - 后台可以将分页的属性currentPage和pageCount单独封装成一个类,然后后台通过对象接收分页的信息。后台对查询的所有的数据进行分页查询就可以实现分页功能。
分页实体类:
public class BaseQuery {
//当前页码
private Integer currentPage;
//每页显示条数
private Integer pageCount;
//每页的起始索引
public Integer getBegin(){
return (currentPage-1)*pageCount;
}
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageCount() {
return pageCount;
}
public void setPageCount(Integer pageCount) {
this.pageCount = pageCount;
}
@Override
public String toString() {
return "BaseQuery [currentPage=" + currentPage + ", pageCount=" + pageCount + "]";
}
}
分页的实现:(begin属性的值是直接从封装的分页实体类里面的getBegin方法获取的该属性的值)
<select id="findAll" resultType="Article" parameterType="ArticleQuery">
select * from t_article limit #{begin},#{pageCount}
</select>
三、页面静态化的实现
- 页面静态化的目的:之所以要实现页面的静态化,是因为静态页面的加载速度比动态页面的加载速度快,动态页面会进行数据库的操作需要获取连接,需要编译,花费的时间较长。
- 实现的方法:使用freemarker技术生成对应的静态页面。
- 页面静态化技术编程步骤:
a. 导入相关的freemarker的jar包。
b. 获取模板对象。
c. 准备数据。(只能是map或实体类对象)
d. 生成静态资源(template.process())
e. 创建以ftl结尾的模板。 - 静态化页面需要相关的开关,所以我们可以在添加和修改文章信息的信息就生成相应的静态页面。
- 静态页面的生成会在很多地方被重复使用,可以将其封装成工具类,不仅提高代码的重用性,同时还能够提高开发效率。
FreeMarkUtil 工具类:
public class FreeMarkUtil {
public static String createTemplate(String loadPath,String templateName,Object data,String suffix){
FileWriter out = null;
try {
//获取Configuration对象 -- 为了获取模板对象
Configuration config = new Configuration(Configuration.VERSION_2_3_28);
//设置默认加载路径
File file = new File(loadPath);
config.setDirectoryForTemplateLoading(file);
//设置默认编码格式
config.setDefaultEncoding("utf-8");
//获取模板
Template template = config.getTemplate(templateName);
//时间戳
long time = System.currentTimeMillis();
//拼接生成新的图片名称
String url=time+suffix;
out = new FileWriter(new File(file,url));
//生成静态资源
template.process(data, out);
//返回地址
return url;
} catch (Exception e) {
e.printStackTrace();
}finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
添加和修改文章信息的时候生成静态页面:
@Override
public void saveArticle(Article article,HttpServletRequest req) {
//获取模板所在的路径
String realPath = req.getServletContext().getRealPath("/static/template");
//模板生成相应的静态页面后能够得到对应的文章地址
String url = FreeMarkUtil.createTemplate(realPath, "article.ftl", article, ".html");
//设置文章详细信息的访问地址
article.setUrl(url);
if(article.getId()==null){
//插入操作
articleMapper.insertArticle(article);
}else{
//获取更新之前静态页面的地址
Article oneArticle = articleMapper.getOneArticle(article.getId());
String beforeUrl = oneArticle.getUrl();
//更新数据
articleMapper.updateArticle(article);
//更新后删除原来的静态资源
File file = new File(realPath,beforeUrl);
if(file.exists()){
file.delete();
}
}
}
模板内容的显示方式:(将里面的内容替换成动态获取:${需要显示的属性})
<div class="wrapper majority article" id="article">
<div class="info">
<span><span b>发表时间: </span>${createDate?datetime}</span><span><span b>浏览: </span ><span id="clickCount">${clickCount} </span></span>
</div>
<div class="title">${title}</div>
<div class="content">
<div>${content}</div>
</div>
</div>