基于grpc从零开始搭建一个准生产分布式应用(8) - 01 - 附:GRPC公共库源码

发布时间:2023年12月20日

开始前必读:??基于grpc从零开始搭建一个准生产分布式应用(0) - quickStart???

common包中的源码,因后续要用所以一次性全建好了。

一、common工程完整结构

二、引入依赖包

<?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>base-grpc-framework-parent</artifactId>
        <groupId>com.zd</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>base-grpc-framework-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>net.devh</groupId>
            <artifactId>grpc-server-spring-boot-starter</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <scope>compile</scope>
        </dependency>

    </dependencies>

</project>

三、源码-常量

package com.zd.baseframework.common.constants;

/**
 * @Title: com.zd.baseframework.common.constants.ResponseConst
 * @Description 系统常量类,定义一些返回码等,这里不建议定义成(int, string)枚举,因为1个错误码可能对应多个描述字段,分开来定义更灵活,
 * 同时定义在一个类里面又达到了一种封装效果
 * @author liudong
 * @date 2022/6/15 8:48 PM
 */
public interface ResponseConst {

    int SUCCESS = 0;

    int FAIL = 1;

    interface Msg{
        String SYS_ERROR = "系统异常 ";

        String SUCCESS = "请求成功";

        String FAIL = "请求失败";
    }

}
package com.zd.baseframework.common.enumeration;

/**
 * @author liudong
 * @Title: AppEnum
 * @Description 和系统相关的一些枚举值
 * @date 2022/2/6 12:27 PM
 */
public interface AppEnum {

    enum AppType implements AppEnum {
        X_APP, DOMAIN, PLUGIN,
        ;
    }

    enum Protocol implements AppEnum {
        HTTP("http"), HTTPS("https"), GRPC("grpc"),
        ;
        private final String value;

        Protocol(String value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return this.value;
        }

    }
}

四、源码-对象基础类

Dao实体基础类

package com.zd.baseframework.common.entity.dao;

import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.Date;

/**
 * @author liudong
 * @Title: BaseEntity
 * @Description 此基类主要用于mybatis的实体定义继承用,这里固定了三个参数
 * id:数据库代理主键
 * ctime:创建时间
 * utime:更新时间
 * @date 2022/1/23 6:55 PM
 */
@Data
@EqualsAndHashCode(callSuper = false, of = {"id"})
public abstract class BaseEntity<T extends Model<T>> extends Model<T> {
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    @TableField(value = "ctime", fill = FieldFill.INSERT, insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date ctime;

    @TableField(value = "utime", fill = FieldFill.INSERT_UPDATE, insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date utime;
}
package com.zd.baseframework.common.entity.dao;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Slf4j
@Component
public class BaseMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        // 设置创建与更新时间
        Date nowTime = new Date();
        if (metaObject.hasGetter("ctime")) {

            // 记录创建信息
            this.setFieldValByName("ctime", nowTime, metaObject);
        }
        if (metaObject.hasGetter("utime")) {
            // 记录更新时间
            this.setFieldValByName("utime", nowTime, metaObject);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        if (metaObject.hasGetter("utime")) {
            Date nowTime = new Date();
            // 记录更新信息
            this.setFieldValByName("utime", nowTime, metaObject);
        }
    }
}

Http实体基础类

package com.zd.baseframework.common.entity.http;

import com.zd.baseframework.common.constants.ResponseConst;
import lombok.Data;

/**
 * @author liudong
 * @Title: com.zd.baseframework.common.entity.http.ResponseEntity
 * @Description 用于controller的正常返回
 * @date 2022/1/23 7:00 PM
 */
@Data
public class BaseResponse<T> {
    /*响应状态码@see ResponseConstants*/
    private Integer status;
    /*响应概要信息*/
    private String message;
    /*响应数据*/
    private T data;

    public BaseResponse() {

    }

    public BaseResponse(Integer status, String message) {
        this.status = status;
        this.data = null;
        this.message = message;
    }

    public BaseResponse(Integer status, String message, T data) {
        this(status, message);
        this.data = data;
    }

    /*响应成功*/
    public static <T> BaseResponse<T> success(T o) {
        return new BaseResponse<>(ResponseConst.SUCCESS, ResponseConst.Msg.SUCCESS, o);
    }

    public static <T> BaseResponse<T> success(String msg, T o) {
        return new BaseResponse<>(ResponseConst.SUCCESS, msg, o);
    }

    /*响应失败*/
    public static <T> BaseResponse<T> error() {
        return new BaseResponse<>(ResponseConst.FAIL,  ResponseConst.Msg.FAIL);
    }

    public static <T> BaseResponse<T> error(String msg) {
        return new BaseResponse<>(ResponseConst.FAIL, msg);
    }

    public static <T> BaseResponse<T> error(Integer status, String msg) {
        return new BaseResponse<>(status, msg);
    }
}
package com.zd.baseframework.common.entity.http;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;

/**
 * @author liudong
 * @Title: com.zd.baseframework.common.entity.http.FileResponseEntity
 * @Description 用于controller返回文件上传的返回值
 * @date 2022/1/23 7:11 PM
 */
@Slf4j
public class FileResponse {

