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

news2024/11/27 7:35:59

开始前必读:​​基于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;
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1349397.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Pytorch】Pytorch或者CUDA版本不符合问题解决与分析

NVIDIA CUDA Toolkit Release Notes Package installation issues INSTALL PYTORCH 先声毒人&#xff1a;最好资料就是上面三份资料&#xff0c;可以通过官网明确的获取一手信息&#xff0c;你所遇到的99%的问题都可以找到&#xff0c;明确的解决方案&#xff0c;建议最好看…

2024主流的免费电脑数据恢复软件EasyRecovery

EasyRecovery绿色版是一款非常专业的电脑数据恢复工具。它可以全面恢复删除丢失数据&#xff0c;能对电脑误删文件恢复、格式化硬盘数据恢复、手机U盘数据恢复等&#xff0c;能恢复包括文档、表格、图片、音视频等各种文件&#xff0c;此版本经过处理&#xff0c;可永久免费使用…

[ffmpeg系列 02] 音视频基本知识

一 视频 RGB&#xff1a; AV_PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB… Y&#xff1a;明亮度, Luminance或luma, 灰阶图&#xff0c; UV&#xff1a;色度&#xff0c;Chrominance或Chroma。 YCbCr: Cb蓝色分量&#xff0c;Cr是红色分量。 取值范围&#xff…

【索引的数据结构】第1章节:B+Tree存储结构

目录结构 之前整篇文章太长&#xff0c;阅读体验不好&#xff0c;将其拆分为几个子篇章。 本篇章讲解 BTree 存储结构。 什么是索引 可以简单理解为索引好比一本书的目录&#xff0c;通过目录我们可以快速定位到我们要查看的章节。 MySQL 中的数据同样也是根据索引分类&…

ROS TF坐标变换 - 位姿描述与消息类型

目录 一、位姿描述二、位姿相关消息体类型2.1 geometry_msgs/TransformStamped2.2 geometry_msgs/PoseStamped 在机器人系统中&#xff0c;有许多运动机构和传感器&#xff0c;为了描述他们之间的相对位姿关系&#xff0c;分别为他们定义了各自的坐标系&#xff0c;通过坐标系转…

合伙企业法关于合伙企业的要求

合伙协议可以载明合伙企业的经营期限和合伙人争议的解决方式。 合伙协议经全体合伙人签名、盖章后生效。合伙人依照合伙协议享有权利&#xff0c;承担责任。 经全体合伙人协商一致&#xff0c;可以修改或者补充合伙协议。 申请合伙企业设立登记&#xff0c;应当向企业登记机关提…

B2005 字符三角形(python)

a input() print( a) print( a a a) print(a a a a a)python中默认输入的是字符型&#xff0c;第一句就是输入了一个字符赋给a python中单引号内的也是字符串&#xff0c;用print输出需要连接的字符串时用加号加在后面即可

Spring通信传参的方法

Spring通信传参的方法 目录概述需求&#xff1a; 设计思路实现思路分析1.简单参数传递2.复合参数3.动态参数 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better resul…

爬虫基础一(持续更新)

爬虫概念&#xff1a; 通过编写程序&#xff0c;模拟浏览器上网&#xff0c;然后让其去互联网上抓取数据的过程 分类&#xff1a; 1&#xff0c;通用爬虫&#xff1a;抓取一整张页面数据 2&#xff0c;聚焦爬虫&#xff1a;抓取页面中的局部内容 3&#xff0c;增量式爬虫&…

消息中间件常见知识点

一&#xff1a;消息队列的主要作用是什么&#xff1f; 1.消息队列的特性&#xff1a; 业务无关&#xff0c;一个具有普适性质的消息队列组件不需要考虑上层的业务模型&#xff0c;只做好消息的分发就可以了&#xff0c;上层业务的不同模块反而需要依赖消息队列所定义的规范进行…

JVM篇:JVM的简介

