commons-dto 工具模块设计规范

AI编码助手是认知负荷转移器,不是生产力加速器 AI编程工具本质上是代码生成辅助技术,其核心原理在于利用大语言模型对海量开源代码的模式识别与上下文补全能力,将开发者从语法补全、API查证、模板化代码编写等低阶重复劳动中释放出来;技术价值不在于替代人类编码,而在于提升单位时间内的有效决策密度;典型应用场景包括CR辅助审查、规范驱动的代码生成、边界条件自动注入等;关键瓶颈在于意图表达精度与结果可信验证——这正是‘提示词工程’和‘本地知识库’成为落地刚需的原因;本文聚焦真实产线中AI编码的隐性成本、可用性瓶颈与工程化落地路径。 阅读详情

你提出的这个问题非常关键——commons-dto 模块是整个微服务架构的“契约基石”和“协作枢纽”。

在分布式系统中,不同服务之间通过 HTTP API 通信,而 DTO(Data Transfer Object) 是它们交换数据的唯一载体。
如果每个服务都自己定义一套 DTO,就会导致:

  • 前端对接困难(字段名不一致)
  • 接口文档混乱
  • 类型无法复用(如 UserBaseInfo 在 5 个服务里重复定义)
  • 难以做自动化测试、Mock、代码生成
  • 新人上手成本高

✅ commons-dto 的核心使命就是:让所有服务使用同一套“语言”说话。


📜《urbane-commerce commons-dto 工具模块设计规范》

版本:19.0 | 最后更新:2025年4月 | 技术栈:Java + Lombok + Jackson + OpenAPI


✅ 一、commons-dto 模块的核心作用(Why?)

作用说明
✅ 统一数据契约所有服务对“用户”、“订单”、“商品”的结构定义完全一致
✅ 避免重复定义不再出现 order-service.UserVO、product-service.UserDTO、auth-service.UserInfo 三类同义对象
✅ 前端/测试统一依赖前端、Postman、自动化测试工具只需引入一个 JAR,就能获得完整接口模型
✅ 支持 OpenAPI 文档生成SpringDoc 能自动识别并展示 commons-dto 中的类型,提升文档质量
✅ 提升开发效率IDE 自动补全、类型安全、重构一键同步
✅ 降低耦合度业务服务不再强依赖对方实体,只依赖抽象 DTO
✅ 支持序列化/反序列化优化统一使用 @JsonInclude、@JsonIgnoreProperties 等注解控制 JSON 输出
✅ 支撑自动化代码生成可基于 DTO 生成前端 TypeScript 接口、Swagger 客户端、Mock 数据

💡 一句话总结:
commons-dto 就是微服务之间的“通用语言字典”——没有它,团队就是在说不同的方言。


✅ 二、推荐目录结构(企业级标准)

commons/
├── commons-dto/                             ← 👉 核心模块
│   ├── pom.xml                              ← 独立 Maven 模块,打包为 JAR
│   └── src/main/java/io/urbane/commons/dto/
│       ├── dto/                             ← 核心 DTO 类(按业务域分包)
│       │   ├── user/                        ← 用户相关
│       │   │   ├── UserBaseInfo.java        ← 用户基础信息(脱敏)
│       │   │   └── UserLoginResponse.java   ← 登录响应
│       │   ├── order/                       ← 订单相关
│       │   │   ├── OrderSummary.java        ← 订单摘要(列表页)
│       │   │   ├── OrderItem.java           ← 订单明细项
│       │   │   └── CreateOrderRequest.java  ← 创建订单请求
│       │   ├── product/                     ← 商品相关
│       │   │   ├── ProductSummary.java      ← 商品摘要(搜索结果)
│       │   │   ├── ProductDetail.java       ← 商品详情(非快照)
│       │   │   └── SkuInfo.java             ← SKU 销售单元信息
│       │   ├── promotion/                   ← 促销相关
│       │   │   ├── CouponSummary.java       ← 优惠券摘要
│       │   │   └── PromotionOption.java     ← 可选优惠方案
│       │   ├── logistics/                   ← 物流相关
│       │   │   ├── WaybillSummary.java      ← 运单摘要
│       │   │   └── TrackingInfo.java        ← 物流轨迹信息
│       │   ├── common/                      ← 公共基础类型
│       │   │   ├── PageRequest.java         ← 分页参数
│       │   │   ├── ResponseResult.java      ← 统一响应体(code, message, data)
│       │   │   ├── ErrorResponse.java       ← 统一错误体
│       │   │   └── IdempotentRequest.java   ← 幂等请求(含 clientOrderId)
│       │   │
│       │   ├── util/                        ← 工具类(可选)
│       │   │   └── JsonUtils.java           ← Jackson 工具封装(如忽略空值)
│       │   │
│       │   └── constant/                    ← 枚举常量
│       │       ├── OrderStatus.java         ← 订单状态枚举
│       │       ├── PaymentMethod.java       ← 支付方式
│       │       └── ResponseCode.java        ← 响应码枚举(200=成功)
│       │
│       └── README.md                        ← 模块使用说明文档
│
└── ...

