后端开发通用

1、前后端开发

项目基于前后端分离的架构进行开发,前后端分离架构总体上包括前端和服务端,通常是多人协作开发

  • 对于后端java工程师

把精力放在设计模式,spring+springmvc,linux,mysql事务隔离与锁机制,mongodb,http/tcp,多线程,分布式架构,弹性计算架构,微服务架构,java性能优化,以及相关的项目管理等等。

  • 对于前端工程师

把精力放在html5,css3,vuejs,webpack,nodejs,Google V8引擎,javascript多线程,模块化,面向切面编程,设计模式,浏览器兼容性,性能优化等等。

  • 前后端分离开发流程
    后端开发通用_第1张图片
  • 前后端开发流程
1,需求分析
2,接口定义:根据需求分析定义接口,定义出接口文档
3,服务端和前端并行开发
服务端:依据接口文档进行服务端接口开发
前端:根据用户需求开发操作界面,并根据接口文档制作mock数据,进行测试
4,前后端集成接口联调
最终前端调用服务端接口完成业务

2、后端接口开发规范

  • 2.1 开发原则
  • 自顶向下的设计原则:功能应该从表现层分析再到控制层、服务层、持久层逐层设计
  • 自底向上的开发原则:上层需调用下层,因此开发应从底层向上层逐层开发
  • 项目中开发的层次次序参考DB->中间件->持久层->服务层->控制层
  • 单一职责的开发原则:类或者方法提供的功能应该单一明确,特别越底层越应单一职责,以便维护,项目中Mapper方法必须功能单一,参数明确,拒绝两种以上的持久逻辑使用同一个Mapper方法
  • 依赖倒置的开发原则:上层依赖下层,是依赖下层接口,并不是依赖下层的实现
    项目中每层都是通过接口调用Controller->Service->Mapper
  • 2.2 开发步骤

明确类定义:明确哪些是重用类,哪些是需要新增的类
明确主键规则:确认操作表的ID生成规则,自增或id_work
ControllerApi定义:定义接口
Mapper实现:使用mybatis-plus封装的方法还是自定义mapper映射
Service实现:可用通过时序图帮助我们梳理实现逻辑
Controller实现:简单的Service层调用
单元测试或接口测试或前端直接联调测试

  • 2.3 接口版本规范说明

随着业务的复杂,同一个接口可能出现多个版本,为了方便后期切换和AB测试,需要定义接口的版本号

在某一个微服务下访问controller的时候在包名下加一个版本号,如下
properties
  com.lantian.app.controller.v1

在访问具体的接口方法的url映射的时候也应该加上版本说明,如下:

  @RequestMapping("/api/v1/app")
  

3、接口通用请求和响应

dto(Data Transfer Object):数据传输对象,用于展示层与服务层之间的数据传输对象

3.1 通用的响应对象

通用的响应对象:
不分页:com.heima.model.common.dtos.ResponseResult

/**
 * 通用的结果返回类
 * @param 
 */
public class ResponseResult<T> implements Serializable {

    private String host;

    private Integer code;

    private String errorMessage;

    private T data;

    public ResponseResult() {
        this.code = 200;
    }

    public ResponseResult(Integer code, T data) {
        this.code = code;
        this.data = data;
    }

    public ResponseResult(Integer code, String msg, T data) {
        this.code = code;
        this.errorMessage = msg;
        this.data = data;
    }

    public ResponseResult(Integer code, String msg) {
        this.code = code;
        this.errorMessage = msg;
    }

    public static ResponseResult errorResult(int code, String msg) {
        ResponseResult result = new ResponseResult();
        return result.error(code, msg);
    }

    public static ResponseResult okResult(int code, String msg) {
        ResponseResult result = new ResponseResult();
        return result.ok(code, null, msg);
    }

