文章目录

  • 0.定义CMS
  • 1.CMS页面管理
  • 2.需求分析
  • 3.模型类介绍
  • 4.定义请求及响应类型
  • 5.定义接口
  • 6.创建CMS工程结构
  • 7.Dao
    • 1)创建Dao,继承MongoRepository
    • 2)编写测试类
      • 分页查询测试
      • 添加
      • 删除
      • 修改
  • 8.Service
  • 9.Controller
  • 10.接口开发规范

0.定义CMS

1)CMS是什么 ?
CMS (Content Management System)即内容管理系统,不同的项目对CMS的定位不同,比如:一个在线教育网站,有些公司认为CMS系统是对所有的课程资源进行管理,而在早期网站刚开始盛行时很多公司的业务是网站制作,当时对CMS的定位是创建网站,即对网站的页面、图片等静态资源进行管理。
2)CMS有哪些类型?
上边也谈到每个公司对每个项目的CMS定位不同,CMS基本上分为:针对后台数据内容的管理、针对前端页面的管理、针对样式风格的管理等 。比如:一个给企业做网站的公司,其CMS系统主要是网站页面管理及样式风格的管理。
3)本项目CMS的定位是什么?
本项目作为一个大型的在线教育平台,对CMS系统的定位是对各各网站(子站点)页面的管理,主要管理由于运营需要而经常变动的页面,从而实现根据运营需要快速进行页面开发、上线的需求。

1.CMS页面管理

本项目要实现什么样的功能?
1)页面管理
管理员在后台添加、修改、删除页面信息。
2)页面预览
管理员通过页面预览功能预览页面发布后的效果。
3)页面发布
管理员通过页面发布功能将页面发布到远程门户服务器。页面发布成功,用户即可在浏览器浏览到最新发布的页面,整个页面添加、发布的过程由于软件自动执行,无需人工登录服务器操作。
这些页面的管理流程是什么?
1)创建站点:
一个网站有很多子站点,比如:学成在线有主门户、学习中心、问答系统等子站点。具体的哪个页面是归属于具体的站点,所以要管理页面,先要管理页面所属的站点。
2)创建模板:
页面如何创建呢?比如电商网站的商品详情页面,每个页面的内容布局、板式是相同的,不同的只是内容,这个页面的布局、板式就是页面模板,模板+数据就组成一个完整的页面,最终要创建一个页面文件需要先定义此页面的模板,最终拿到页面的数据再结合模板就拼装成一个完整的页面。
3)创建页面:
创建页面是指填写页面的基本信息,如:页面的名称、页面的url地址等。
4)页面预览:
页面预览是页面发布前的一项工作,页面预览使用静态化技术根据页面模板和数据生成页面内容,并通过浏览器预览页面。页面发布前进行页面预览的目是为了保证页面发布后的正确性。
5)页面发布:
使用计算机技术将页面发送到页面所在站点的服务器,页面发布成功就可以通过浏览器来访问了。

2.需求分析

在梳理完用户需求后就要去定义前后端的接口,接口定义后前端和后端就可以依据接口去开发功能。

具体需求如下:
1、分页查询CmsPage 集合下的数据
2、根据站点Id、模板Id、页面别名查询页面信息
3、接口基于Http Get请求,响应Json数据

本次定义页面查询接口,本接口供前端请求查询页面列表,支持分页及自定义条件查询方式。

3.模型类介绍

接口的定义离不开数据模型,根据前边对需求的分析,整个页面管理模块的数据模型如下:
CmsSite:站点模型
CmsTemplate:页面模板
CmsPage:页面信息

其中页面信息CmsPage如下:

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;//页面ID@Idprivate 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 List<CmsPageParam> pageParams;//模版文件Id
//    private String templateFileId;//静态文件Idprivate String htmlFileId;//数据Urlprivate String dataUrl;
}

属性说明:
1、定义一个页面需要指定页面所属站点
一个站点包括多个页面,比如:学成在线的门户站点(网站)包括了多个页面。
2、定义一个页面需要指定页面使用的模板
多个页面可以使用相同的模板,比如:商品信息模板,每个商品就是一个页面,所有商品使用同一个商品信息模板

