基于grpc从零开始搭建一个准生产分布式应用(9) - Service业务逻辑层实现

本文主要是介绍基于grpc从零开始搭建一个准生产分布式应用(9) - Service业务逻辑层实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

前面章节的GRPC内基本是一个空实现,本章就实现下service业务逻辑层代码,因例子比较简单代码量也不算大,本章代码任务:1、用spring实现服务层,熟悉各注解的使用;2、实现一个VO逻辑,巩固mapStruct框架的使用。

一、工程结构

本章只涉及【base-grpc-framework-core】工程的改动,需改动的代码如下图所示:

二、创建必要的实体类

2.1、MVC层VO类

package com.zd.baseframework.core.controller.core.vo;import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Data;import java.time.LocalDateTime;@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class SystemLogVo {private Long id;private String bizId;private Long userId;private String trackUid;private String code;private String customCode;private Integer state;@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")private LocalDateTime ctime;@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")private LocalDateTime utime;
}

2.2、Service层BO类

package com.zd.baseframework.core.core.systemlog.model;import lombok.Data;
import java.time.LocalDateTime;@Data
public class SystemLogBo {private Long id;private String bizId;private Long userId;private String trackUid;private String code;private String customCode;private Integer state;private LocalDateTime ctime;private LocalDateTime utime;
}
package com.zd.baseframework.core.core.systemlog.model;import lombok.Data;@Data
public class SystemLogQueryBo {private String bizId;private Long userId;private String code;}

2.3、VO和BO的专换工具类

新增代码第16~20行,转换VO和BO

/*** @Title: com.zd.baseframework.core.controller.core.translator.SystemLogTranslator* @Description http层与grpc层对象转换工具* @author liudong* @date 2022/6/15 8:52 PM*/
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,imports = {MapStructMapperUtil.class},uses = BaseMapStructMapper.class)
public interface SystemLogTranslator {SystemLogTranslator INSTANCE = Mappers.getMapper(SystemLogTranslator.class);/*查询请求参数转换*/ListSystemLogRequest toGrpcQueryReqObject(SystemLogQueryRequest var);/*查询返回结果转换,这两个是一组,其中在生成源码时toQueryResultVos会调用toQueryResultVo*/SystemLogVo toQueryResultVo(SystemLogDto var);List<SystemLogVo> toQueryResultVos(List<SystemLogDto> var);
}
/*** @Title: com.zd.baseframework.core.core.systemlog.api.SystemLogDtoTranslator* @Description grpc与service层对象转换工具类* @author liudong* @date 2022/6/15 8:59 PM*/
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,imports = {MapStructMapperUtil.class},uses = BaseMapStructMapper.class)
public interface SystemLogDtoTranslator {SystemLogDtoTranslator INSTANCE = Mappers.getMapper(SystemLogDtoTranslator.class);/*查询请求参数转换*/SystemLogQueryBo toQueryBo(ListSystemLogRequest var);/*返回结果转换*/SystemLogDto toQueryResultDto(SystemLogBo var);List<SystemLogDto> toQueryResultDtos(List<SystemLogBo> var);
}

三、创建Service接口和实现

3.1、接口定义

package com.zd.baseframework.core.core.systemlog.service;public interface ISystemLogServcie {boolean createSystemLog(SystemLogBo systemLogBo);List<SystemLogBo> listByCondition(SystemLogQueryBo systemLogQueryBo);
}

3.2、接口实现

package com.zd.baseframework.core.core.systemlog.service.impl;@Service
@Slf4j
@Primary
public class SystemLogServcieImpl implements ISystemLogServcie {@Overridepublic boolean createSystemLog(SystemLogBo systemLogBo) {String trackLog = LogGenerator.trackLog();log.info(trackLog+ "createSystemLog=" + JSONUtil.toJsonStr(systemLogBo));try{return null;}catch(Exception e){throw e;}}@Overridepublic List<SystemLogBo> listByCondition(SystemLogQueryBo systemLogQueryBo) {String trackLog = LogGenerator.trackLog();try{return null;}catch(Exception e){throw e;}}
}

四、建立GRPC与SERVICE调用关系

4.1、Contoller集成VO

修改com.zd.baseframework.core.controller.core.SystemLogController类的如下方法,新增第5~8行。