    public static ResponseResult okResult(Object data) {
        ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS,AppHttpCodeEnum.SUCCESS.getErrorMessage());
        if(data!=null) {
            result.setData(data);
        }
        return result;
    }

    public static ResponseResult errorResult(AppHttpCodeEnum enums){
        return setAppHttpCodeEnum(enums,enums.getErrorMessage());
    }

    public static ResponseResult errorResult(AppHttpCodeEnum enums,String errorMessage){
        return setAppHttpCodeEnum(enums,errorMessage);
    }

    public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){
        return okResult(enums.getCode(),enums.getErrorMessage());
    }

    private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums,String errorMessage){
        return okResult(enums.getCode(),errorMessage);
    }

    public ResponseResult<?> error(Integer code, String msg) {
        this.code = code;
        this.errorMessage = msg;
        return this;
    }

    public ResponseResult<?> ok(Integer code, T data) {
        this.code = code;
        this.data = data;
        return this;
    }

    public ResponseResult<?> ok(Integer code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.errorMessage = msg;
        return this;
    }

    public ResponseResult<?> ok(T data) {
        this.data = data;
        return this;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }
}

3.2 分页通用返回

public class PageResponseResult extends ResponseResult {
    private Integer currentPage;
    private Integer size;
    private Integer total;

    public PageResponseResult(Integer currentPage, Integer size, Integer total) {
        this.currentPage = currentPage;
        this.size = size;
        this.total = total;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }
}

3.3 通用的请求dtos

Data
@Slf4j
public class PageRequestDto {

    protected Integer size;
    protected Integer page;

    public void checkParam() {
        if (this.page == null || this.page < 0) {
            setPage(1);
        }
        if (this.size == null || this.size < 0 || this.size > 100) {
            setSize(10);
        }
    }
}

3.4 用的异常枚举

public enum AppHttpCodeEnum {

    // 成功段0
    SUCCESS(0,"操作成功"),
    // 登录段1~50
    NEED_LOGIN(1,"需要登录后操作"),
    LOGIN_PASSWORD_ERROR(2,"密码错误"),
    // TOKEN50~100
    TOKEN_INVALID(50,"无效的TOKEN"),
    TOKEN_EXPIRE(51,"TOKEN已过期"),
    TOKEN_REQUIRE(52,"TOKEN是必须的"),
    // SIGN验签 100~120
    SIGN_INVALID(100,"无效的SIGN"),
    SIG_TIMEOUT(101,"SIGN已过期"),
    // 参数错误 500~1000
    PARAM_REQUIRE(500,"缺少参数"),
    PARAM_INVALID(501,"无效参数"),
    PARAM_IMAGE_FORMAT_ERROR(502,"图片格式有误"),
    SERVER_ERROR(503,"服务器内部错误"),
    // 数据错误 1000~2000
    DATA_EXIST(1000,"数据已经存在"),
    AP_USER_DATA_NOT_EXIST(1001,"ApUser数据不存在"),
    DATA_NOT_EXIST(1002,"数据不存在"),
    // 数据错误 3000~3500
    NO_OPERATOR_AUTH(3000,"无权限操作");

    int code;
    String errorMessage;

    AppHttpCodeEnum(int code, String errorMessage){
        this.code = code;
        this.errorMessage = errorMessage;
    }

    public int getCode() {
        return code;
    }

    public String getErrorMessage() {
        return errorMessage;
    }
}

4、通用环境说明

4.1 多环境切换

maven_dev.properties
maven_prod.properties
maven_test.properties



<profiles>
    <profile>
        <id>devid>
        <build>
            <filters>
                <filter>maven_dev.propertiesfilter>
            filters>
        build>
    profile>
    <profile>
        <id>testid>
        <activation>
            <activeByDefault>trueactiveByDefault>
        activation>
        <build>
            <filters>
                <filter>maven_test.propertiesfilter>
            filters>
        build>
    profile>
    <profile>
        <id>prodid>
        <build>
            <filters>
                <filter>maven_prod.propertiesfilter>
            filters>
        build>
    profile>
profiles>

你可能感兴趣的:(spring系列,spring)