😎 知识点概览

为了方便后续回顾该项目时能够清晰的知道本章节讲了哪些内容,并且能够从该章节的笔记中得到一些帮助,所以在完成本章节的学习后在此对本章节所涉及到的知识点进行总结概述。

本章节为【学成在线】项目的 day01 的内容

  • 搭建门户页面
  • 搭建服务端基础工程
  • 页面查询服务的构建
  • 使用MangoDB 进行 CRUD 操作
  • Swagger 的基本使用
  • Postman 的基本使用

一、项目架构

1. 业务架构

2. 技术架构

二、CMS 门户工程搭建

1. 安装 WebStorm

参考 WebStorm安装手册.md 安装WebStorm,导入 资料\门户\xc-ui-pc-static-portal.rar 压缩包下的内容。

2. Nginx虚拟主机

在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/ 本目录即为门户的主目录,自行修改为自己的路径

三、CMS 服务端工程搭建

1. 基础工程搭建

创建一个项目文件夹 xcEduService01导入 资料\基础工程\基础工程.zip 中的基础工程,并依次将所有基础工程添加至pom项目中

2. 导入MongoDB数据

搭建好mongodb数据库后,导入 资料\mongodb\xc_cms 内的json数据

3. 定义接口

定义请求以及相应类型

domain.cms.request 下创建 QueryPageRequest 并继承 RequestData

package com.xuecheng.framework.domain.cms.request;

import com.xuecheng.framework.model.request.RequestData;
import lombok.Data;

@Data
public class QueryPageRequest extends RequestData {
    //站点id
    private String siteId;
    //页面id
    private String pageId;
    //页面名称
    private String pageName;
    //别名
    private String pageAliase;
    //模板id
    private String templateId;
}

定义响应接口

com.xuecheng.api.cms 下定义 CmsPageControllerApi 查询列表的响应格式统一为 QueryResponseResult

package com.xuecheng.api.cms;

import com.xuecheng.framework.domain.cms.request.QueryPageRequest;
import com.xuecheng.framework.model.response.QueryResponseResult;

/**
 * 分页查询接口
 */
public interface CmsPageControllerApi {
    public QueryResponseResult findList(int page, int size, QueryPageRequest queryPageRequest);
}

四、页面查询服务开发

1. 创建CMS服务工程

导入 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>

创建一个 xc-service-manage-cms 的maven工程,依赖父工程 xc-framework-parent

创建在 com.xuecheng.manage_cms 包并在包下创建config、dao、service、controller 等包,目录结构如下

创建入口文件 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.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);
    }
}

resources 下创建 application.yml

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

resources 下导入日志文件,直接复制 资料\CMS配置文件 下的 logback-spring.xml

2. 定义dao

在dao下定义一个接口 CmsPageRepository 继承 MongoRepository

MongoRepository<CmsPage,String> 中的 CmsPage 对应我们mongodb中集合的实体类

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> {

}

3. 单元测试

查询测试

定义CmsPageRepository 的测试类 CmsPageRepositoryTest

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@SpringBootTest
@RunWith(SpringRunner.class)
public class CmsPageRepositoryTest {
    @Autowired
    CmsPageRepository cmsPageRepository;

    @Test
    public void testFindAll(){
        List<CmsPage> all = cmsPageRepository.findAll();
        System.out.println(all);
    }

    //分页查询
    @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);
}

删除

//删除
@Test
public void testDelete(){
    cmsPageRepository.deleteById("5e705470cc53e4266c135ee7");
    System.out.println("删除成功!");
}

修改

//修改
@Test
public void testUpdate(){
    Optional<CmsPage> optional = cmsPageRepository.findById("5e705470cc53e4266c135ee7");
    if(optional.isPresent()){  //判断是否为空,jdk1.8新特性optional
        CmsPage cmsPage = optional.get();
        cmsPage.setPageName("测试页面02");
        CmsPage save = cmsPageRepository.save(cmsPage);
        System.out.println("修改成功 " + save);
    }
}