✅ 命名规范:

  • 包名:io.urbane.commons.dto.<domain>(小写 kebab-case)
  • 文件名:<名词><类型>.java(如 UserBaseInfo.java)
  • 类名:使用 PascalCase,语义清晰

✅ 三、核心文件详解(带详细中文注释)

1️⃣ commons-dto/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">
    <modelVersion>4.0.0</modelVersion>

    <!-- 与父模块保持一致 -->
    <groupId>io.urbane</groupId>
    <artifactId>commons-dto</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>urbane-commons-dto</name>
    <description>统一数据传输对象(DTO),供所有微服务共享</description>

    <!-- 依赖核心库 -->
    <dependencies>
        <!-- Lombok:减少 getter/setter/toString/构造函数样板代码 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
            <optional>true</optional>
        </dependency>

        <!-- Jackson:JSON 序列化/反序列化(Spring Boot 默认) -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.15.3</version>
        </dependency>

        <!-- SpringDoc OpenAPI 注解支持(用于生成 Swagger 文档) -->
        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
            <version>2.3.0</version>
            <scope>provided</scope> <!-- 仅编译时使用,不打包进 JAR -->
        </dependency>

        <!-- Java Bean Validation(JSR-303) -->
        <dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
            <version>3.0.2</version>
        </dependency>
    </dependencies>

    <!-- 构建配置 -->
    <build>
        <plugins>
            <!-- 编译器设置 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <!-- 打包时包含源码(方便调试) -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

✅ 关键点:

  • 使用 optional=true 避免 Lombok 传递依赖到下游项目
  • springdoc 使用 provided,因为它是注解库,由业务服务引入即可
  • 打包源码,方便 IDE 跳转查看 DTO 结构

2️⃣ dto/common/ResponseResult.java —— 统一响应体(核心!)

package io.urbane.commons.dto.common;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * 统一响应体结构(所有 API 返回都使用此格式)
 * 功能:
 *   - 所有服务对外返回的 JSON 都必须是此结构
 *   - 前端可统一处理:if (res.code === 200) { ... } else { alert(res.message) }
 *   - 与网关的 GlobalExceptionHandler 配合,实现前后端契约一致
 *
 * 注意:
 *   - 使用 @JsonInclude(NON_NULL) 避免返回 null 字段,减少网络流量
 *   - 使用 @Schema 描述该类,供 OpenAPI 自动生成文档
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL) // 忽略 null 字段
@Schema(description = "统一 API 响应结构")
public class ResponseResult<T> {

    /**
     * 状态码:200=成功,400=参数错误,500=服务器错误等
     * 与 HTTP 状态码保持一致,便于前端统一处理
     */
    @Schema(description = "HTTP 状态码,200=成功,401=未授权,500=服务器错误", example = "200")
    private int code;

    /**
     * 可读性消息,用于前端提示(如“密码错误”、“库存不足”)
     * 禁止返回堆栈信息或敏感细节
     */
    @Schema(description = "操作结果描述,用于前端提示用户", example = "操作成功")
    private String message;

    /**
     * 实际业务数据,泛型 T 表示任意类型(如 Order、Product、User)
     * 若无数据,则为 null
     */
    @Schema(description = "业务数据内容,若无则为 null")
    private T data;

    /**
     * 时间戳,ISO 8601 格式,便于前端解析
     * 用于审计、日志追踪、缓存控制
     */
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
    @Schema(description = "响应生成时间,ISO 8601 格式", example = "2025-04-05T10:30:00.123+08:00")
    private LocalDateTime timestamp;

    // ========== 构造函数 ==========
    public ResponseResult() {}

    // ========== 工厂方法(推荐使用)==========

