SPRING MVC - Validation


なぜ検証が必要ですか?


  • 会員加入の状況を考えてみましょう.
    年齢を文字で記入したり、フォーマットに合わないデータを入力したりした場合、エラーページが直接表示されたり、例外ページに移動したりしたらどうなりますか?
    ユーザーは「ああこれは何ですか」と言います
    したがって,我々が提供するWebサービスは,このようなエラーが発生した場合に,エラーの位置を指摘し,ユーザが入力したデータが変わらないことを確保しなければならない.

  • ではValidationはどちらで行うべきでしょうか?
  • クライアントのみの認証??もちろん、ユーザーが表示しやすく、インスタントで可用性が高いため、セキュリティが悪い場合がありますが、自由に操作できます.
  • サーバでのみ検証されますか?:クライアントからメリットを得ることはできません.
    So 2つの適切な混合使用
  • まず、BindingResult
    検証のコア
    @PostMapping("/signup")
    public String signup(@ModelAttribute SignupForm form, BindingResult bindingresult){
    ...
    return "redirect:/"
    }
    このように使います.BindingResultには、フィールドにエラーが発生したときにFieldErrorが含まれます.時間軸では、BindingResultに含まれるエラーに#フィールドを使用してアクセスできます.
    BindingResult@ModelAttributeでデータをバインドする場合、タイプが一致しないためにエラーが発生することはありません.このフィールドは保持され、コントローラが正常に呼び出されます.
    そのためには、SpringはValidationのターゲットオブジェクトを処理する後ろにBindingResultに続く必要があります.これは簡単なルールです.

    メンバー登録の場合のValidation適用例


    会員フォーラム
    @Data
    public class SignupForm {
    
        private String name;
    
        private String password;
    
        private Integer age;
    }
    検証用Validator
    @Component
    public class SignupValidator implements Validator {
    
        @Override
        public boolean supports(Class<?> clazz) {
            return SignupForm.class.isAssignableFrom(clazz);
        }
    
        @Override
        public void validate(Object target, Errors errors) {
            SignupForm form=(SignupForm) target;
    
            if(!StringUtils.hasText(form.getName())){
                errors.rejectValue("name","required");
    
            }
            if(!StringUtils.hasText(form.getPassword())){
                errors.rejectValue("password","required");
    
            }
        }
    }
    会員登録時に名前とパスワードが記入されていない場合、このコードはこの部分が空であることを示します.
    ここでvalidateメソッドのerrorsパラメータが表示されます.
    errors.RequitValueのパラメータを表示すると、{"name"、"password"、"required"が表示されます.
    「name」と「password」は、エラーが発生したフィールドの名前と見なすことができます.
    「required」はメッセージコードを表します.(SpringはMessage.propertiesをMessage.Sourceで読み込み、コードに一致するメッセージをロードします.)
    メッセージコードを作成すると、required.signupform.name:이름은 필수 입니다.に示すように詳細を作成することもできます.required:필수 입니다.簡単に作成することもできます.
    エラー・メッセージを定義した場合、どのエラー・コードを検索して出力しますか?
    優先オプションとして、定義された詳細(required.signupform.nameなど)を使用します.
    しかし、上記のコードを見ると、エラーメッセージコードがrequiredに設定されていることを疑う可能性がありますが、エラーメッセージを優先順位でロードするにはどうすればいいですか?
    これらの質問の答えはMessageCodesResolverにあります!
    MessageCodesResolver
  • で転送されたエラーコードを使用して
  • メッセージコードを生成
  • フィールドエラーを生成するには、次の手順に従います.
  • 優先度
  • code.object name.field
  • code.field
  • code.type(field)
  • code
    この順序でメッセージを検索して出力します!
  • メンバーの登録に使用するフォームを表示すると、ageはIntegerタイプですが、文字を入力するとバインドエラーが発生し、例外が発生します.
    この文書の冒頭でBindingResultについて説明するとき、データバインド時にタイプが一致しない場合、BindingResultにはこのフィールドのエラーが含まれます.
    スプリングはtypemismatchというエラーコードを生成し、BindingResultに入れます.
    typemismatch codeも上の優先度に基づいてメッセージコードを生成します!
    application.properties

    errors.properties

    SignupController
    @Controller
    @RequiredArgsConstructor
    public class SignupController {
    
        private final SignupValidator signupValidator;
    
        @InitBinder
        public void init(WebDataBinder webDataBinder){
            webDataBinder.addValidators(signupValidator);
        }
    
        @GetMapping("/signup")
        public String signupForm(Model model){
            model.addAttribute("signupForm",new SignupForm());
    
            return "signup";
        }
    
        @PostMapping("/signup")
        public String signup(@Validated @ModelAttribute SignupForm form, BindingResult bindingResult){
            if(bindingResult.hasErrors()){
                return "signup";
            }
    
            return "redirect:/";
        }
    }
    WebDataBinderに検証プログラムを追加した後、@Validatedコメントを使用できます.
    これは検証にのみ使用されるコードです!
    signup.html
    <!DOCTYPE HTML>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="utf-8">
        <style>
            .field-error{
                border-color:red;
                color:red;
            }
        </style>
    </head>
    <body>
    
    <div >
        <div >
            <h2 >회원 가입</h2>
        </div>
    
        <form  th:action th:object="${signupForm}" method="post">
            <div>
                <label for="name" >이름</label>
                <input type="text" id="name" th:field="*{name}"  placeholder="이름을 입력하세요"
                       th:errorclass="field-error">
                <div class="field-error" th:errors="*{name}">
                    이름 오류
                </div>
            </div>
            <div>
                <label for="password" >비밀번호</label>
                <input type="text" id="password" th:field="*{password}" 
                       placeholder="가격을 입력하세요" th:errorclass="field-error">
                <div class="field-error" th:errors="*{password}">
                    비밀번호 오류
                </div>
            </div>
            <div>
                <label for="age" >나이</label>
                <input type="text" id="age" th:field="*{age}"
                       placeholder="가격을 입력하세요" th:errorclass="field-error">
                <div class="field-error" th:errors="*{age}">
                    나이 오류
                </div>
            </div>
    
            <div >
                <input type="submit">
            </div>
        </form>
    </div> 
    </body>
    </html>
    th:errors:このフィールドにエラーがある場合、出力タグ(th:ifおよびth:textの統合バージョン(?))
    th:errorclass:th:fieldで指定されたエラーがある場合は、クラスを追加します.

    実行結果




    予想通りに稼働していることを確認します!!

    以上が私たちのヒントですありがとうございます


    この記事では、インフラストラクチャの金ヨンハン氏の「Spring MVC 2編−バックエンドWeb開発のキーテクノロジー」を学び、執筆する.
    ソース:https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2/dashboard