国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

在 Spring Boot 中使用 JSON Schem 實現復雜對象、可變結構參數校驗!

開發 前端
聲明式?的 JSON Schema 把“數據結構約束”從業務代碼中抽離,使得?接口契約?與?實現?分離,降低了后期變更的風險。統一的校驗入口(如自定義注解 + 參數解析器)讓所有入口點的校驗行為保持一致,避免遺漏。

1. 為什么要在 Spring Boot 中使用 JSON Schem進行校驗

1.1 傳統校驗方式的局限

? 手寫 POJO + @Valid:只能校驗映射到 Java 對象的字段,面對 深層嵌套、可變結構(如數組中對象字段不統一)時往往需要大量的自定義 DTO 與轉換代碼。

? 手動解析 + if 判斷:代碼冗余、易遺漏、錯誤信息不統一,維護成本隨業務增長呈指數級上升。

1.2 JSON Schema 的優勢

優勢

說明

聲明式

通過 JSON 文檔描述結構、約束、默認值,業務代碼無需關心細節。

可組合

支持 $ref 引用、allOf/anyOf/oneOf 組合,能夠復用公共子結構。

跨語言

同一套 Schema 可在前端、后端、測試腳本等多端共享,保證全鏈路一致性。

錯誤定位精準

校驗器會返回錯誤路徑(JSON Pointer),便于快速定位問題字段。

可擴展

支持自定義關鍵字,滿足業務特有的校驗需求(如唯一性、業務規則校驗)。

在微服務架構中,接口契約往往以 JSON Schema 形式保存于 API 文檔中心(如 Swagger、OpenAPI),將其直接用于運行時校驗是最自然的落地方式。

2. JSON Schema 基礎概念與核心關鍵字

2.1 基本結構

{
  "$schema":"http://json-schema.org/draft-07/schema#",
"title":"用戶信息",
"type":"object",
"properties":{
    "id":   {"type":"integer","minimum":1},
    "name":{"type":"string","minLength":1},
    "email":{"type":"string","format":"email"},
    "roles":{
      "type":"array",
      "items":{"type":"string","enum":["ADMIN","USER","GUEST"]},
      "minItems":1,
      "uniqueItems":true
    }
},
"required":["id","name","email"]
}

? type:限定數據類型(object、array、string、number、boolean、null)。

? properties:對象屬性的子 Schema。

? required:必須出現的屬性列表。

? enum:枚舉值集合。

? format:預定義格式(email、date-time、uri 等)。

2.2 常用關鍵字速查

關鍵字

作用

示例

minimum

 / maximum

數值范圍

"minimum": 0

exclusiveMinimum

 / exclusiveMaximum

開區間

"exclusiveMinimum": 0

minLength

 / maxLength

字符串長度

"minLength": 3

pattern

正則匹配

"pattern": "^[A-Z]{3}\\d{4}$"

minItems

 / maxItems

數組元素個數

"minItems": 1

uniqueItems

數組元素唯一性

"uniqueItems": true

additionalProperties

是否允許未聲明屬性

"additionalProperties": false

dependencies

屬性間依賴

"dependencies": { "creditCard": ["billingAddress"] }

allOf

 / anyOf / oneOf / not

組合約束

"allOf": [{...}, {...}]

$ref

引用外部或內部 Schema

"$ref": "#/definitions/Address"

default

默認值(僅在生成時有意義)

"default": "UNKNOWN"

2.3 版本兼容性

? Draft-07 是目前最廣泛支持的版本,幾乎所有 Java 校驗庫均兼容。

? 若項目需要 2020?12 或 2023?09 的新特性(如 unevaluatedProperties),需要確認所選庫已實現對應草案。

3. Spring Boot 項目準備與依賴選型

3.1 項目結構(示例)

src/main/java
 └─ com.example.demo
      ├─ controller
      ├─ service
      ├─ validator   // 自定義校驗器
      └─ config      // Spring 配置
src/main/resources
 └─ schemas
      └─ user-schema.json

3.2 主流 JSON Schema 校驗庫對比

Maven 坐標

主要特性

備注

NetworkNT json-schema-validator

com.networknt:json-schema-validator

完全實現 Draft?07、支持 $ref、自定義關鍵字、緩存

社區活躍,文檔完整

Everit JSON Schema

org.everit.json:org.everit.json.schema

輕量、異常信息友好、支持 Draft?07

依賴 org.json

Justify

org.leadpony.justify:justify

支持 Draft?07、流式校驗、低內存占用

適合大文件校驗

Jackson-module-jsonSchema

com.fasterxml.jackson.module:jackson-module-jsonSchema

與 Jackson 緊耦合、生成 Schema 為主

生成能力強,校驗功能相對弱

推薦:在 Spring Boot 項目中使用 NetworkNT,因為它提供了 JsonSchemaFactory、Validator、ValidationMessage 等易于集成的 API,并且對 $ref 的解析支持良好。

3.3 Maven 依賴示例

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- JSON Schema Validator (NetworkNT) -->
    <dependency>
        <groupId>com.networknt</groupId>
        <artifactId>json-schema-validator</artifactId>
        <version>1.0.86</version>
    </dependency>

    <!-- Jackson (已隨 Spring Boot 引入) -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>

    <!-- Lombok(可選) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

注意:json-schema-validator 依賴 jackson-databind 進行 JSON 讀取,確保版本兼容。

4. 基于 json-schema-validator(NetworkNT)實現自動校驗

4.1 加載 Schema

package com.example.demo.config;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.InputStream;

@Configuration
publicclassJsonSchemaConfig {

    privatefinalObjectMappermapper=newObjectMapper();

    /** 讀取 classpath 下的 schema 文件并返回 JsonSchema 實例 */
    @Bean
    public JsonSchema userSchema()throws Exception {
        try (InputStreamis= getClass().getResourceAsStream("/schemas/user-schema.json")) {
            JsonNodeschemaNode= mapper.readTree(is);
            JsonSchemaFactoryfactory= JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7))
                    .objectMapper(mapper)
                    .build();
            return factory.getSchema(schemaNode);
        }
    }
}

? SpecVersion.VersionFlag.V7 指定使用 Draft?07。

? 通過 @Bean 將 JsonSchema 注入 Spring 容器,后續可直接 @Autowired 使用。

4.2 編寫校驗工具類

package com.example.demo.validator;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.ValidationMessage;
import org.springframework.stereotype.Component;

import java.util.Set;

@Component
publicclassJsonValidator {

    privatefinalObjectMappermapper=newObjectMapper();

    /** 校驗 JSON 字符串是否符合給定的 Schema,返回錯誤集合 */
    public Set<ValidationMessage> validate(String json, JsonSchema schema)throws Exception {
        JsonNodenode= mapper.readTree(json);
        return schema.validate(node);
    }

    /** 將錯誤集合轉為統一的錯誤信息字符串(可自行改造為錯誤對象) */
    public String formatErrors(Set<ValidationMessage> errors) {
        StringBuildersb=newStringBuilder();
        for (ValidationMessage msg : errors) {
            sb.append("路徑 ").append(msg.getPath())
              .append(" : ").append(msg.getMessage())
              .append("; ");
        }
        return sb.toString();
    }
}

? ValidationMessage#getPath() 返回 JSON Pointer(如 /roles/0),幫助前端定位。

? validate 方法拋出異常僅用于 JSON 解析錯誤,業務校驗錯誤通過返回集合處理。

4.3 在 Controller 中使用

package com.example.demo.controller;

import com.example.demo.validator.JsonValidator;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.ValidationMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Set;

@RestController
@RequestMapping("/api/users")
publicclassUserController {

    @Autowired
    private JsonSchema userSchema;          // 注入的 Schema Bean

    @Autowired
    private JsonValidator validator;       // 校驗工具

    @PostMapping
    public ResponseEntity<?> createUser(@RequestBody String rawJson) {
        try {
            Set<ValidationMessage> errors = validator.validate(rawJson, userSchema);
            if (!errors.isEmpty()) {
                // 返回 400 并附帶錯誤詳情
                return ResponseEntity.badRequest()
                        .body(validator.formatErrors(errors));
            }

            // 業務處理:將 JSON 反序列化為 POJO、持久化等
            // User user = objectMapper.readValue(rawJson, User.class);
            // userService.save(user);

            return ResponseEntity.ok("校驗通過,業務處理完成");
        } catch (Exception e) {
            // JSON 解析異?;蚱渌麅炔垮e誤
            return ResponseEntity.status(500).body("服務器內部錯誤:" + e.getMessage());
        }
    }
}

? 核心思路:把原始請求體保留為字符串,先交給校驗器;只有在校驗通過后才進行業務層的對象映射與持久化。

? 這樣可以 避免因反序列化錯誤導致的異常泄露,并且錯誤信息直接對應 JSON Schema 定義。

5. 自定義關鍵字與擴展校驗邏輯

5.1 業務場景示例

假設業務要求 用戶名在同一租戶內唯一,這屬于跨記錄的業務規則,JSON Schema 本身不提供此類校驗。我們可以通過 自定義關鍵字 uniqueInTenant 來實現。

5.2 實現自定義關鍵字

package com.example.demo.config;

import com.networknt.schema.*;
import com.networknt.schema.keyword.Keyword;
import com.networknt.schema.keyword.KeywordFactory;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Set;

/** 自定義關鍵字工廠 */
@Component
publicclassCustomKeywordFactoryimplementsKeywordFactory {

    @Override
    public Set<String> getKeywords() {
        return Collections.singleton("uniqueInTenant");
    }

    @Override
    public Keyword createKeyword(String keyword, JsonNode node) {
        returnnewUniqueInTenantKeyword(node);
    }

    /** 關鍵字實現類 */
    staticclassUniqueInTenantKeywordimplementsKeyword {
        privatefinal JsonNode schemaNode;

        UniqueInTenantKeyword(JsonNode schemaNode) {
            this.schemaNode = schemaNode;
        }

        @Override
        public ValidationResult validate(JsonNode node, JsonNode rootNode, String at) {
            // 這里的 node 為待校驗的字段值(如 username)
            Stringusername= node.asText();
            // 假設有一個租戶 ID 已經在上下文中獲取
            StringtenantId= ValidationContext.getCurrentTenantId();

            // 調用業務服務檢查唯一性(這里用偽代碼演示)
            booleanexists= UserService.isUsernameExistsInTenant(username, tenantId);
            if (exists) {
                return ValidationResult.error(at, "用戶名在當前租戶內已存在");
            }
            return ValidationResult.ok();
        }

        @Override
        public String getKeyword() {
            return"uniqueInTenant";
        }
    }
}

5.3 將自定義關鍵字注冊到 Factory

@Bean
public JsonSchemaFactory jsonSchemaFactory(ObjectMapper mapper, CustomKeywordFactory customFactory) {
    return JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7))
            .objectMapper(mapper)
            .addKeyword(customFactory)   // 注冊自定義關鍵字
            .build();
}

5.4 在 Schema 中使用

{
  "$schema":"http://json-schema.org/draft-07/schema#",
"title":"用戶注冊",
"type":"object",
"properties":{
    "username":{
      "type":"string",
      "minLength":3,
      "uniqueInTenant":true   // 自定義關鍵字
    },
    "password":{
      "type":"string",
      "minLength":8
    }
},
"required":["username","password"]
}

注意:自定義關鍵字的實現必須是 無副作用 的純函數式校驗,否則可能導致并發安全問題。

6. 全局異常處理與錯誤信息統一返回

6.1 統一錯誤響應結構

{
  "timestamp":"2025-10-11T14:23:45.123+08:00",
"status":400,
"error":"Bad Request",
"message":"請求參數校驗失敗",
"details":[
    {"path":"/email","msg":"必須是合法的 email 地址"},
    {"path":"/roles/0","msg":"不允許的枚舉值"}
]
}

6.2 實現 @ControllerAdvice

package com.example.demo.exception;

import com.networknt.schema.ValidationMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.ZonedDateTime;
import java.util.List;
import java.util.stream.Collectors;

@RestControllerAdvice
publicclassGlobalExceptionHandler {

    @ExceptionHandler(ValidationException.class)
    public ResponseEntity<ErrorResponse> handleValidation(ValidationException ex) {
        List<FieldError> fieldErrors = ex.getErrors().stream()
                .map(v -> newFieldError(v.getPath(), v.getMessage()))
                .collect(Collectors.toList());

        ErrorResponseresp=newErrorResponse(
                ZonedDateTime.now(),
                HttpStatus.BAD_REQUEST.value(),
                "Bad Request",
                "請求參數校驗失敗",
                fieldErrors
        );
        returnnewResponseEntity<>(resp, HttpStatus.BAD_REQUEST);
    }

    // 其它異常統一處理...
}

/** 自定義異常包裝 ValidationMessage 集合 */
classValidationExceptionextendsRuntimeException {
    privatefinal Set<ValidationMessage> errors;
    publicValidationException(Set<ValidationMessage> errors) {
        this.errors = errors;
    }
    public Set<ValidationMessage> getErrors() { return errors; }
}

/** 錯誤響應 DTO */
recordErrorResponse(
        ZonedDateTime timestamp,
        int status,
        String error,
        String message,
        List<FieldError> details) {}

recordFieldError(String path, String msg) {}

6.3 在業務層拋出統一異常

Set<ValidationMessage> errors = validator.validate(rawJson, userSchema);
if (!errors.isEmpty()) {
    throw new ValidationException(errors);
}

這樣,所有校驗錯誤都會統一走 GlobalExceptionHandler,前端只需要解析一次統一結構即可。

7. 在 Controller 中使用校驗注解的完整示例

7.1 定義自定義注解

package com.example.demo.annotation;

import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public@interface JsonValidated {
    /** 指定使用的 Schema Bean 名稱 */
    @AliasFor("value")
    String schema()default"";

    @AliasFor("schema")
    String value()default"";
}

7.2 實現參數解析攔截器

package com.example.demo.resolver;

import com.example.demo.annotation.JsonValidated;
import com.example.demo.exception.ValidationException;
import com.example.demo.validator.JsonValidator;
import com.networknt.schema.JsonSchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.*;
import org.springframework.web.method.support.*;

import java.util.Set;

@Component
publicclassJsonValidatedArgumentResolverimplementsHandlerMethodArgumentResolver {

    @Autowired
    private JsonValidator validator;

    @Autowired
    private ApplicationContext ctx;   // 用于獲取 Schema Bean

    @Override
    publicbooleansupportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(JsonValidated.class)
                && parameter.getParameterType().equals(String.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory)throws Exception {

        JsonValidatedann= parameter.getParameterAnnotation(JsonValidated.class);
        StringschemaBeanName= ann.schema();
        JsonSchemaschema= (JsonSchema) ctx.getBean(schemaBeanName);

        Stringbody= webRequest.getNativeRequest(HttpServletRequest.class)
                .getReader()
                .lines()
                .reduce("", (acc, line) -> acc + line);

        Set<ValidationMessage> errors = validator.validate(body, schema);
        if (!errors.isEmpty()) {
            thrownewValidationException(errors);
        }
        return body;   // 校驗通過后返回原始 JSON 字符串
    }
}

7.3 注冊解析器

@Configuration
publicclassWebConfigimplementsWebMvcConfigurer {

    @Autowired
    private JsonValidatedArgumentResolver jsonResolver;

    @Override
    publicvoidaddArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(jsonResolver);
    }
}

7.4 使用示例

@PostMapping("/register")
public ResponseEntity<?> register(@JsonValidated("userSchema") String userJson) {
    // 此時 userJson 已經通過 userSchema 校驗
    // 直接反序列化業務對象
    UserDto dto = objectMapper.readValue(userJson, UserDto.class);
    userService.register(dto);
    return ResponseEntity.ok("注冊成功");
}

通過自定義注解 + 參數解析器,校驗邏輯與業務代碼徹底解耦,控制器只關心業務本身。

8. 單元測試與集成測試最佳實踐

8.1 單元測試校驗工具

@SpringBootTest
classJsonValidatorTest {

    @Autowired
    private JsonValidator validator;

    @Autowired
    @Qualifier("userSchema")
    private JsonSchema schema;

    @Test
    voidvalidJsonShouldPass()throws Exception {
        Stringjson="""
        {
          "id": 10,
          "name": "張三",
          "email": "zhangsan@example.com",
          "roles": ["ADMIN"]
        }
        """;
        Set<ValidationMessage> errors = validator.validate(json, schema);
        assertTrue(errors.isEmpty());
    }

    @Test
    voidinvalidJsonShouldReturnErrors()throws Exception {
        Stringjson="""
        {
          "id": -1,
          "name": "",
          "email": "not-an-email",
          "roles": []
        }
        """;
        Set<ValidationMessage> errors = validator.validate(json, schema);
        assertFalse(errors.isEmpty());
        // 斷言具體錯誤路徑
        assertTrue(errors.stream().anyMatch(v -> v.getPath().equals("$.id")));
        assertTrue(errors.stream().anyMatch(v -> v.getPath().equals("$.email")));
    }
}

8.2 集成測試 Controller

@AutoConfigureMockMvc
@SpringBootTest
classUserControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    voidcreateUserWhenInvalidShouldReturn400()throws Exception {
        Stringpayload="""
        {
          "id": 0,
          "name": "",
          "email": "bad",
          "roles": ["UNKNOWN"]
        }
        """;

        mvc.perform(post("/api/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(payload))
           .andExpect(status().isBadRequest())
           .andExpect(jsonPath("$.details[?(@.path=='/email')].msg")
                     .value("must be a valid email address"));
    }
}

? 使用 MockMvc 可以完整走一遍 請求 → 校驗 → 異常處理 → 響應 流程,確保錯誤信息的結構與內容符合約定。

9. 性能考量與緩存策略

9.1 Schema 加載成本

? 一次性加載:在啟動階段把所有 Schema 讀取為 JsonSchema 對象并放入 Spring 容器(如前文 @Bean),后續直接復用,避免每次請求重新解析。

? 緩存 JsonSchema:JsonSchemaFactory 本身提供內部緩存(基于 $id),但顯式緩存可以更好控制生命周期。

9.2 校驗過程的 CPU 與內存占用

? CPU:校驗本質是遍歷 JSON 樹并匹配關鍵字,復雜度與 JSON 大小呈線性關系。對大文件(>10?MB)建議使用 流式校驗(Justify)或分塊校驗。

? 內存:ObjectMapper.readTree 會把整個 JSON 讀取為樹結構,若業務只需要校驗而不需要后續對象映射,可在校驗后直接丟棄樹對象,減輕 GC 壓力。

9.3 并發場景下的優化

場景

優化手段

高并發短請求

采用 線程安全的 ObjectMapper(Spring Boot 默認已配置),避免每次創建實例。

大批量數據校驗

使用 批量緩存:一次性校驗一個數組,返回每條記錄的錯誤集合,減少線程切換。

多租戶環境

將租戶相關的自定義關鍵字實現 無狀態,通過 ThreadLocal 傳遞租戶上下文,避免在校驗器內部進行 I/O 查詢。

10. 進階特性:條件校驗、動態模式、格式化校驗

10.1 條件校驗(if/then/else)

{
  "type":"object",
"properties":{
    "type":{"enum":["PERSON","COMPANY"]},
    "personInfo":{"$ref":"#/definitions/person"},
    "companyInfo":{"$ref":"#/definitions/company"}
},
"required":["type"],
"if":{
    "properties":{"type":{"const":"PERSON"}}
},
"then":{
    "required":["personInfo"]
},
"else":{
    "required":["companyInfo"]
},
"definitions":{
    "person":{"type":"object","properties":{"name":{"type":"string"}}},
    "company":{"type":"object","properties":{"name":{"type":"string"}}}
}
}

? if/then/else 讓同一對象在不同業務分支下擁有不同必填字段,極大提升 單一 Schema 的表達能力。

10.2 動態模式(patternProperties)

{
  "type":"object",
"patternProperties":{
    "^prop_[0-9]+$":{"type":"string"}
},
"additionalProperties":false
}

? 適用于 鍵名可變、但鍵值類型統一的場景(如動態屬性表、標簽集合)。

10.3 自定義格式(format)

JSON Schema 預定義的 format 包括 email、date-time、uri 等。若業務需要 手機號、身份證號 等自定義格式,可通過 自定義 FormatValidator 注入到 JsonSchemaFactory:

JsonSchemaFactory factory = JsonSchemaFactory.builder()
        .formatValidator("phone", value -> 
            Pattern.matches("^1[3-9]\\d{9}$", value) ? Optional.empty()
                                                   : Optional.of("不是合法的手機號"))
        .build();

隨后在 Schema 中使用:

{
  "type": "string",
  "format": "phone"
}

11. 常見問題排查與調優技巧

問題

可能原因

解決方案

校驗報 null 指針

JSON 讀取為 null(空請求體)或 Schema 中 type 與實際不匹配

在 Controller 首先判斷請求體是否為空;在 Schema 明確 type 為 null 時使用 nullable:true(Draft?07 通過 type 數組實現)。

錯誤路徑不準確

使用了 additionalProperties:false 并在子對象中出現未聲明字段

將 additionalProperties:true 或在子對象中添加 patternProperties 捕獲動態字段。

自定義關鍵字不生效

未把自定義 KeywordFactory 注入到 JsonSchemaFactory

確認 JsonSchemaFactory 的構造器已調用 addKeyword(customFactory),并且 Bean 已被 Spring 管理。

性能瓶頸在 JSON 解析

大文件每次都完整讀取為樹結構

改用 流式校驗(Justify)或 分塊讀?。↗ackson JsonParser)配合 Validator 的 validate(JsonParser) 方法。

多租戶唯一校驗失效

ValidationContext

 中租戶信息未正確傳遞

使用 ThreadLocal 或 Spring RequestContextHolder 在攔截器層面注入租戶 ID,確保自定義關鍵字能夠獲取到。

錯誤信息中文亂碼

ValidationMessage

 默認使用英文描述

在 JsonSchemaFactory 中通過 Locale 參數或自行翻譯 ValidationMessage#getMessage()。

12. 結語:讓 JSON 校驗成為項目的安全防線

? 聲明式 的 JSON Schema 把“數據結構約束”從業務代碼中抽離,使得 接口契約 與 實現 分離,降低了后期變更的風險。

? 統一的校驗入口(如自定義注解 + 參數解析器)讓所有入口點的校驗行為保持一致,避免遺漏。

? 自定義關鍵字 與 格式校驗 能夠把業務規則直接嵌入 Schema,進一步提升系統的防御能力。

? 通過 緩存、流式校驗 與 錯誤信息統一化,我們可以在保持高吞吐的同時,提供友好的錯誤反饋。

責任編輯:武曉燕 來源: JAVA日知錄
相關推薦

2024-08-06 11:17:58

SpringJSON數據

2021-08-10 15:11:27

Spring Boot參數校驗

2021-08-12 10:32:50

Spring Boot參數校驗分組校驗

2023-11-26 09:10:34

WebSocketgreeting?在線用戶

2022-02-08 17:07:54

Spring BooSpring Aop日志記錄

2023-07-17 18:42:47

gRPCDemo項目

2025-05-27 07:07:29

2010-01-05 16:33:35

使用JSON

2011-05-25 13:22:05

PHPJSON

2023-03-30 07:48:46

接口鑒權SpringBoot

2009-06-15 16:23:39

Eclipse中使用SEclipse RCP

2022-11-10 07:53:54

Spring參數校驗

2022-07-26 16:54:08

QuartzJava

2024-12-03 08:00:00

2011-03-11 09:20:35

jQueryjavascript

2024-09-05 09:35:58

CGLIBSpring動態代理

2023-03-09 12:04:38

Spring文件校驗

2023-09-27 08:14:56

2024-11-01 10:40:32

2017-12-27 15:16:35

Spring BootFlyway數據庫
點贊
收藏

51CTO技術棧公眾號

成人a在线观看| 亚洲第一男人av| 亚洲精品欧美精品| 一本精品一区二区三区| 色多多国产成人永久免费网站| www.亚洲免费| 中文字幕精品一区| 路边理发店露脸熟妇泻火| 亚洲欧美网站| 成人免费在线看片| 不卡一区综合视频| 国产精品九九久久久久久久| 岛国成人av| 久久久久久久久久av| 日本少妇精品亚洲第一区| 伊人久久五月天| 羞羞影院欧美| 亚洲欧美精品伊人久久| 日本三级在线观看网站| 7777精品伊人久久久大香线蕉| 青青草免费观看免费视频在线| 一区二区欧美久久| 视频一区视频二区在线观看| 国产深夜精品福利| 国产精品色婷婷视频| 深夜福利在线视频| 亚洲视频在线观看一区| 男人女人黄一级| 久久夜色精品一区| 人人爽人人av| 久久蜜桃一区二区| 国产第一亚洲| 午夜大尺度福利视频| 日韩欧美午夜| 国产精品美女免费| 国产精品一区二区三区av麻| 高清欧美性猛交xxxx黑人猛交| 亚洲18在线| 欧美激情图片区| 欧美一性一交| 国产精品第一第二| 欧美va天堂在线| 好吊妞www.84com只有这里才有精品| 欧美aaaa视频| 国产伦精品一区二区三区照片91 | 欧洲美女7788成人免费视频| 亚洲精品天堂| 日韩欧美成人激情| 成人免费一区二区三区牛牛| 亚洲欧美日本另类| 88久久精品| 国产区亚洲区欧美区| 一本久道久久久| 国产一级不卡视频| 亚洲视频免费看| jyzzz在线观看视频| 亚洲精品之草原avav久久| 国产aⅴ精品一区二区四区| 青青草精品毛片| 国产精品日韩精品欧美精品| 国产夫妻自拍一区| 亚洲成人动漫精品| 超碰91在线观看| 91成人天堂久久成人| 国产一区二区三区的电影| 久久国产亚洲精品无码| 色网综合在线观看| 九七电影院97理论片久久tvb| 欧美在线视频网| 久久亚洲综合| 日韩不卡一二三| 日韩一区二区在线观看| 在线精品自拍| 欧美一级爽aaaaa大片| 中文字幕精品在线不卡| 激情成人四房播| 久久久久久久久久久网站| 欧美伊人久久| 黄色aaa级片| 欧美大片顶级少妇| 色棕色天天综合网| 最近中文字幕免费mv| 久久婷婷五月综合色丁香| 九九热r在线视频精品| 香蕉久久网站| 久久影院100000精品| 成年人在线免费观看| 欧美tk—视频vk| 日韩一区二区三区高清在线观看| 国产精品久久久久高潮| 久久久水蜜桃av免费网站| 国产主播中文字幕| 欧美一区二区在线视频| 666精品在线| 伊人久久大香线蕉精品| 国产一区二区精品久久99| av网站在线不卡| 日韩西西人体444www| 成人免费av电影| 午夜在线精品| 国产亚洲精品91在线| 欧美成人黑人| 性色av一区二区三区| 日本一二区不卡| 国产极品粉嫩福利姬萌白酱| 亚洲精品福利免费在线观看| 欧美视频三区在线播放| 91成人精品视频| 人猿泰山h版在线观看| 欧美性bbwbbwbbwhd| 欧美日韩国产丝袜另类| 国产日韩三级| 国产在线天堂www网在线观看| 一区在线观看| a级片国产精品自在拍在线播放| 午夜视频精品| 亚洲最大免费| 国产日韩欧美一区二区三区综合| 黄网站色大毛片| 欧洲精品视频在线观看| 久久99在线观看| 国产精品果冻传媒潘| 久久精品一区二区三区不卡| 欧美性猛片xxxxx免费中国 | 97成人精品视频在线观看| 免费成人你懂的| 国产大学生校花援交在线播放| 91国内揄拍国内精品对白| 91在线观看高清| 高清av一区| www.xxx麻豆| 在线午夜精品自拍| 成人av手机在线观看| 国产精品久久久久久妇女| 国产美女在线一区| 最近中文字幕2019免费| 成人sese在线| 91成人入口| 午夜视频国产| 亚洲一区二区在线播放| 日本韩国视频一区二区| 激情综合视频| 色婷婷在线播放| 国产女人18毛片| 久久影院资源网| 自拍偷拍国产精品| 日产午夜精品一线二线三线| 中文乱码字幕高清在线观看| 国产精品老女人精品视频| 婷婷丁香激情综合| 亚洲精品乱码久久久久久蜜桃麻豆| 麻豆视频在线播放| 亚洲一区二区高清视频| 中文字幕日韩精品在线| 26uuu另类欧美亚洲曰本| 老牛影视av一区二区在线观看| 九九久久99| 91九色精品视频| 最新国产精品拍自在线播放 | 亚洲精品国产福利| 蜜桃视频第一区免费观看| 黄色大片在线| 蜜臀av性久久久久蜜臀av| 中文字幕一区电影| 久久精品亚洲一区二区三区浴池 | 欧美高清日韩| 欧美精品videossex少妇| 91黄色在线看| 日本精品视频在线观看| 欧美日韩一区二区在线视频| 视频一区中文字幕| 精品中文在线| 青青草免费在线| 中文字幕欧美日韩一区二区三区| 日韩中文在线观看| 一区二区三区国产精品| 乱人伦精品视频在线观看| 精品国产一级| 二区在线观看| 男人和女人啪啪网站| 91免费看国产| 尤物yw午夜国产精品视频明星| 国产精品亲子伦对白| 亚洲美女视频在线免费观看| 国产成人精品一区二区三区免费 | 天天综合视频在线观看| 丁香六月激情婷婷| 亚洲精品欧美日韩专区| 亚洲伦理中文字幕| 精品久久久中文| av资源网一区| 亚洲经典在线| 成人h动漫精品一区二区器材| 生活片a∨在线观看| 热久久精品国产| 国产91亚洲精品一区二区三区| 在线性视频日韩欧美| 色婷婷综合久久久中文一区二区| 丁香网亚洲国际| 国产日本精品|