Part1 CMS服務端開發
一.CMS需求分析
1、CMS是什麼 ?
1、CMS是什麼 ?
CMS (Content Management System)即內容管理系統,不同的項目對CMS的定位不同,比如:一個在線教育網站,有些公司認爲CMS系統是對所有的課程資源進行管理,而在早期網站剛開始盛行時很多公司的業務是網站製作,當時對CMS的定位是創建網站,即對網站的頁面、圖片等靜態資源進行管理。
2、CMS有哪些類型?
上邊也談到每個公司對每個項目的CMS定位不同,CMS基本上分爲:針對後臺數據內容的管理、針對前端頁面的
管理、針對樣式風格的管理等 。比如:一個給企業做網站的公司,其CMS系統主要是網站頁面管理及樣式風格的
管理。
3、本項目CMS的定位是什麼?
本項目作爲一個大型的在線教育平臺,對CMS系統的定位是對各各網站(子站點)頁面的管理,主要管理由於運營需要而經常變動的頁面,從而實現根據運營需要快速進行頁面開發、上線的需求。
2.靜態門戶工程搭建
門戶效果圖如下:
下載安裝Nginx 配置虛擬主機
server{
listen 80;
server_name www.xuecheng.com;
ssi on;
ssi_silent_errors on;
location / {
alias F:/teach/xcEdu/xcEduUI/xc‐ui‐pc‐static‐portal/;
index index.html;
}
}
#F:/teach/xcEdu/xcEduUI/xc‐ui‐pc‐static‐portal/ 本目錄爲門戶的主目錄
配置hosts文件 修改C:\Windows\System32\drivers\etc\hosts文件
打開瀏覽器輸入http://www.xuecheng.com 成功訪問到主頁
3.SSI服務端包含技術
本節分析首頁的管理方案。
1、頁面內容多如何管理?
將頁面拆分成一個一個的小頁面,通過cms去管理這些小頁面,當要更改部分頁面內容時只需要更改具體某個小頁
面即可。
2、頁面拆出來怎麼樣通過web服務瀏覽呢?
使用web服務(例如nginx)的SSI技術,將多個子頁面合併渲染輸出。
3、SSI是什麼?
ssi包含類似於jsp頁面中的incluce指令,ssi是在web服務端將include指定 的頁面包含在網頁中,渲染html網頁響應給客戶端 。nginx、apache等多數web容器都支持SSI指令。
ssi指令如下:
<!‐‐#include virtual="/../....html"‐‐>
將首頁拆分成
index.html:首頁主體內容
include/header.html:頭部區域
include/index_banner.html:輪播圖
include/index_category.html:左側列表導航
include/footer.html:頁尾
在nginx虛擬主機中開通SSI
ssi的配置參數如下:
ssi on: 開啓ssi支持 ssi_silent_errors on:默認爲off,設置爲on則在處理SSI文件出錯時不輸出錯誤信息 ssi_types:默認爲 ssi_types text/html,如果需要支持shtml(服務器執行腳本,類似於jsp)則需要設置爲ssi_types text/sht
PS: 通過模板靜態化的頁面,在SpringBoot內置的Tomcat中是不支持SSI的
二.CMS服務端搭建
1.導入基礎工程
工程結構
CMS及其它服務端工程基於maven進行構建,首先需要創建如下基礎工程:
parent工程:父工程,提供依賴管理。
common工程:通用工程,提供各層封裝
model工程:模型工程,提供統一的模型類管理
utils工程:工具類工程,提供本項目所使用的工具類
Api工程:接口工程,統一管理本項目的服務接口
工程結果如下:
2.MongoDB安裝並導入數據
安裝過程自行百度
CMS採用MongoDB數據庫存儲CMS頁面信息,CMS選用Mongodb的原因如下:
1、Mongodb是非關係型數據庫,存儲Json格式數據 ,數據格式靈活。
2、相比課程管理等核心數據CMS數據不重要,且沒有事務管理要求
3.頁面查詢接口定義
1 定義模型
1.1 需求分析
在梳理完用戶需求後就要去定義前後端的接口,接口定義後前端和後端就可以依據接口去開發功能了。
本次定義頁面查詢接口,本接口供前端請求查詢頁面列表,支持分頁及自定義條件查詢方式。
具體需求如下:
1、分頁查詢CmsPage 集合下的數據
2、根據站點Id、模板Id、頁面別名查詢頁面信息
3、接口基於Http Get請求,響應Json數據
1.2模型類介紹
1.MongoDB中的文檔就好比Mysql中的表: @Document是把一個java類聲明爲mongodb的文檔,可以通過collection參數指定這個類對應的文檔
2.當Java的Sping Data 框架映射Pojo爲MongoDB數據時,數據庫中會自動給你添加一個_class字段
其作用是 :來映射Pojo的,更具體的說,是爲了方便處理Pojo中存在繼承的情況,增加系統的擴展性的
@Data
@ToString
@Document(collection = "cms_page")
public class CmsPage {
/**
* 頁面名稱、別名、訪問地址、類型(靜態/動態)、頁面模版、狀態
*/
//站點ID
private String siteId;
//頁面ID
@Id
private 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;
//模版id
private String templateId;
//參數列表,暫不用
private List<CmsPageParam> pageParams;
//模版文件Id
// private String templateFileId;
//靜態文件Id
private String htmlFileId;
//數據Url
private String dataUrl;
}
屬性說明:
1、定義一個頁面需要指定頁面所屬站點
一個站點包括多個頁面,比如:學成在線的門戶站點(網站)包括了多個頁面。
2、定義一個頁面需要指定頁面使用的模板
多個頁面可以使用相同的模板,比如:商品信息模板,每個商品就是一個頁面,所有商品使用同一個商品信息模板
註解說明:
@Data、@ToString、@Document註解表示什麼意思?
@Data、@ToString:是Lombok提供的註解,下邊會介紹。
@Document:是Spring Data mongodb提供的註解,最終CMS的開發會使用Mongodb數據庫。
1.3定義請求及響應類型
1、定義請求模型QueryPageRequest,此模型作爲查詢條件類型
爲後期擴展需求,請求類型統一繼承RequestData類型。
2、響應結果類型,分頁查詢統一使用QueryResponseResult
1.4接口定義
在Api接口工程專門定義接口,在Api工程單獨定義接口的原因如下:
1、接口集中管理
2、Api工程的接口將作爲各微服務遠程調用使用。
頁面查詢接口定義如下:
2.服務端開發
1.創建CMS工程結構
創建maven工程, CMS工程的名稱爲 xc-service-manage-cms,父工程爲xc-framework-parent
<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>
<!--由於cms工程要連接mongodb所以需要在在cms服務端工程添加如下依賴:
項目使用spring data mongodb操作mongodb數據庫-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐mongodb</artifactId>
</dependency>
</dependencies>
2.CmsPageController
@RestController
@RequestMapping("/cms/page")
public class CmsPageController implements CmsPageControllerApi {
@Autowired
private CmsPageService cmsPageService;
@Override
@GetMapping("/list/{page}/{size}")
public QueryResponseResult findList(
@PathVariable("page") int page,
@PathVariable("size") int size,
QueryPageRequest queryPageResult) {
return cmsPageService.findList(page, size, queryPageResult);
}
}
3.CmsPageService
@Service
public class CmsPageService {
@Autowired
private CmsPageRepository cmsPageRepository;
public QueryResponseResult findList(int page,int size,
QueryPageRequest queryPageRequest){
if (queryPageRequest == null) {
queryPageRequest = new QueryPageRequest();
}
if (page <= 0) {
page = 1;
}
page = page ‐ 1;//爲了適應mongodb的接口將頁碼減1
if (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);
}
}
4.CmsPageRepository(Dao)
public interface CmsPageRepository extends MongoRepository<CmsPage, String> {
}
//創建Dao,繼承MongoRepository,並指定實體類型和主鍵類型。
測試類下的包路徑與main下的包路徑保持一致。
測試程序使用@SpringBootTest和@RunWith(SpringRunner.class)註解,啓動測試類會從main下找springBoot啓
動類,加載spring容器。
關於Optional:
Optional是jdk1.8引入的類型,Optional是一個容器對象,它包括了我們需要的對象,使用isPresent方法判斷所包
含對象是否爲空,isPresent方法返回false則表示Optional包含對象爲空,否則可以使用get()取出對象進行操作。
Optional的優點是:
1、提醒你非空判斷。
2、將對象非空檢測標準化。
5.接口開發規範
1.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數據。
4、響應結果統一信息爲:是否成功、操作代碼、提示信息及自定義數據。
5、響應結果統一格式爲json。
2.Api定義約束
Api定義使用SpringMVC來完成,由於此接口後期將作爲微服務遠程調用使用,在定義接口時有如下限制:
1、@PathVariable 統一指定參數名稱,如:@PathVariable(“id”)
2、@RequestParam統一指定參數名稱,如:
@RequestParam(“id”)
6.頁面查詢接口測試
1.swagger
swagger介紹
OpenAPI規範(OpenAPI Specification 簡稱OAS)是Linux基金會的一個項目,試圖通過定義一種用來描述API格
式或API定義的語言,來規範RESTful服務開發過程,目前版本是V3.0,並且已經發布並開源在github上。
(https://github.com/OAI/OpenAPI-Specification)
Swagger是全球最大的OpenAPI規範(OAS)API開發工具框架,支持從設計和文檔到測試和部署的整個API生命周
期的開發。 (https://swagger.io/)
Spring Boot 可以集成Swagger,生成Swagger接口,Spring Boot是Java領域的神器,它是Spring項目下快速構建
項目的框架。
Swagger常用註解
在Java類中添加Swagger的註解即可生成Swagger接口,常用Swagger註解如下:
@Api:修飾整個類,描述Controller的作用
@ApiOperation:描述一個類的一個方法,或者說一個接口
@ApiParam:單個參數描述 @ApiModel:用對象來接收參數
@ApiModelProperty:用對象接收參數時,描述對象的一個字段
@ApiResponse:HTTP響應其中1個描述
@ApiResponses:HTTP響應整體描述
@ApiIgnore:使用該註解忽略這個API
@ApiError :發生錯誤返回的信息
@ApiImplicitParam:一個請求參數
@ApiImplicitParams:多個請求參數
@ApiImplicitParam屬性:
Swagger2Configuration配置類
@Configuration
@EnableSwagger2
public class Swagger2Configuration {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.xuecheng"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("學成網api文檔")
.description("學成網api文檔")
// .termsOfServiceUrl("/")
.version("1.0")
.build();
}
}
Swagger接口定義
@Api(value = "Cms頁面管理接口", description = "Cms頁面管理接口,提供頁面的CRUD")
public interface CmsPageControllerApi {
//頁面查詢
@ApiOperation("分頁查詢頁面列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "page", value = "頁碼", required = true, paramType = "int"),
@ApiImplicitParam(name = "size", value = "每頁記錄數", required = true, paramType = "int")
})
QueryResponseResult findList(int page, int size, QueryPageRequest QueryPageRequest);
}
在QueryPageRequest類中使用註解 ApiModelProperty 對屬性註釋:
@Data
public class QueryPageRequest extends RequestData {
//站點id
@ApiModelProperty("站點ID")
private String siteId;
//頁面ID
@ApiModelProperty("頁面ID")
private String pageId;
//頁面名稱
@ApiModelProperty("頁面名稱")
private String pageName;
//別名
@ApiModelProperty("別名")
private String pageAliase;
//模版id
@ApiModelProperty("模版id")
private String templateId;
//頁面類型
@ApiModelProperty("頁面類型")
private String pageType;
}
Swagger接口測試
Swagger接口生成工作原理:
1、系統啓動,掃描到api工程中的Swagger2Configuration類
2、在此類中指定了包路徑com.xuecheng,找到在此包下及子包下標記有@RestController註解的controller類
3、根據controller類中的Swagger註解生成接口文檔。
2.Postman
1) get請求參數設置
2)post請求參數設置
form-data:將表單的數據轉爲鍵值對,並且可以包括文件
x-www-form-urlencoded: content-type爲application/x-www-from-urlencoded,將表單的數據轉爲鍵值對
raw:請求text、json、xml、html,比如如果請求json數據則使用此格式
binary:content-type爲application/octet-stream,可用於上傳文件。