4.配置 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;

    /**
     * 分页查询
     * @return
     */
    public QueryResponseResult findList(int page,int size,QueryPageRequest queryPageRequest) {
        //过滤条件
        if(page <= 0){
            page = 1;
        }
        if(size <= 0){
            size = 10;
        }

        //创建分页查询参数
        PageRequest pageable = PageRequest.of(page, size);
        //分页查询数据
        Page<CmsPage> all = cmsPageRepository.findAll(pageable);
        //整理查询到的数据
        QueryResult queryResult = new QueryResult();
        queryResult.setList(all.getContent());
        queryResult.setTotal(all.getTotalElements());

        //返回结果
        return new QueryResponseResult(CommonCode.SUCCESS,queryResult);
    }
}

5. 配置 Controller

package com.xuecheng.manage_cms.web.controller;

import com.xuecheng.api.cms.CmsPageControllerApi;
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.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;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/cms/page")
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);
    }
}

6.接口开发规范

Api请求及响应规范

为了严格按照接口进行开发,提高效率,对请求及响应格式进行规范化。

  • get 请求时,采用key/value格式请求,SpringMVC可采用基本类型的变量接收,也可以采用对象接收。
  • Post 请求时,可以提交form表单数据(application/x-www-form-urlencoded)和 Json 数据(Content-Type=application/json),文件等多部件类型(multipart/form-data)三种数据格式,SpringMVC接收Json数据使用@RequestBody注解解析请求的json数据。
  • 响应结果统一信息为:是否成功、操作代码、提示信息及自定义数据。
  • 响应结果统一格式为 json

Api定义约束

Api 定义使用SpringMVC来完成,由于此接口后期将作为微服务远程调用使用,在定义接口时有如下限制:

  • @PathVariable 统一指定参数名称,如:@PathVariable("id")
  • @RequestParam 统一指定参数名称,如:@RequestParam("id")

五、Swagger 生成接口文档

1. 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项目下快速构建项目的框架。

2. 开启 Swagger

package com.xuecheng.api.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

//
@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 后,它会自动扫描 com.xuecheng 包下所有标记了 @RestController 这个注解的类,根据这个类的方法来生成接口文档。

运行项目,访问 http://localhost:31001/swagger-ui.html 就可以看到我们刚才定义的这个 controller

image-20200317171117409.png

3. Swagger常用注解

在Java类中添加Swagger的注解即可生成Swagger接口,常用Swagger注解如下:

  • @Api:修饰整个类,描述Controller的作用 @ApiOperation:描述一个类的一个方法,或者说一个接口
  • @ApiParam:单个参数描述 @ApiModel:用对象来接收参数 @ApiModelProperty:用对象接收参数时,描述对象的一个字段
  • @ApiResponse:HTTP响应其中1个描述 @ApiResponses:HTTP响应整体描述
  • @ApiIgnore:使用该注解忽略这个API @ApiError :发生错误返回的信息
  • @ApiImplicitParam:一个请求参数
  • @ApiImplicitParams:多个请求参数
  • @ApiImplicitParam属性:
属性 取值 作用
paramType 查询参数类型
path 以地址的形式提交数据
query 直接跟参数完成自动映射赋值
body 以流的形式提交 仅支持POST
header 参数在request headers 里边提交
form 以form表单的形式提交 仅支持POST
dataType 参数的数据类型 只作为标志说明,并没有实际验证
Long
String
name 接收参数名
value 接收参数的意义描述
required 参数是否必填
true 必填
false 非必填
defaultValue 默认值

4. Swagger接口定义

使用 swagger 的常用注解来描述接口信息

/**
 * 分页查询接口
 */
@Api(value="cms页面管理接口",description = "cms页面管理接口,提供页面的增、删、改、查")
public interface CmsPageControllerApi {
    @ApiOperation("分页查询页面列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name="page",value = "页码",required=true,paramType="path",dataType="int"),
        @ApiImplicitParam(name="size",value = "每页记录数",required=true,paramType="path",dataType="int")
    })
    public QueryResponseResult findList(int page, int size, QueryPageRequest queryPageRequest);

}

在QueryPageRequest类中使用注解 ApiModelProperty 对属性注释

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;
}

重启项目,访问 http://localhost:31001/swagger-ui.html ,可以看到我们添加的描述信息

五、Postman 基本使用

Postman 是一款功能强大的http接口测试工具,使用 postman 可以完成 http 各种请求的功能测试。

官方地址:https://www.getpostman.com/


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

学成在线day02:CMS前端开发 Previous
MongoDB入门 Next