美团CPS分销接口开发中Java请求参数校验的优雅实现技巧 美团CPS分销接口开发中Java请求参数校验的优雅实现技巧在对接美团CPSCost Per Sale分销接口时上游系统或前端传入的参数可能存在缺失、格式错误或业务逻辑不合法等问题。若未做严格校验轻则导致接口异常重则引发佣金计算错误或数据污染。本文结合JSR-380Bean Validation 2.0、自定义注解与分组校验提供一套高内聚、低侵入的参数校验方案。1. 基础DTO与标准注解使用首先定义接收美团回调或调用其OpenAPI的DTO并使用javax.validation注解约束字段packagebaodanbao.com.cn.cps.dto;importjavax.validation.constraints.*;importjava.math.BigDecimal;publicclassMeituanOrderCreateRequest{NotBlank(message商户ID不能为空)privateStringmerchantId;Pattern(regexp^[A-Za-z0-9]{1,32}$,message订单号仅支持字母数字长度1-32)privateStringorderId;NotNull(message用户ID不可为空)Min(value10000,message用户ID需大于10000)privateLonguserId;NotNull(message订单金额不可为空)DecimalMin(value0.01,message订单金额至少0.01元)DecimalMax(value99999.99,message单笔订单金额不得超过99999.99元)privateBigDecimalorderAmount;Email(message通知邮箱格式不正确)privateStringnotifyEmail;// getters setters}2. 分组校验应对多场景复用同一DTO可能用于“创建订单”和“查询订单”两种接口所需字段不同。通过分组实现差异化校验packagebaodanbao.com.cn.cps.groups;publicinterfaceCreateGroup{}publicinterfaceQueryGroup{}在DTO中指定分组publicclassMeituanOrderRequest{NotBlank(groups{CreateGroup.class,QueryGroup.class})privateStringorderId;NotNull(groupsCreateGroup.class)DecimalMin(value0.01,groupsCreateGroup.class)privateBigDecimalamount;Min(value1,groupsQueryGroup.class)privateIntegerpageNum;// ...}Controller中触发对应分组校验packagebaodanbao.com.cn.cps.controller;importbaodanbao.com.cn.cps.dto.MeituanOrderRequest;importbaodanbao.com.cn.cps.groups.CreateGroup;importbaodanbao.com.cn.cps.groups.QueryGroup;importorg.springframework.validation.annotation.Validated;importorg.springframework.web.bind.annotation.*;RestControllerRequestMapping(/meituan/cps)publicclassMeituanCpsController{PostMapping(/order/create)publicStringcreateOrder(Validated(CreateGroup.class)RequestBodyMeituanOrderRequestreq){returnsuccess;}GetMapping(/order/list)publicStringlistOrders(Validated(QueryGroup.class)MeituanOrderRequestreq){returnsuccess;}}3. 自定义业务校验注解美团CPS要求某些字段组合满足特定规则例如“当订单类型为团购时必须包含团购券码”。此时需自定义校验器packagebaodanbao.com.cn.cps.validation;importjavax.validation.Constraint;importjavax.validation.Payload;importjava.lang.annotation.*;Target({ElementType.TYPE})Retention(RetentionPolicy.RUNTIME)Constraint(validatedByCouponCodeValidator.class)DocumentedpublicinterfaceValidCouponIfGroupBuy{Stringmessage()default团购订单必须提供有效券码;Class?[]groups()default{};Class?extendsPayload[]payload()default{};}实现校验逻辑packagebaodanbao.com.cn.cps.validation;importbaodanbao.com.cn.cps.dto.MeituanOrderCreateRequest;importjavax.validation.ConstraintValidator;importjavax.validation.ConstraintValidatorContext;publicclassCouponCodeValidatorimplementsConstraintValidatorValidCouponIfGroupBuy,MeituanOrderCreateRequest{OverridepublicbooleanisValid(MeituanOrderCreateRequestrequest,ConstraintValidatorContextcontext){if(GROUP_BUY.equals(request.getOrderType())){returnrequest.getCouponCode()!null!request.getCouponCode().trim().isEmpty();}returntrue;// 非团购订单无需校验}}在DTO上使用ValidCouponIfGroupBuypublicclassMeituanOrderCreateRequest{privateStringorderType;// NORMAL / GROUP_BUYprivateStringcouponCode;// other fields...}4. 全局异常处理统一返回格式捕获MethodArgumentNotValidException并返回结构化错误信息packagebaodanbao.com.cn.cps.exception;importorg.springframework.http.HttpStatus;importorg.springframework.validation.FieldError;importorg.springframework.web.bind.MethodArgumentNotValidException;importorg.springframework.web.bind.annotation.ExceptionHandler;importorg.springframework.web.bind.annotation.ResponseStatus;importorg.springframework.web.bind.annotation.RestControllerAdvice;importjava.util.HashMap;importjava.util.Map;RestControllerAdvicepublicclassValidationExceptionHandler{ExceptionHandler(MethodArgumentNotValidException.class)ResponseStatus(HttpStatus.BAD_REQUEST)publicMapString,StringhandleValidationExceptions(MethodArgumentNotValidExceptionex){MapString,StringerrorsnewHashMap();ex.getBindingResult().getAllErrors().forEach((error)-{StringfieldName((FieldError)error).getField();StringerrorMessageerror.getDefaultMessage();errors.put(fieldName,errorMessage);});returnerrors;}}5. 手动触发校验适用于非Controller场景在Service层或消息消费中可手动校验对象packagebaodanbao.com.cn.cps.service;importbaodanbao.com.cn.cps.dto.MeituanOrderCreateRequest;importorg.springframework.stereotype.Service;importjavax.validation.ConstraintViolation;importjavax.validation.Validation;importjavax.validation.Validator;importjavax.validation.ValidatorFactory;importjava.util.Set;ServicepublicclassOrderValidationService{privatefinalValidatorvalidator;publicOrderValidationService(){ValidatorFactoryfactoryValidation.buildDefaultValidatorFactory();this.validatorfactory.getValidator();}publicvoidvalidate(MeituanOrderCreateRequestrequest){SetConstraintViolationMeituanOrderCreateRequestviolationsvalidator.validate(request);if(!violations.isEmpty()){StringBuildersbnewStringBuilder();for(ConstraintViolationMeituanOrderCreateRequestviolation:violations){sb.append(violation.getPropertyPath()).append(: ).append(violation.getMessage()).append(; );}thrownewIllegalArgumentException(sb.toString());}}}本文著作权归 俱美开放平台 转载请注明出处

相关新闻

最新新闻

SerenityOS 命令行选项解析指南:getopt 与 getopt_long 用法、返回值与底层实现

SerenityOS 命令行选项解析指南:getopt 与 getopt_long 用法、返回值与底层实现

SerenityOS 命令行选项解析指南:getopt 与 getopt_long 用法、返回值与底层实现 【免费下载链接】serenity The Serenity Operating System 🐞 项目地址: https://gitcode.com/GitHub_Trending/se/serenity 导读 本文以 getopt(3) 手册 为核心&a…

2026/9/25 12:45:43
轻量服务器还是ECS?大促云服务器选购与避坑实战指南

轻量服务器还是ECS?大促云服务器选购与避坑实战指南

每年大促节点,群里永远有人在问同一个问题:“38元的轻量服务器到底怎么抢?为什么我每次点进去都是已售罄?68元直购和99元的ECS我到底选哪个?”作为一个常年帮团队和自己采购云服务器的老用户,我太清楚这种纠…

2026/9/24 14:25:52
为 AI 代理的 Review 动作编写 Cedar 审批门控策略:review-agent-governance 策略编写实战指南

为 AI 代理的 Review 动作编写 Cedar 审批门控策略:review-agent-governance 策略编写实战指南

为 AI 代理的 Review 动作编写 Cedar 审批门控策略:review-agent-governance 策略编写实战指南 【免费下载链接】agents Multi-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity 项目地址:…

2026/9/24 14:49:33
PaddleOCR 手写数学公式识别算法 CAN 实战指南:Counting-Aware Network 训练、评估与推理部署

PaddleOCR 手写数学公式识别算法 CAN 实战指南:Counting-Aware Network 训练、评估与推理部署

PaddleOCR 手写数学公式识别算法 CAN 实战指南:Counting-Aware Network 训练、评估与推理部署 【免费下载链接】PaddleOCR Turn any PDF or image document into structured data for your AI. A powerful, lightweight OCR toolkit that bridges the gap between i…

2026/9/23 8:01:38
Spring源码解析:构造器注入的类型转换与候选匹配机制

Spring源码解析:构造器注入的类型转换与候选匹配机制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 14:28:18
openai-agents-python 多模型接入指南:深入解析 AnyLLMModel 适配层与 any-llm 路由

openai-agents-python 多模型接入指南:深入解析 AnyLLMModel 适配层与 any-llm 路由

openai-agents-python 多模型接入指南:深入解析 AnyLLMModel 适配层与 any-llm 路由 【免费下载链接】openai-agents-python A lightweight, powerful framework for multi-agent workflows 项目地址: https://gitcode.com/GitHub_Trending/op/openai-agents-pyth…

2026/9/25 15:49:36

日新闻

周新闻