注解说明:
@Data、@ToString:是Lombok提供的注解。
@Document:是Spring Data mongodb提供的注解,最终CMS的开发会使用Mongodb数据库。

4.定义请求及响应类型

定义请求模型QueryPageRequest,此模型作为查询条件类型

package com.xuecheng.framework.domain.cms.request;import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
public class QueryPageRequest {//接收页面查询的查询条件//站点id//站点id@ApiModelProperty("站点id")private String siteId;//页面IDprivate String pageId;//页面名称private String pageName;//别名private String pageAliase;//模版idprivate String templateId;//....
}

响应结果类型,分页查询统一使用QueryResponseResult

package com.xuecheng.framework.model.response;import lombok.Data;
import lombok.ToString;@Data
@ToString
public class QueryResponseResult extends ResponseResult {QueryResult queryResult;public QueryResponseResult(ResultCode resultCode,QueryResult queryResult){super(resultCode);this.queryResult = queryResult;}}

5.定义接口

在Api接口工程专门定义接口,在Api工程单独定义接口的原因如下:
1、接口集中管理
2、Api工程的接口将作为各微服务远程调用使用。

页面查询接口定义如下:

public interface CmsPageControllerApi {public QueryResponseResult findList(int page, int size, QueryPageRequest queryPageRequest) ;
}

此接口编写后会在CMS服务工程编写Controller类实现此接口。

6.创建CMS工程结构

1)创建maven工程, CMS工程的名称为 xc-service-manage-cms,父工程为xc-framework-parent。
pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>xc-framework-parent</artifactId><groupId>com.xuecheng</groupId><version>1.0-SNAPSHOT</version><relativePath>../xc-framework-parent/pom.xml</relativePath></parent><modelVersion>4.0.0</modelVersion><artifactId>xc-service-manage-cms</artifactId><dependencies><dependency><groupId>com.xuecheng</groupId><artifactId>xc-service-api</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.xuecheng</groupId><artifactId>xc-framework-model</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.xuecheng</groupId><artifactId>xc-framework-utils</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.xuecheng</groupId><artifactId>xc-framework-common</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies></project>

由于cms工程要连接mongodb,使用spring data mongodb操作mongodb数据库,所以需要在在cms服务端工程添加依赖spring-boot-starter-data-mongodb。

2)创建基本的包结构:
com.xuecheng.manage_cms.config:配置类目录,数据库配置、MQ配置等
com.xuecheng.manage_cms.dao:dao接口目录
com.xuecheng.manage_cms.service:service类目录
com.xuecheng.manage_cms.web.controller:controller类目录

3)配置文件
在classpath下配置application.yml

server:port: 31001
spring:application:name: xc-service-manage-cmsdata:mongodb:uri:  mongodb://root:123@localhost:27017database: xc_cms

logback-spring.xml:

<?xml version="1.0" encoding="UTF-8"?><configuration><!--定义日志文件的存储地址,使用绝对路径--><property name="LOG_HOME" value="d:/logs"/><!-- Console 输出设置 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern><charset>utf8</charset></encoder></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><fileNamePattern>${LOG_HOME}/xc.%d{yyyy-MM-dd}.log</fileNamePattern></rollingPolicy><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 异步输出 --><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --><discardingThreshold>0</discardingThreshold><!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --><queueSize>512</queueSize><!-- 添加附加的appender,最多只能添加一个 --><appender-ref ref="FILE"/></appender><logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false"><appender-ref ref="CONSOLE"/></logger><logger name="org.springframework.boot" level="DEBUG"/><root level="info"><!--<appender-ref ref="ASYNC"/>--><appender-ref ref="FILE"/><appender-ref ref="CONSOLE"/></root>
</configuration>

4)SpringBoot 启动类
Spring Boot应用需要创建一个应用启动类,启动过程中会扫描Bean并注入spring 容器
注意:此类创建在本工程com.xuecheng.manage_cms包下

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.ComponentScan;@SpringBootApplication
@EntityScan("com.xuecheng.framework.domain.cms")//扫描实体类
@ComponentScan(basePackages={"com.xuecheng.api"})//扫描接口
@ComponentScan(basePackages={"com.xuecheng.manage_cms"})//扫描本项目下的所有类
public class ManageCmsApplication {public static void main(String[] args) {SpringApplication.run(ManageCmsApplication.class,args);}
}