JVM简介 JVM全称为Java Virtual Machine&#xff0c;翻译过来就是java虚拟机&#xff0c;Java程序&#xff08;Java二进制字节码&#xff09;的运行环境 JVM的优点&#xff1a; Java最大的一个优点是&#xff0c;一次编写&#xff0c;到处运行。之所以能够实现这个功能就是依…

go语言语法基础

文章目录 前言一、输入和输出常用的字符串格式化符号 二、注释三、Go常用基本语言数据类型数字类型布尔类型字符类型变量与常量数组和切片数组切片 map类型创建map增删改查特别提醒 指针 四、运算符五、条件判断语句if系列switch六、循环语句for循环标准写法死循环while循环do …

java设计模式学习之【观察者模式】

文章目录 引言观察者模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用观察者示例代码地址 引言 想象你在一个在线拍卖会上竞标一件珍贵的艺术品。每当有人出价更高&#xff0c;系统都会立即通知你。这个实时更新机制使你可以做出快速反应。这种模式&#x…

Linux之进程管理

什么是进程 在linux中每个执行的程序都称为一个进程&#xff0c;每个进程都分配一个ID号&#xff08;pid进程号&#xff09;。每个进程都可能以两种方式存在&#xff0c;即前台和后天。前台进程就是用户目前的屏幕上可以进行操作的。后台进程则是实际在操作&#xff0c;但屏幕…

hugo-theme-kiwi V0.0.2 博客主题上新了时间轴

至此佳节&#xff0c;我在此给正在屏幕前浏览本文的您和您的家人&#xff0c;恭祝元旦快乐&#xff0c;虽然&#xff0c;这声祝福是晚了&#xff0c;但却不妨碍我我由内心深处对您和您的家人的诚挚祝福&#xff01; 新的一年&#xff0c;从这一天逐渐步入我们的生活&#xff0c…

web等保评测需要实机查看的操作系统、服务器、数据库和应用部分

“等保测评”全称是信息安全等级保护测评。是经公安部认证的具有资质的测评机构&#xff0c;依据国家信息安全等级保护规范规定&#xff0c;受有关单位委托&#xff0c;按照有关管理规范和技术标准&#xff0c;对信息系统安全等级保护状况进行检测评估的活动。 本文陆续将遇到的…

『番外篇九』SwiftUI 实战:打造一款“五脏俱全”的网络图片显示 App(上)

概览 俗话说得好:“读书破万卷,下笔如有神”。不过如果把这句话放到编程的学习上可就不那么贴切了。 要想熟练掌握一门编程语言,光看书是绝对不够的。我们还需尽可能的多撸码、早撸码,撸到无路可退、海枯石烂才有可能一窥门径。 在本篇和续篇博文中,我们将和小伙伴们一起…

手把手教你绘制和解读实用R列线图(Nomogram):从入门到精通

一、引言 列线图&#xff08;Nomogram&#xff09;是一种常用的数据可视化工具&#xff0c;它能够直观地展示多个变量之间的关系&#xff0c;并帮助我们理解和解释复杂的数据模式。通过绘制列线图&#xff0c;我们可以将各种变量的影响和相互关联转化为图形化的表示&#xff0c…

2001-2021年各省高速公路里程数据

2001-2021年全国及各省高速公路里程数据 1、时间&#xff1a;2001-2021年 2、指标&#xff1a;高速公路里程 3、范围&#xff1a;全国及30个省市 &#xff08;不含西藏&#xff09; 4、来源&#xff1a;各省NJ、省TJGB、第三产业TJNJ &#xff08;无缺失&#xff09; 5、指…

鸿蒙项目方舟框架(ArkUI)之线性布局容器Stack组件

鸿蒙项目方舟框架&#xff08;ArkUI&#xff09;之线性布局容器Stack组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Stack组件 堆叠容器&#xff0c;子组件按照顺序依次入栈&#xff0c;后一个子组件覆盖前一个子组件。 …