    public static ResponseEntity responseSuccess(File file) {
        if (file == null) {
            return null;
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=" + file.getName());
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
    }

    public static ResponseEntity responseSuccess(String content, String fileName) {
        if (content == null) {
            return null;
        }
        File file = new File(fileName);
        try {
            OutputStream os = new FileOutputStream(file);
            os.write(content.getBytes());
            os.close();
        } catch (IOException e) {
            log.error("write to file error");
        }
        HttpHeaders headers = new HttpHeaders();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Content-Disposition", "attachment; filename=" + file.getName());
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Last-Modified", new Date().toString());
        headers.add("ETag", String.valueOf(System.currentTimeMillis()));
        return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
    }

}
package com.zd.baseframework.common.entity.http;

import com.zd.baseframework.common.constants.ResponseConst;
import lombok.Data;

import java.util.List;

@Data
public class ListBaseResponse<T> extends BaseResponse<T> {

    /*数据的总条数*/
    private Long count;
    public ListBaseResponse() {
        super();
    }

    public ListBaseResponse(Integer status, String message) {
        super(status, message);
    }

    public ListBaseResponse(Integer status, String msg, T value, Integer count) {
        super(status, msg, value);
        this.count = Long.valueOf(count == null ? 0 : count);
    }

    public static ListBaseResponse responseListSuccess(String msg, List list) {
        long size = 0L;
        if (list != null) {
            size = list.size();
        }
        return new ListBaseResponse(ResponseConst.SUCCESS, msg, list, Math.toIntExact(size));
    }

    public static ListBaseResponse responseListSuccess(String msg, List list, Integer count) {
        return new ListBaseResponse(ResponseConst.SUCCESS, msg, list, count);
    }
}
package com.zd.baseframework.common.entity.http;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zd.baseframework.common.constants.ResponseConst;
import lombok.Data;

/**
 * @author liudong
 * @Title: com.zd.baseframework.common.entity.http.PageResponseEntity
 * @Description 分页响应对象
 * @date 2022/1/23 7:30 PM
 */
@Data
public class PageBaseResponse<T> extends ListBaseResponse<T> {

    /*偏移位置,用于内部计算*/
    private Long offset;
    /*每页多少条*/
    private Long pageSize;
    /*当前第几页*/
    private Long currentPage;

    public PageBaseResponse() {
        super();
    }

    public PageBaseResponse(Integer status, String message) {
        super(status, message);
    }

    public PageBaseResponse(Integer status, String msg, T value, Integer count, Integer offset, Integer pageSize, Integer currentPage) {
        super(status, msg, value, count);
        this.offset = Long.valueOf(offset);
        this.pageSize = Long.valueOf(pageSize);
        this.currentPage = Long.valueOf(currentPage);
    }

    /*为了适应IPage,暂定这样,后续有可能优化*/
    public PageBaseResponse(Integer status, String msg, T value, Long count, Long offset, Long pageSize, Long currentPage) {
        super(status, msg, value, Math.toIntExact(count));
        this.offset = Long.valueOf(offset);
        this.pageSize = Long.valueOf(pageSize);
        this.currentPage = Long.valueOf(currentPage);
    }

    public static <T> PageBaseResponse<T> responseListSuccess(String msg, IPage pageEntity) {
        return new PageBaseResponse(ResponseConst.SUCCESS, msg, pageEntity.getRecords(),
                Math.toIntExact(pageEntity.getTotal()),
                Math.toIntExact(pageEntity.offset()),
                Math.toIntExact(pageEntity.getSize()),
                Math.toIntExact(pageEntity.getCurrent()));
    }

}

MapStruct工具类

可查看??基于grpc从零开始搭建一个准生产分布式应用(5) - MapStruct传输对象转换??附录部分

Model实体基础类

@Data
public abstract class BaseModel {
    private Long id;

    private Date ctime;

    private Date utime;
}
package com.zd.baseframework.common.entity.model;

import lombok.Data;

import java.util.List;

@Data
public class WrapBoForDto<T> {
    private Integer count;

    private Integer offset;

    private Integer pageSize;

    private Integer currentPage;

    private List<T> data;
}

五、源码-异常

package com.zd.baseframework.common.exceptions;

/**
 * @author liudong
 * @Title: AppException
 * @Description 基础异常类,用于处理普通业务上的异常,直接抛送即可,定义不同的异常类主要是用于区别异常的类型
 * @date 2022/1/17 4:52 PM
 */
//TODO  异常传导链断了,需要修复
public class AppException extends RuntimeException {

    private Integer status;

    public AppException() {
        super();
    }

    public AppException(String message) {
        super(message);
    }

    public AppException(String s, Throwable throwable) {
        super(s, throwable);
    }

    public AppException(Throwable throwable) {
        super(throwable);
    }

    public AppException(Integer status, String message) {
        super(message);
        this.status = status;
    }

    public Integer getStatus() {
        return this.status;
    }

}

文章来源:https://blog.csdn.net/liudonglovehemin/article/details/135090531
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。