7.Dao

1)创建Dao,继承MongoRepository

本项目使用Spring Data Mongodb完成Mongodb数据库的查询,Spring Data Mongodb提供一套快捷操作mongodb的方法。
创建Dao,继承MongoRepository,并指定实体类型和主键类型。

package com.xuecheng.manage_cms.dao;import com.xuecheng.framework.domain.cms.CmsPage;
import org.springframework.data.mongodb.repository.MongoRepository;public interface CmsPageRepository extends MongoRepository<CmsPage,String> {//根据页面名称查询CmsPage findByPageName(String pageName);
}

其中继承的接口MongoRepository有以下方法:

2)编写测试类


test下的包路径与main下的包路径保持一致。
测试程序使用@SpringBootTest和@RunWith(SpringRunner.class)注解,启动测试类会从main下找springBoot启
动类,加载spring容器。
测试代码如下:

package com.xuecheng.manage_cms;
import com.xuecheng.framework.domain.cms.CmsPage;
import com.xuecheng.manage_cms.dao.CmsPageRepository;
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.data.domain.*;
import org.springframework.test.context.junit4.SpringRunner;@SpringBootTest
@RunWith(SpringRunner.class)
public class CmsPageRepositoryTest {@Autowired
CmsPageRepository cmsPageRepository;}

分页查询测试

//分页测试
@Test
public void testFindPage() {int page = 0;//从0开始
int size = 10;//每页记录数
Pageable pageable = PageRequest.of(page,size);
Page<CmsPage> all = cmsPageRepository.findAll(pageable);
System.out.println(all);
}

添加

//添加
@Test
public void testInsert(){//定义实体类
CmsPage cmsPage = new CmsPage();
cmsPage.setSiteId("s01");
cmsPage.setTemplateId("t01");
cmsPage.setPageName("测试页面");
cmsPage.setPageCreateTime(new Date());
List<CmsPageParam> cmsPageParams = new ArrayList<>();
CmsPageParam cmsPageParam = new CmsPageParam();
cmsPageParam.setPageParamName("param1");
cmsPageParam.setPageParamValue("value1");
cmsPageParams.add(cmsPageParam);
cmsPage.setPageParams(cmsPageParams);
cmsPageRepository.save(cmsPage);
System.out.println(cmsPage);
}

删除

//删除
@Test
public void testDelete() {cmsPageRepository.deleteById("5b17a2c511fe5e0c409e5eb3");
}

修改

/
/修改
@Test
public void testUpdate() {Optional<CmsPage> optional = cmsPageRepository.findOne("5b17a34211fe5e2ee8c116c9");
if(optional.isPresent()){CmsPage cmsPage = optional.get();
cmsPage.setPageName("测试页面01");
cmsPageRepository.save(cmsPage);
}
}

关于Optional:
Optional是jdk1.8引入的类型,Optional是一个容器对象,它包括了我们需要的对象,使用isPresent方法判断所包
含对象是否为空,isPresent方法返回false则表示Optional包含对象为空,否则可以使用get()取出对象进行操作。
Optional的优点是:
1、提醒你非空判断。
2、将对象非空检测标准化。

3)自定义Dao方法
同Spring Data JPA一样Spring Data mongodb也提供自定义方法的规则,如下:
按照findByXXX,findByXXXAndYYY、countByXXXAndYYY等规则定义方法,实现查询操作。

public interface CmsPageRepository extends MongoRepository<CmsPage,String> {//根据页面名称查询
CmsPage findByPageName(String pageName);
//根据页面名称和类型查询
CmsPage findByPageNameAndPageType(String pageName,String pageType);
//根据站点和页面类型查询记录数
int countBySiteIdAndPageType(String siteId,String pageType);
//根据站点和页面类型分页查询
Page<CmsPage> findBySiteIdAndPageType(String siteId,String pageType, Pageable pageable);
}

8.Service