    /**
     * 成功响应(无数据)
     */
    public static <T> ResponseResult<T> success() {
        ResponseResult<T> result = new ResponseResult<>();
        result.code = 200;
        result.message = "操作成功";
        result.timestamp = LocalDateTime.now();
        return result;
    }

    /**
     * 成功响应(有数据)
     */
    public static <T> ResponseResult<T> success(T data) {
        ResponseResult<T> result = new ResponseResult<>();
        result.code = 200;
        result.message = "操作成功";
        result.data = data;
        result.timestamp = LocalDateTime.now();
        return result;
    }

    /**
     * 成功响应(自定义消息)
     */
    public static <T> ResponseResult<T> success(String message, T data) {
        ResponseResult<T> result = new ResponseResult<>();
        result.code = 200;
        result.message = message;
        result.data = data;
        result.timestamp = LocalDateTime.now();
        return result;
    }

    /**
     * 失败响应(业务异常)
     */
    public static <T> ResponseResult<T> fail(int code, String message) {
        ResponseResult<T> result = new ResponseResult<>();
        result.code = code;
        result.message = message;
        result.timestamp = LocalDateTime.now();
        return result;
    }

    /**
     * 失败响应(默认 500)
     */
    public static <T> ResponseResult<T> fail(String message) {
        return fail(500, message);
    }
}

✅ 前端使用示例(TypeScript):

interface ApiResponse<T> {
  code: number;
  message: string;
  data?: T;
  timestamp: string;
}

const res = await axios.get('/user/me');
if (res.data.code === 200) {
  setUser(res.data.data); // 直接拿到 User 对象
} else {
  toast.error(res.data.message); // 统一提示
}

3️⃣ dto/common/ErrorResponse.java —— 统一错误响应

package io.urbane.commons.dto.common;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * 统一错误响应体
 * 功能:
 *   - 网关层全局异常处理器返回的错误格式
 *   - 与 ResponseResult 不同:它不包含 data 字段,仅用于错误场景
 *   - 用于记录路径、时间戳,便于链路追踪
 *
 * 注意:
 *   - 此类不被业务服务直接使用,而是由网关统一返回
 *   - 与 ResponseResult 分离,避免语义混淆
 */
@Data
@Schema(description = "全局异常返回的错误响应结构")
public class ErrorResponse {

    /**
     * 错误码(HTTP 状态码)
     */
    @Schema(description = "HTTP 状态码,如 401、404、500", example = "401")
    private int code;

    /**
     * 错误信息(用户可读)
     */
    @Schema(description = "错误描述信息,如 'Token 已过期'", example = "认证失败:Token 无效")
    private String message;

    /**
     * 请求路径
     */
    @Schema(description = "发生错误的请求路径", example = "/order/123")
    private String path;

    /**
     * 时间戳
     */
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
    @Schema(description = "错误发生时间,ISO 8601 格式", example = "2025-04-05T10:30:00.123+08:00")
    private LocalDateTime timestamp;

    // ========== 构造函数 ==========
    public ErrorResponse() {}

    public ErrorResponse(int code, String message, String path) {
        this.code = code;
        this.message = message;
        this.path = path;
        this.timestamp = LocalDateTime.now();
    }
}

✅ 为什么独立于 ResponseResult?
因为 ResponseResult 是“正常响应”,而 ErrorResponse 是“异常响应”。
前端需要区分:一个是 data,一个是 message,不能混用!


4️⃣ dto/user/UserBaseInfo.java —— 用户基础信息(脱敏)

package io.urbane.commons.dto.user;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * 用户基础信息 DTO(脱敏版)
 * 功能:
 *   - 所有服务返回用户信息时统一使用此结构
 *   - 避免暴露手机号、身份证、邮箱等敏感字段
 *   - 适用于登录、查询、展示等场景
 *
 * 注意:
 *   - 所有字段均为只读,不可修改
 *   - 邮箱、电话需脱敏显示(如 z***@example.com)
 *   - 不包含 passwordHash、lastLoginAt 等敏感字段
 */
@Data
@Schema(description = "用户基础信息(脱敏)")
public class UserBaseInfo {

    /**
     * 用户唯一 ID(主键)
     */
    @Schema(description = "用户唯一标识符", example = "123")
    private Long id;

    /**
     * 登录用户名(系统内部使用)
     */
    @Schema(description = "登录账号,用于系统内部识别", example = "zhangsan")
    private String username;

    /**
     * 显示昵称(前端展示用)
     */
    @Schema(description = "用户在界面上显示的名字", example = "小张")
    private String nickname;