@PostMapping("/v1/list_systemlog")public BaseResponse listSystemLog(@RequestBody SystemLogQueryRequest systemLogRequest){try{//构建查询参数ListSystemLogRequest listSystemLogRequest  = SystemLogTranslator.INSTANCE.toGrpcQueryReqObject(systemLogRequest);ListSystemLogResponse listSystemLogResponse = iSysRecordServiceBlockingStub.listSystemLogByCondition(listSystemLogRequest);List<SystemLogVo> vos = SystemLogTranslator.INSTANCE.toQueryResultVos(listSystemLogResponse.getDataList());return BaseResponse.success(vos);}catch(StatusRuntimeException e){log.error("ErrorCode : " + e.getStatus().getCode());return BaseResponse.error(e.getMessage());}catch(Exception e){e.printStackTrace();return BaseResponse.error(e.getMessage());}}

4.2、Grpc调用Service逻辑

修改com.zd.baseframework.core.core.systemlog.api.impl.SystemLogServiceApiImpl类,完整代码如下:

@GrpcService
@Slf4j
public class SystemLogServiceApiImpl extends ISystemLogServiceGrpc.ISystemLogServiceImplBase {@Autowiredprivate ISystemLogServcie iSystemLogServcie;@Overridepublic void createSystemLog(CreateSystemLogRequest request, StreamObserver<SystemLogOperatorResponse> responseObserver)  {String bizId = request.hasBizId()?request.getBizId().getValue():null;Long userId  = request.hasUserId()?request.getUserId().getValue():null;String code = request.hasCode()?request.getCode().getValue():null;String customCode = request.hasCustomCode()?request.getCustomCode().getValue():null;String trackLog = LogGenerator.trackLog();try{//打印原始入参log.info(trackLog+ " grpcReqParam=" + JsonFormat.printer().omittingInsignificantWhitespace().print(request));//入参验证if(StrUtil.isEmpty(bizId)|| null==userId|| StrUtil.isEmpty(code) ){throw new AppException("非法参数");}SystemLogBo systemLogBo = new SystemLogBo();systemLogBo.setCode(code);systemLogBo.setCustomCode(customCode);systemLogBo.setBizId(bizId);systemLogBo.setUserId(userId);systemLogBo.setTrackUid("10000");boolean result = iSystemLogServcie.createSystemLog(systemLogBo);if(result){SystemLogOperatorResponse response  = SystemLogOperatorResponse.newBuilder().setStatus(ResponseConst.SUCCESS).setMessage(ResponseConst.Msg.SUCCESS).build();responseObserver.onNext(response);}else{log.info(trackLog+ " grpcReqParam=" + JsonFormat.printer().omittingInsignificantWhitespace().print(request)+ " result=fail" );responseObserver.onError(Status.INVALID_ARGUMENT.asException());}responseObserver.onCompleted();}catch (AppException e) {log.error(e.getMessage());responseObserver.onError(Status.INVALID_ARGUMENT.withDescription(e.getMessage()).asException());}catch(Exception e){log.error(e.getMessage());responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());}}@Overridepublic void listSystemLogByCondition(ListSystemLogRequest request, StreamObserver<ListSystemLogResponse> responseObserver) {String trackLog = LogGenerator.trackLog();try{//打印原始入参log.info(trackLog+ " grpcReqParam=" + JsonFormat.printer().omittingInsignificantWhitespace().print(request));SystemLogQueryBo systemLogQueryBo = SystemLogDtoTranslator.INSTANCE.toQueryBo(request);List<SystemLogBo> systemLogBoList = iSystemLogServcie.listByCondition(systemLogQueryBo);log.info(trackLog+ " systemLogBoListSize=" + CollUtil.size(systemLogBoList));List<SystemLogDto> dtos = SystemLogDtoTranslator.INSTANCE.toQueryResultDtos(systemLogBoList);ListSystemLogResponse response = ListSystemLogResponse.newBuilder().addAllData(dtos).build();responseObserver.onNext(response);responseObserver.onCompleted();}catch (AppException e) {log.error(e.getMessage());responseObserver.onError(Status.INVALID_ARGUMENT.withDescription(e.getMessage()).asException());}catch(Exception e){log.error(e.getMessage());responseObserver.onError(Status.INTERNAL.withDescription(e.getMessage()).asException());}}
}

这篇关于基于grpc从零开始搭建一个准生产分布式应用(9) - Service业务逻辑层实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/560019

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja