0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

SpringBoot參數(shù)驗(yàn)證的10個(gè)技巧2

jf_78858299 ? 來(lái)源:JAVA旭陽(yáng) ? 作者:JAVA旭陽(yáng) ? 2023-04-07 15:11 ? 次閱讀

5 將 i18n 用于錯(cuò)誤消息

如果你的應(yīng)用程序支持多種語(yǔ)言,則必須使用國(guó)際化 (i18n) 以用戶首選語(yǔ)言顯示錯(cuò)誤消息。

以下是在 Spring Boot 應(yīng)用程序中使用 i18n 處理錯(cuò)誤消息的示例

  1. 首先,在資源目錄下創(chuàng)建一個(gè)包含默認(rèn)錯(cuò)誤消息的 messages.properties 文件
# messages.properties
user.name.required=Name is required.
user.email.invalid=Invalid email format.
user.age.invalid=Age must be a number between 18 and 99.
  1. 接下來(lái),為每種支持的語(yǔ)言創(chuàng)建一個(gè) messages_xx.properties 文件,例如,中文的 messages_zh_CN.properties。
user.name.required=名稱不能為空.
user.email.invalid=無(wú)效的email格式.
user.age.invalid=年齡必須在1899歲之間.
  1. 然后,更新您的驗(yàn)證注釋以使用本地化的錯(cuò)誤消息
public class User {
    @NotNull(message = "{user.id.required}")
    private Long id;

    @NotBlank(message = "{user.name.required}")
    private String name;

    @Email(message = "{user.email.invalid}")
    private String email;

    @NotNull(message = "{user.age.required}")
    @Min(value = 18, message = "{user.age.invalid}")
    @Max(value = 99, message = "{user.age.invalid}")
    private Integer age;
}
  1. 最后,在 Spring 配置文件中配置 MessageSource bean 以加載 i18n 消息文件
@Configuration
public class AppConfig {
    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean validatorFactoryBean = new LocalValidatorFactoryBean();
        validatorFactoryBean.setValidationMessageSource(messageSource());
        return validatorFactoryBean;
    }
}
  1. 現(xiàn)在,當(dāng)發(fā)生驗(yàn)證錯(cuò)誤時(shí),錯(cuò)誤消息將根據(jù)隨請(qǐng)求發(fā)送的“Accept-Language”標(biāo)頭以用戶的首選語(yǔ)言顯示。

6 使用分組驗(yàn)證

驗(yàn)證組是 Spring Boot 驗(yàn)證框架的一個(gè)強(qiáng)大功能,允許您根據(jù)其他輸入值或應(yīng)用程序狀態(tài)應(yīng)用條件驗(yàn)證規(guī)則。

現(xiàn)在有一個(gè)包含三個(gè)字段的User類的情況下:firstName、lastNameemail。我們要確保如果 email 字段為空,則 firstNamelastName 字段必須非空。否則,所有三個(gè)字段都應(yīng)該正常驗(yàn)證。

為此,我們將定義兩個(gè)驗(yàn)證組:EmailNotEmptyDefault。EmailNotEmpty 組將包含當(dāng) email 字段不為空時(shí)的驗(yàn)證規(guī)則,而 Default 組將包含所有三個(gè)字段的正常驗(yàn)證規(guī)則。

  1. 創(chuàng)建帶有驗(yàn)證組的 User
public class User {
    @NotBlank(groups = Default.class)
    private String firstName;

    @NotBlank(groups = Default.class)
    private String lastName;

    @Email(groups = EmailNotEmpty.class)
    private String email;

    // getters and setters omitted for brevity
    public interface EmailNotEmpty {}
    public interface Default {}
}
  • 請(qǐng)注意,我們?cè)?code>User類中定義了兩個(gè)接口,EmailNotEmptyDefault。這些將作為我們的驗(yàn)證組。
  1. 接下來(lái),我們更新Controller使用這些驗(yàn)證組
@RestController
@RequestMapping("/users")
@Validated
public class UserController {
    public ResponseEntity<String> createUser(
            @Validated({org.example.model.ex6.User.EmailNotEmpty.class}) @RequestBody User userWithEmail,
            @Validated({User.Default.class}) @RequestBody User userWithoutEmail)
    {
        // Create the user and return a success response
       
    }
}
  • 我們已將@Validated注釋添加到我們的控制器,表明我們想要使用驗(yàn)證組。我們還更新了 createUser 方法,將兩個(gè) User 對(duì)象作為輸入,一個(gè)在 email 字段不為空時(shí)使用,另一個(gè)在它為空時(shí)使用。
  • @Validated 注釋用于指定將哪個(gè)驗(yàn)證組應(yīng)用于每個(gè) User 對(duì)象。對(duì)于 userWithEmail 參數(shù),我們指定了 EmailNotEmpty 組,而對(duì)于 userWithoutEmail 參數(shù),我們指定了 Default 組。
  1. 進(jìn)行這些更改后,現(xiàn)在將根據(jù)“電子郵件”字段是否為空對(duì)“用戶”類進(jìn)行不同的驗(yàn)證。如果為空,則 firstNamelastName 字段必須非空。否則,所有三個(gè)字段都將正常驗(yàn)證。

7 對(duì)復(fù)雜邏輯使用跨域驗(yàn)證

如果需要驗(yàn)證跨多個(gè)字段的復(fù)雜輸入規(guī)則,可以使用跨字段驗(yàn)證來(lái)保持驗(yàn)證邏輯的組織性和可維護(hù)性??缱侄悟?yàn)證可確保所有輸入值均有效且彼此一致,從而防止出現(xiàn)意外行為。

假設(shè)我們有一個(gè)表單,用戶可以在其中輸入任務(wù)的開(kāi)始日期和結(jié)束日期,并且我們希望確保結(jié)束日期不早于開(kāi)始日期。我們可以使用跨域驗(yàn)證來(lái)實(shí)現(xiàn)這一點(diǎn)。

  1. 首先,我們定義一個(gè)自定義驗(yàn)證注解EndDateAfterStartDate
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EndDateAfterStartDateValidator.class)
public @interface EndDateAfterStartDate {
    String message() default "End date must be after start date";
    Class?[] groups() default {};
    Class? extends Payload[] payload() default {};
}
  1. 然后,我們創(chuàng)建驗(yàn)證器EndDateAfterStartDateValidator
public class EndDateAfterStartDateValidator implements ConstraintValidator<EndDateAfterStartDate, TaskForm> {
    @Override
    public boolean isValid(TaskForm taskForm, ConstraintValidatorContext context) {
        if (taskForm.getStartDate() == null || taskForm.getEndDate() == null) {
            return true;
        }

        return taskForm.getEndDate().isAfter(taskForm.getStartDate());
    }
}
  1. 最后,我們將EndDateAfterStartDate注釋?xiě)?yīng)用于我們的表單對(duì)象TaskForm
@EndDateAfterStartDate
public class TaskForm {
    @NotNull
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate startDate;

    @NotNull
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate endDate;
}

現(xiàn)在,當(dāng)用戶提交表單時(shí),驗(yàn)證框架將自動(dòng)檢查結(jié)束日期是否晚于開(kāi)始日期,如果不是,則提供有意義的錯(cuò)誤消息。

8 對(duì)驗(yàn)證錯(cuò)誤使用異常處理

可以使用異常處理ExceptionHandler來(lái)統(tǒng)一捕獲和處理驗(yàn)證錯(cuò)誤。

以下是如何在 Spring Boot 中使用異常處理來(lái)處理驗(yàn)證錯(cuò)誤的示例:

@RestControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                                                                  HttpHeaders headers, HttpStatus status,
                                                                  WebRequest request) {
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("timestamp", LocalDateTime.now());
        body.put("status", status.value());

        // Get all errors
        List<String> errors = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(x -> x.getDefaultMessage())
                .collect(Collectors.toList());

        body.put("errors", errors);

        return new ResponseEntity<>(body, headers, status);
    }
}

在這里,我們創(chuàng)建了一個(gè)用 @RestControllerAdvice 注解的 RestExceptionHandler 類來(lái)處理我們的 REST API 拋出的異常。然后我們創(chuàng)建一個(gè)用@ExceptionHandler注解的方法來(lái)處理在驗(yàn)證失敗時(shí)拋出的 MethodArgumentNotValidException。

在處理程序方法中,我們創(chuàng)建了一個(gè) Map 對(duì)象來(lái)保存錯(cuò)誤響應(yīng)的詳細(xì)信息,包括時(shí)間戳、HTTP 狀態(tài)代碼和錯(cuò)誤消息列表。我們使用 MethodArgumentNotValidException 對(duì)象的 getBindingResult() 方法獲取所有驗(yàn)證錯(cuò)誤并將它們添加到錯(cuò)誤消息列表中。

最后,我們返回一個(gè)包含錯(cuò)誤響應(yīng)詳細(xì)信息的ResponseEntity對(duì)象,包括作為響應(yīng)主體的錯(cuò)誤消息列表、HTTP 標(biāo)頭和 HTTP 狀態(tài)代碼。

有了這個(gè)異常處理代碼,我們的 REST API 拋出的任何驗(yàn)證錯(cuò)誤都將被捕獲并以結(jié)構(gòu)化和有意義的格式返回給用戶,從而更容易理解和解決問(wèn)題。

9 測(cè)試你的驗(yàn)證邏輯

需要為你的驗(yàn)證邏輯編寫(xiě)單元測(cè)試,以幫助確保它正常工作。

@DataJpaTest
public class UserValidationTest {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private Validator validator;

    @Test
    public void testValidation() {
        User user = new User();
        user.setFirstName("John");
        user.setLastName("Doe");
        user.setEmail("invalid email");

        Set

我們使用 JUnit 5 編寫(xiě)一個(gè)測(cè)試來(lái)驗(yàn)證具有無(wú)效電子郵件地址的“用戶”對(duì)象。然后我們使用 Validator 接口來(lái)驗(yàn)證 User 對(duì)象并檢查是否返回了預(yù)期的驗(yàn)證錯(cuò)誤。

10 考慮客戶端驗(yàn)證

客戶端驗(yàn)證可以通過(guò)向用戶提供即時(shí)反饋并減少對(duì)服務(wù)器的請(qǐng)求數(shù)量來(lái)改善用戶體驗(yàn)。但是,不應(yīng)依賴它作為驗(yàn)證輸入的唯一方法。客戶端驗(yàn)證很容易被繞過(guò)或操縱,因此必須在服務(wù)器端驗(yàn)證輸入,以確保安全性和數(shù)據(jù)完整性。

總結(jié)

有效的驗(yàn)證對(duì)于任何 Web 應(yīng)用程序的穩(wěn)定性和安全性都是必不可少的。Spring Boot 提供了一套工具和庫(kù)來(lái)簡(jiǎn)化驗(yàn)證邏輯并使其更易于維護(hù)。通過(guò)遵循本文中討論的最佳實(shí)踐,您可以確保您的驗(yàn)證組件有效并提供出色的用戶體驗(yàn)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 應(yīng)用程序
    +關(guān)注

    關(guān)注

    37

    文章

    3198

    瀏覽量

    57364
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    335

    瀏覽量

    14259
  • Boot
    +關(guān)注

    關(guān)注

    0

    文章

    148

    瀏覽量

    35675
  • SpringBoot
    +關(guān)注

    關(guān)注

    0

    文章

    172

    瀏覽量

    145
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    SpringBoot配置Mybatis的2個(gè)錯(cuò)誤和修正

    SpringBoot】配置Mybatis錯(cuò)誤
    發(fā)表于 04-19 10:31

    SpringBoot中的Druid介紹

    SpringBoot中Druid數(shù)據(jù)源配置
    發(fā)表于 05-07 09:21

    SpringBoot知識(shí)總結(jié)

    SpringBoot干貨學(xué)習(xí)總結(jié)
    發(fā)表于 08-01 10:40

    一文解析SpringBoot2整合SSM框架

    SpringBoot2整合SSM框架詳解
    發(fā)表于 06-09 16:43

    怎么學(xué)習(xí)SpringBoot

    SpringBoot學(xué)習(xí)之路(X5)- 整合JPA
    發(fā)表于 06-10 14:52

    springboot集成mqtt

    springboot集成mqtt,大綱一.數(shù)據(jù)入庫(kù)1.數(shù)據(jù)入庫(kù)解決方案二.開(kāi)發(fā)實(shí)時(shí)訂閱發(fā)布展示頁(yè)面1.及時(shí)通訊技術(shù)2.技術(shù)整合
    發(fā)表于 07-16 07:53

    怎樣去使用springboot

    怎樣去使用springboot呢?學(xué)習(xí)springboot需要懂得哪些?
    發(fā)表于 10-25 07:13

    SpringBoot應(yīng)用啟動(dòng)運(yùn)行run方法

    什么時(shí)候創(chuàng)建嵌入式的Servlet容器工廠?什么時(shí)候獲取嵌入式的Servlet容器并啟動(dòng)Tomcat;獲取嵌入式的Servlet容器工廠:1)、SpringBoot應(yīng)用啟動(dòng)運(yùn)行run方法2
    發(fā)表于 12-20 06:16

    怎樣去設(shè)計(jì)一個(gè)基于springboot+freemark+jpa+MySQL的在線電影訂票系統(tǒng)

    實(shí)現(xiàn)的功能有:前臺(tái): 1、正在上映的電影瀏覽查看,可在線播放預(yù)告視頻。 2、影院信息瀏覽查看,包括各影院上映場(chǎng)次數(shù)。 3、新聞咨詢信息瀏覽查看。 4、地域信息查看切換。 5、用戶注冊(cè)登錄,登錄支持發(fā)送短信驗(yàn)證碼登錄和...
    發(fā)表于 01-03 07:22

    如何使用springboot+vue搭建個(gè)人網(wǎng)站2

    * 1. maven下載(win10) * 2. 配置環(huán)境變量 * 3. maven配置 * 4. ***idea下載*** * 5. idea的maven設(shè)置 * 6. 新建Springboot項(xiàng)目(測(cè)試) I
    的頭像 發(fā)表于 02-14 15:54 ?631次閱讀
    如何使用<b class='flag-5'>springboot</b>+vue搭建個(gè)人網(wǎng)站<b class='flag-5'>2</b>

    什么是 SpringBoot?

    本文從為什么要有 `SpringBoot`,以及 `SpringBoot` 到底方便在哪里開(kāi)始入手,逐步分析了 `SpringBoot` 自動(dòng)裝配的原理,最后手寫(xiě)了一個(gè)簡(jiǎn)單的 `sta
    的頭像 發(fā)表于 04-07 11:28 ?1183次閱讀
    什么是 <b class='flag-5'>SpringBoot</b>?

    SpringBoot常用注解及使用方法2

    基于 SpringBoot 平臺(tái)開(kāi)發(fā)的項(xiàng)目數(shù)不勝數(shù),與常規(guī)的基于Spring開(kāi)發(fā)的項(xiàng)目最大的不同之處,SpringBoot 里面提供了大量的注解用于快速開(kāi)發(fā),而且非常簡(jiǎn)單,基本可以做到開(kāi)箱即用!
    的頭像 發(fā)表于 04-07 11:52 ?557次閱讀

    SpringBoot的核心注解2

    今天跟大家來(lái)探討下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot為什么不需要XML,達(dá)到零配置
    的頭像 發(fā)表于 04-07 14:34 ?1871次閱讀
    <b class='flag-5'>SpringBoot</b>的核心注解<b class='flag-5'>2</b>

    SpringBoot參數(shù)驗(yàn)證10個(gè)技巧1

    參數(shù)驗(yàn)證很重要,是平時(shí)開(kāi)發(fā)環(huán)節(jié)中不可少的一部分,但是我想很多后端同事會(huì)偷懶,干脆不錯(cuò),這樣很可能給系統(tǒng)的穩(wěn)定性和安全性帶來(lái)嚴(yán)重的危害。那么在Spring Boot應(yīng)用中如何做好參數(shù)校驗(yàn)工作呢,本文提供了
    的頭像 發(fā)表于 04-07 15:10 ?442次閱讀

    個(gè)注解搞定SpringBoot接口防刷

    技術(shù)要點(diǎn):springboot的基本知識(shí),redis基本操作,
    的頭像 發(fā)表于 11-28 10:46 ?342次閱讀