    /**
     * 头像 URL(CDN 地址)
     */
    @Schema(description = "头像图片 URL", example = "https://cdn.example.com/avatar/123.jpg")
    private String avatar;

    /**
     * 脱敏后的邮箱(如 z***@example.com)
     */
    @Schema(description = "脱敏后的邮箱地址", example = "z***@example.com")
    private String email;

    /**
     * 角色列表(如 ["USER", "ADMIN"])
     */
    @Schema(description = "用户角色列表", example = "[\"USER\"]")
    private java.util.List<String> roles;

    /**
     * 会员等级
     */
    @Schema(description = "会员等级", example = "NORMAL")
    private String level;

    /**
     * 注册时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
    @Schema(description = "账户注册时间", example = "2024-01-01T00:00:00Z")
    private LocalDateTime createdAt;

    // ========== 构造函数 ==========
    public UserBaseInfo() {}

    public UserBaseInfo(Long id, String username, String nickname, String avatar,
                        String email, java.util.List<String> roles, String level, LocalDateTime createdAt) {
        this.id = id;
        this.username = username;
        this.nickname = nickname;
        this.avatar = avatar;
        this.email = email;
        this.roles = roles;
        this.level = level;
        this.createdAt = createdAt;
    }
}

✅ 关键设计:

  • 不包含手机号、身份证、地址 → 安全合规(GDPR)
  • email 脱敏 → 防止泄露隐私
  • roles 为 List<String> → 前端可直接判断权限
  • createdAt 为 ISO 格式 → 前端无需转换

5️⃣ dto/order/OrderSummary.java —— 订单摘要(用于列表页)

package io.urbane.commons.dto.order;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 订单摘要 DTO(用于订单列表页展示)
 * 功能:
 *   - 减少网络传输体积,仅包含前端展示所需字段
 *   - 不包含订单明细、收货地址、支付凭证等冗余信息
 *   - 与 OrderDetail 区分,避免滥用
 *
 * 注意:
 *   - 本类仅供前端列表页使用
 *   - 详情页使用 OrderDetail
 */
@Data
@Schema(description = "订单摘要信息(列表页使用)")
public class OrderSummary {

    /**
     * 订单号(全局唯一)
     */
    @Schema(description = "订单编号,如 ORD20250405123456", example = "ORD20250405123456")
    private String orderNo;

    /**
     * 订单总金额
     */
    @Schema(description = "订单总金额(含运费)", example = "8999.00")
    private BigDecimal totalAmount;

    /**
     * 实际支付金额
     */
    @Schema(description = "实际支付金额(扣除优惠后)", example = "8899.00")
    private BigDecimal payAmount;

    /**
     * 订单状态
     */
    @Schema(description = "订单状态:PENDING_PAYMENT / PAID / SHIPPED / DELIVERED / CANCELLED", example = "PAID")
    private String status;

    /**
     * 创建时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "GMT+8")
    @Schema(description = "订单创建时间", example = "2025-04-05T10:30:00Z")
    private LocalDateTime createdAt;

    /**
     * 收货人姓名(缩略)
     */
    @Schema(description = "收货人姓名(前两位+星号)", example = "张*")
    private String receiverName;

    /**
     * 商品数量
     */
    @Schema(description = "订单中商品总数", example = "2")
    private Integer itemCount;

    // ========== 构造函数 ==========
    public OrderSummary() {}
}

✅ 优势:

  • 查询 100 条订单,只传 1KB,而不是 10KB
  • 前端加载更快,体验更好
  • 与 OrderDetail 分离,职责清晰

6️⃣ dto/common/PageRequest.java —— 分页参数(公共基类)

package io.urbane.commons.dto.common;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import lombok.Data;

/**
 * 分页请求参数 DTO
 * 功能:
 *   - 所有列表查询接口统一使用此结构
 *   - 避免每个服务自己定义 page、size、sortBy
 *   - 支持校验和文档自动生成
 */
@Data
@Schema(description = "分页请求参数")
public class PageRequest {

    @NotNull(message = "页码不能为空")
    @Min(value = 1, message = "页码必须大于等于1")
    @Schema(description = "当前页码,从1开始", example = "1")
    private Integer page = 1;

    @NotNull(message = "每页数量不能为空")
    @Min(value = 1, message = "每页数量必须大于等于1")
    @Max(value = 100, message = "每页数量不能超过100")
    @Schema(description = "每页显示条数", example = "10")
    private Integer size = 10;