定义页面查询方法,根据条件查询暂时不实现:

package com.xuecheng.manage_cms.service;
import com.xuecheng.framework.domain.cms.CmsPage;
import com.xuecheng.framework.domain.cms.request.QueryPageRequest;
import com.xuecheng.framework.model.response.CommonCode;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.framework.model.response.QueryResult;
import com.xuecheng.manage_cms.dao.CmsPageRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
@Service
public class PageService {@Autowired
CmsPageRepository cmsPageRepository;
/**
* 页面列表分页查询
* @param page 当前页码
* @param size 页面显示个数
* @param queryPageRequest 查询条件
* @return 页面列表
*/
public QueryResponseResult findList(int page,int size,QueryPageRequest queryPageRequest){if (queryPageRequest == null) {queryPageRequest = new QueryPageRequest();} if (page <= 0) {page = 1;} page = page ‐ 1;//为了适应mongodb的接口将页码减1if (size <= 0) {size = 20;} //分页对象Pageable pageable = new PageRequest(page, size);//分页查询Page<CmsPage> all = cmsPageRepository.findAll(pageable);QueryResult<CmsPage> cmsPageQueryResult = new QueryResult<CmsPage>();cmsPageQueryResult.setList(all.getContent());cmsPageQueryResult.setTotal(all.getTotalElements());//返回结果return new QueryResponseResult(CommonCode.SUCCESS,cmsPageQueryResult);}
}

9.Controller

使用springMVC完成接口实现开发。

package com.xuecheng.manage_cms.web.controller;
import com.xuecheng.api.cms.CmsPageControllerApi;
import com.xuecheng.framework.domain.cms.request.QueryPageRequest;
import com.xuecheng.framework.model.response.QueryResponseResult;
import com.xuecheng.manage_cms.service.PageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CmsPageController implements CmsPageControllerApi {@Autowired
PageService pageService;
@Override
@GetMapping("/list/{page}/{size}")
public QueryResponseResult findList(@PathVariable("page") int page, @PathVariable("size")
int size, QueryPageRequest queryPageRequest) {return pageService.findList(page,size,queryPageRequest);
}
}

使用浏览器测试
输入:http://localhost:31001/cms/page/list/1/10 查询第1页,每页显示10条记录。

10.接口开发规范

Api请求及响应规范
为了严格按照接口进行开发,提高效率,对请求及响应格式进行规范化。
1)get 请求时,采用key/value格式请求,SpringMVC可采用基本类型的变量接收,也可以采用对象接收。
2)Post请求时,可以提交form表单数据(application/x-www-form-urlencoded)和Json数据(ContentType=application/json),文件等多部件类型(multipart/form-data)三种数据格式,SpringMVC接收Json数据
使用@RequestBody注解解析请求的json数据。
3)响应结果统一信息为:是否成功、操作代码、提示信息及自定义数据。
4)响应结果统一格式为json。

Api定义约束
Api定义使用SpringMVC来完成,由于此接口后期将作为微服务远程调用使用,在定义接口时有如下限制:
1)@PathVariable 统一指定参数名称,如:@PathVariable(“id”)
2)@RequestParam统一指定参数名称,如:@RequestParam(“id”)

学成在线--1.CMS接口开发相关推荐

  1. 学成在线--2.CMS前端页面查询开发

    文章目录 0.思路总结 1.创建CMS模块的目录架构 2.创建页面并配置路由 1)在page目录新建page_list.vue,扩展名为.vue. 2)在cms的router下配置路由. 3)在bas ...

  2. 学成在线--7.CMS页面管理开发(异常处理)

    文章目录 1.异常处理的问题分析 2.异常处理流程 3.可预知异常处理 1.自定义异常类 2.异常抛出类 3.异常捕获类 4.异常处理测试 1)定义错误代码 2)异常处理测试 4.不可预知异常处理 1 ...

  3. 学成在线--6.CMS页面管理开发(删除页面)

    文章目录 0.删除用户逻辑 1.删除页面接口定义 2.后端开发--Dao 3.后端开发--Service 4.后端开发--controller 5.前端开发--page_list.vue添加删除按钮 ...

  4. 学成在线--5.CMS页面管理开发(修改页面)

    文章目录 1.修改页面流程 1)前端逻辑 2)后端逻辑 2.修改页面接口定义 3.后端开发--Dao 4.后端开发--Service 5.后端开发--Controller 1)根据id查询页面 2)保 ...

  5. 学成在线--4.CMS页面管理开发(新增页面)

    文章目录 1.定义新增页面接口 1)在model工程中定义响应模型 2)在api工程中添加接口 2.新增页面服务端开发 1)Dao 2)Service 3)Controller 3.新增页面前端开发 ...

  6. 学成在线--3.CMS页面管理开发(自定义条件查询)

    文章目录 0.需求分析 1.服务端--Dao 2.服务端--Service 3.服务端--Controller 4.前端 1)page_list.vue中增加查询表单 2)page_list.vue中 ...

  7. 【HTML CSS】笔记4日 [ 学成在线素材 ]

    准备素材和工具 学成在线PSD源文件. 开发工具:PS(切图)/cutterman插件 + VScode(代码)+ Chrome(调试). 创建study目录文件夹(用于存放我们这个页面的相关内容), ...

  8. Day07——PS相关操作、学成在线案例

    文章目录 一.PS 操作 1.1 基本操作 1.2 常见的图片格式 1.3 PS切图 1.3.1 图层切图 1.3.2 切片切图 1.3.3 PS 插件切图 二.学成在线案例 2.1 准备素材和工具 ...

  9. Java开发实战项目分享之学成在线v1.0项目总结

    前言: 学成在线项目是传智燕青老师研发的JavaEE分布式微服务架构项目,采用SpringCloud框架研发,课程共20天,应广大学员的建议现将整个项目的技术点以问题的形式进行总结,方便大家学习总结. ...

最新文章

  1. Java 树形结构数据生成--不需要顶级节点
  2. 企业级LNMP架构搭建实例(基于Centos6.x)
  3. vue中过渡动画(类名实现方式)
  4. 【学习笔记】含委托加工(转包)的标准成本估算
  5. 10以内数的组成分解图_学前儿童如何学习20以内的加减法,收藏了
  6. linux下使用John检测用户是否存在弱口令
  7. freemarker【FTL】常见语法大全
  8. leetcode第12题Python版整数转罗马字符串
  9. 计算机诞生了自主意识,计算机会有意识吗?整合信息或非人类独有
  10. MD5值的简介和查看
  11. Excel表格导入CAD后,表格内数字后的小数点怎么消除呢?
  12. 游戏实战篇|原神人物模型下载教程,并在Unity中给模型 添加动画【伯嫖最新原神所有人物模型】文末送书
  13. C++调用ffmpeg批量合并bilibili缓存视频
  14. vite+ts+vue3 知识点(定义全局函数和变量)
  15. 两化融合的定义和两化融合如何认定
  16. 问题: return unicode(text, encoding, errors=errors) UnicodeDecodeError: ‘utf-8‘ codec can‘t decode
  17. python谷歌浏览器驱动安装失败_Selenium自动化库在安装谷歌浏览器Chrome及其驱动chromedriver的安装问题...
  18. echarts 环状饼图 显示lebel
  19. 倍频程频谱_倍频程科学编程语言速成课程
  20. 360开源mysql_奇虎360开源基于Kubernetes管理平台 Wayne

热门文章

  1. 基于HubServing的PaddleOCR部署
  2. 销售员所做的一切工作最终目的就是为了成交
  3. HEVC/H265 HM10.0 分析(一)NALread.cpp
  4. DCT(离散余弦变换(DiscreteCosineTransform))
  5. centos-install-kong-cassandra
  6. 【Cef编译】 CefSharp编译失败,检测到“RuntimeLibrary”的不匹配项: 值“MT_StaticRelease”不匹配值“MD_DynamicRelease”...
  7. ABP开发框架前后端开发系列---(9)ABP框架的权限控制管理
  8. thymeleaf 使用javascript定义数组报错
  9. Web项目替换jar包中的文件的方法
  10. 博客园“图灵杯”第3届博问大赛比赛结果