    @Schema(description = "排序字段,如 'created_at' 或 'price_asc'", example = "created_at_desc")
    private String sortBy;

    // ========== 构造函数 ==========
    public PageRequest() {}

    public PageRequest(Integer page, Integer size) {
        this.page = page;
        this.size = size;
    }
}

✅ 前端调用示例:

axios.get('/order/list', {
  params: {
    page: 1,
    size: 10,
    sortBy: 'created_at_desc'
  }
})

7️⃣ dto/constant/OrderStatus.java —— 枚举常量(避免魔法字符串)

package io.urbane.commons.dto.constant;

import io.swagger.v3.oas.annotations.media.Schema;

/**
 * 订单状态枚举
 * 功能:
 *   - 统一所有服务使用的订单状态值
 *   - 避免出现 "pending"、"wait_pay"、"已支付" 等不一致写法
 *   - 与数据库字段、API 响应保持一致
 */
@Schema(description = "订单状态枚举")
public enum OrderStatus {

    PENDING_PAYMENT("待支付"),
    PAID("已支付"),
    SHIPPED("已发货"),
    DELIVERED("已签收"),
    COMPLETED("已完成"),
    CANCELLED("已取消");

    private final String description;

    OrderStatus(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    // 可添加静态方法:fromValue(String value)
    public static OrderStatus fromValue(String value) {
        for (OrderStatus status : values()) {
            if (status.name().equalsIgnoreCase(value)) {
                return status;
            }
        }
        throw new IllegalArgumentException("未知订单状态:" + value);
    }
}

✅ 使用场景:

// Controller 层
@GetMapping("/orders")
public ResponseResult<List<OrderSummary>> getOrders(@RequestParam OrderStatus status) { ... }

// 前端
const statusMap = {
  PENDING_PAYMENT: "待支付",
  PAID: "已支付",
  ...
};

✅ 四、为什么这个结构是工业级标准?

特性说明
✅ 单一职责每个 DTO 只负责一个场景(列表/详情/请求)
✅ 语义清晰类名明确表达用途(UserBaseInfo vs UserInfo)
✅ 可复用1 个 DTO 被 5 个服务使用,减少重复代码
✅ 可测试单元测试可 Mock DTO,验证序列化是否正确
✅ 可生成文档SpringDoc 自动识别 @Schema,生成标准 OpenAPI
✅ 可生成前端代码可通过 Swagger Codegen 生成 TypeScript 接口
✅ 符合 DDDDTO 是应用层与表现层之间的契约,非实体
✅ 行业对标阿里、京东、美团均采用类似模式

✅ 五、最终建议:立即行动清单

步骤操作
✅ 1在 commons/ 下新建模块 commons-dto
✅ 2复制上述 pom.xml 和所有 Java 文件
✅ 3在 commons-dto/src/main/java/io/urbane/commons/dto/ 下按业务域建包
✅ 4为每个 DTO 添加 @Schema、@JsonInclude、Lombok 注解
✅ 5在所有业务服务(order、user、product…)的 pom.xml 中引入 commons-dto
✅ 6删除各服务中重复的 DTO 类
✅ 7在 api-gateway 中启用 springdoc,确保能扫描到 commons-dto 中的类型
✅ 8编写 README.md:“如何使用 commons-dto”
✅ 9在 GitLab CI 中加入 mvn test,确保打包正常
✅ 10通知前端团队:从此以后,所有接口模型请引用 commons-dto

📦 Bonus:我为你准备了完整 ZIP 模板包

如果你希望我为你提供:

  • ✅ 完整的 commons-dto 项目 ZIP(含所有 Java 文件、注释、pom.xml)
  • ✅ README.md 模板(团队使用指南)
  • ✅ OpenAPI 生成的 Swagger UI 截图示例
  • ✅ TypeScript 接口生成脚本(基于 swagger-codegen)
  • ✅ Postman Collection 导出模板(含 DTO 示例)
  • ✅ IDEA 插件推荐(Lombok、JSON to POJO)

👉 请回复:
“请给我完整的 commons-dto 模板包!”

我会立刻发送你一份开箱即用的企业级 DTO 统一架构方案,包含所有文件、注释、文档,你只需复制粘贴,即可让整个团队进入专业 API 开发时代 💪

微服务之间如何共享DTO? 近些年来,微服务变得越来越流行。微服务基本特征是模块化、独立、易于扩展的。它们之间需要协同工作并交换数据。为了实现这一点,我们创建了名为 DTO的共享数据传输对象。在本文中,我们将介绍在微服务之间共享DTO的方法。 使用微服务管理表示应用程序域的模型。域模型的关注点与DTO不同,我们将它们与DAO层中的数据模型分开。 这样做的主要原因是我们不想通过服务向客 立即下载

相关推荐

STM32与FreeRTOS:基于TIM6的高精度系统时间获取实践

本文详细介绍了在STM32与FreeRTOS环境下,基于TIM6定时器实现高精度系统时间获取的实践方法。通过复用FreeRTOS的TIM6硬件资源,开发者可以高效获取毫秒级和微秒级系统时间,同时解决时间溢出和中断处理等关键问题。文章还提供了CubeMX配置技巧、代码实现及性能优化建议,适用于嵌入式系统开发中的精确时间管理需求。

weixin_29169505的博客 357

微服务实体类命名规范

配合 VO, 提供数据库的 CRUD 操作.为了项目能够更清晰的分层,我们将不同的对象按照其功能进行划分,也就出现了各种各样的对象类型,在Java中常用的有这些:PO、DO、TO、VO、DO、DTO、DAO、POJO。2、个人理解,DTO是可以存在于各层服务中(接口、服务、数据库等等)服务间的交互使用DTO来解耦。3、个人理解使用场景,在服务层服务中,由DTO转成BO然后进行业务处理后,转成DTO返回到接口层。3、个人理解使用场景,在数据库层中,获取的数据库数据存储到PO中,然后转为DTO返回到服务层中。

weixin_69402201的博客 1165

西门子1500T系列凸轮同步(CAMIN指令用法)

添加凸轮工艺对象(TO_CAM),也就是凸轮表。开始编程,先写2个轴的使能、回原点与主轴的定位。监控主轴与从轴的位置、速度关系是否满足实验要求。1.添加工艺对象(1个定位轴,1个同步轴)调用CAMIN指令 ,凸轮耦合。主轴为旋转轴且为模数轴。3.调用插补凸轮盘指令。4.仿真、监控、调试。

gyxgyx789的博客 1万+

7、微服务中 DTO、VO、PO、BO 的设计规范

本文探讨了Java微服务架构中DTO、VO、PO、BO和Entity的概念区别与使用场景。核心结论强调DTO(数据传输对象)和VO(视图对象)必须独立存在,不能混用。DTO用于前端到后端的数据传输,包含完整请求字段;VO用于后端到前端的响应展示,需进行脱敏处理并仅包含必要信息。文章通过用户注册和登录场景的实例,对比了DTO和VO在字段数量、敏感信息处理等方面的差异。推荐在commons-dto模块中严格分离请求DTO和响应VO,并提供了标准的目录结构和代码示例,包括带有详细注释的RegisterReques

python15397的博客 1760

032、准谐振反激变换器(QR-Flyback)原理

文章摘要: 本文以65W PD快充炸管案例切入,解析准谐振反激变换器(QR-Flyback)原理。通过主动利用漏感与MOS结电容的谐振,在Vds波谷开通实现近似ZVS,显著降低开关损耗与电压应力。对比传统反激,QR模式轻载效率提升8%,Vds尖峰减少23%。关键设计要点包括:变压器漏感需<3%、谷底检测电路需抗干扰、启动阶段需防过冲。推荐NCP1340等专用控制芯片,并强调VCC电容优选低ESR陶瓷材质。QR适用于30W-150W场景,其核心优势在于轻载效率优化,但需平衡漏感控制与可靠性。作者结合实测数据与

Jack010169的博客 112

RK3566/RK3568 Android 11添加系统服务

【代码】RK3566/RK3568 Android 11添加系统服务。

qq_23921815的博客 641

【微服务】DTO与DMO

DTO与DMO

zhcf的博客 879

硬件学习手册【总目录】

欢迎大家来到《硬件学习手册》,专栏主要包括 《硬件经验手册》《电子元器件器件手册》《PCB手册》《CPU手册》《元器件选型手册》五个分册。在开始专栏的更新前,博主先列出专栏的大纲,以供大家参考。大家直接点击大纲中的蓝色标题即可轻松传送。

fydar的博客 5848

微服务架构下,DTO与VO分离的实战指南与模块化设计

本文深入探讨了微服务架构中DTO与VO分离的必要性及实战技巧,通过模块化设计和MapStruct工具提升开发效率。文章详细介绍了DTO/VO的设计规范、对象转换技巧及复杂场景处理方案,帮助开发者避免敏感数据泄露和维护性问题,优化微服务架构下的协作与性能。

weixin_30315723的博客 592

PHPStorm携手ThinkPHP8:开启高效开发之旅

本文围绕使用 PHPStorm 进行 ThinkPHP8 开发展开,先介绍开发环境搭建与 Xdebug 配置,再阐述 PHPStorm 集成 ThinkPHP8 的步骤,包括项目导入、解释器和服务器配置。还讲解了项目开发基础、数据库操作、高级技巧、调试处理及部署上线等内容,为开发者提供了从环境搭建到项目上线的完整指引,助力高效开展 ThinkPHP8 开发工作。

邓邓子的博客 1544

PX4实战(四):PX4 uorb模块详解

本节主要讲解PX4中的uorb消息,主要包括uorb的基本概念使用、PX4内重要的uorb消息、如何自定义uorb消息以及使用uorb消息的注意点等,其中讲解重要uorb消息是为了对PX4内重要数据结构有初步的了解,有助于后期算法理解。uORB(micro Object Request Broker)是PX4中用于模块间通信的轻量级发布-订阅(Publish/Subscribe)机制。模块之间可以通过uORB传递消息,无需直接调用对方函数;提高系统模块化与解耦性;

PX4-SLAM-PNC 1928

从模糊需求到精确蓝图:行为完整设计规范与AI辅助实践

在软件工程领域,设计规范是连接产品构想与代码实现的桥梁。其核心价值在于将模糊的需求转化为无歧义、可执行的技术指令,从而大幅降低沟通成本与返工风险。从概念上讲,一份优秀的设计规范应具备行为完整性,这意味着它需要明确定义系统的所有可能状态、输入输出以及异常处理流程,使其可直接转化为测试用例。在原理上,这通常通过结构化的用户故事、Given-When-Then格式的验收条件、精确的API契约以及完整的状态迁移图来实现。其技术价值体现在促进测试驱动开发(TDD)、提升团队协作效率以及作为自动化测试的可靠依据。在实际

weixin_34161032的博客 448

TRAE智能体开发:TRAE概述

TRAE(/treɪ/)深度融合 AI 能力,是一名能够理解需求、调用工具并独立完成各类开发任务的“AI 开发工程师”,帮助你高效推进每一个项目。

王国平的博客 1254

Java反射安全:框架开发与代码审计中的风险防范实践

反射机制作为Java语言的核心特性,允许程序在运行时动态检查和操作类、方法与字段,其原理是通过Class对象获取元数据并突破访问控制。这项技术为框架带来了极大的灵活性,是Spring依赖注入、Hibernate ORM等众多流行框架的技术基石,其核心价值在于实现解耦与动态扩展。然而,在Web应用、微服务等实际应用场景中,反射若使用不当,会直接破坏封装性,导致严重的安全边界崩塌。特别是在框架开发与代码审计领域,由反射引发的安全漏洞,如通过`setAccessible(true)`绕过权限控制进行敏感字段篡改,

473

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Spring Boot实战:构建高并发餐饮点餐收银一体化系统

在软件开发领域,单体应用架构与分层设计是构建稳健业务系统的经典范式。其核心原理在于通过清晰的职责分离,将表现层、业务逻辑层和数据访问层解耦,从而提升代码的可维护性与可扩展性。这一架构的技术价值在于,它能有效应对业务复杂度,并为后续的微服务化改造奠定基础。在餐饮、零售等线下实体行业,这类系统常被应用于解决订单处理、库存管理和收银对账等核心业务场景。本文将聚焦于如何利用Spring Boot框架,结合Spring Data JPA、Redis缓存及声明式事务管理,设计并实现一个能处理高并发订单、确保数据一致性的

weixin_34239169的博客 503

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Java & Spring Boot常见异常全解析:原因、危害、处理与防范

Java与Spring Boot常见异常处理指南 摘要:本文系统梳理了Java核心异常与Spring Boot框架特有异常类型,从产生原因、潜在危害、应急处理措施和防范方案四个维度进行深度解析。重点分析了NullPointerException、IndexOutOfBoundsException等运行时异常的典型场景,并提供了判空检查、Optional类、索引校验等实用解决方案。针对Spring Boot应用,详细介绍了参数校验异常、JSON处理异常等常见问题的处理方式,帮助开发者构建更健壮的异常处理机制,

深耕 Java 后端与企业级软件架构设计,专注微服务、分布式系统、大模型 AI 应用架构落地。 675

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Java深入了解DTO及如何使用DTO

看了几套源码,其中都有用到DTO,这篇文章主要来谈论一下DTO使用的场合及其带来的好处。 在传统的编程中,我们一般都是前台请求数据,发送到Webservice,然后WebService向数据库发出请求,获取数据,然后一层层返回;模型如下: 这种比较原始的请求方式带来的缺点有很多,多次 请求耗费一定的网络资源,减慢效率。如果一次性返回整个实体类,还可能造成数据库表结构的泄漏。 采用DTO模

Visant Blog 8万+

微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人...

微服务应用大行其道,我提供一个dto和entity转换工具类,方便大家做转换,少写机械代码,多陪陪家人。 该工具类主要是对dozer进行了封装,使用过程代码量极少,废话少说,贴代码了 import java.util.ArrayList; import java.util.List; i...

cif01854的博客 992

定义一个dto对象_如何跨微服务共享DTO

1. 概述近年来,微服务变得非常流行。微服务的基本特征之一是它们是模块化的、独立的、易于伸缩的。微服务需要一起工作并交换数据。为了实现这一点,我们创建一个称为dto的共享数据传输对象。在本文中,我们将介绍在微服务之间共享dto的方法。2. 将域对象暴露为DTO表示应用程序域的模型使用微服务进行管理。领域模型是不同的关注点,我们将它们与DAO层中的数据模型分离开来。这样做的主要原因是,我们不想通过服...

weixin_33539912的博客 1014

Java 和微服务,第 4 部分: 处理数据 JPA 反射

此内容是该系列的一部分: Java 和微服务,第 4 部分 在微服务系统中,具有混合持久性的环境时,有必要让数据处理保持可管理。为了解释如何实现此目标,本章会简要介绍微服务在数据处理方面的特征,然后介绍如何使用基于 Java 的微服务实现此目的。 微服务特定于数据的特征 识别数据的一种方式是自上而下的方法,数据必须存储在您的微服务的数据存储中。从业务级别开始建模您的数据。以下各节将介绍如何识

流年、你奈我何 1470

微服务调用:通过@FeignClient注解调用外部微服务接口

通过@FeignClient注解可以调用外部微服务接口 总共分为5步: 第一步:加载Jar包 第二步:新建一个Feign接口类( ClearBatchFeign.java),并且注明接口实现类 第三步:创建一个Feign接口实现类(ClearBatchFeignFallback.java),实现Feign接口, 需要加上注解@Component自动注入 第四步,定义DTO类...

qq1186907347的博客 1万+

从壹开始微服务 [ DDD ] 之八 ║剪不断理还乱的 值对象和Dto

缘起 哈喽大家周四好,时间是过的真快,这几天一直忙着在公司的项目,然后带带新人,眼看这周要过去了,还是要抽出时间学习学习,这些天看到群里的小伙伴也都在忙着新学习,还是很开心的,至少当时的初衷已经达到了,一起学习一起进步嘛,哪怕是对现在或者是对以后的工作有一丢丢的帮助,也是不枉此时的努力,哈哈夜里写文章总是容易多想,好啦,废话不多说,上次咱们说到了《从壹开始微服务 [ DDD ] 之七 ║项目第一...

weixin_30571465的博客 269

浅谈微服务-POJO

POJO的定义 按照阿里巴巴规范,是DTO,VO,BO等的统称。任何模型不许定义为***POJO。 实际模型 Entity 数据库 DTO 系统间传输对象 VO 页面显示对象 Result -> 一种特殊的DTO,用于定义服务间数据传输的包装类 Result 属性一般有:String code; String message; T data; Boolean success; 其中...

慎独的博客 1412

详解Java业务领域分层模型中的vo/po/dto/pojo/bo

O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写。 通俗点讲,就是将对象与关系数据库绑定,用对象来表示关系数据。 在O/R Mapping的世界里,有两个基本的也是重要的需要了解,即VO,PO。 VO,值对象(Value Object) PO,持久对象(Persisent Object) 它们是由一组属性及其get/set组成。从结构上看,它们并...

JavaEdge全是干货的技术号 4913
上一篇: commons-mybatis 工具模块设计规范
下一篇: @Valid 和 @Validated 两个数据校验的关键注解的区别和使用
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值