チェックマーク(英: checkmark, check mark)は、「✓」(または、「v」や「レ」)のように下か右下に伸びたあと右上にはねる線であらわされる図形・記号である。イギリス英語では tick と呼ばれる。
歴史
チェックマークはローマ帝国期に作られていたと考えられている。"V" はラテン語で真実を意味する単語 veritas を縮めるために使われた。これは、肯定の返答、真実、または表中の項目への承認を示すために使われた。長い期間をかけて、このマークのデザインは変化した。
⇧ 衝撃...「ローマ帝国期」には「チェックマーク」が爆誕していたんだそうな。
⇧ 紀元前8世紀中ごろには、「チェックマーク」が使われていたって考えると、不思議な気持ちになりますね、どうもボクです。
というわけで、今回もJavaのフレームワーク「Spring Framework」についてです。
レッツトライ~。
Validationとは?
Wikipediaさんに聞いてみる。
In software project management, software testing, and software engineering, verification and validation (V&V) is the process of checking that a software system meets specifications and requirements so that it fulfills its intended purpose. It may also be referred to as software quality control. It is normally the responsibility of software testers as part of the software development lifecycle. In simple terms, software verification is: "Assuming we should build X, does our software achieve its goals without any bugs or gaps?" On the other hand, software validation is: "Was X what we should have built? Does X meet the high level requirements?"
https://en.wikipedia.org/wiki/Software_verification_and_validation
⇧ 超ザックリ要約すると「ソフトウェアシステムが仕様や要件を満たしているかをチェックするプロセス」ってことになるみたいね。
で、「Verification」と「Validation」の違いはというと、
Verification and validation are not the same things, although they are often confused. Boehm succinctly expressed the difference as
- Verification: Are we building the product right?
- Validation: Are we building the right product?
https://en.wikipedia.org/wiki/Software_verification_and_validation
⇧ う、う~ん...よう分からん...
このあたりは、Wikipediaの続きを読んでいただくとして、「Validation」ってのは、「あらかじめ決めておいた仕様や要件を満たしているかチェックすること」って意味合いってことになるんですかね。
Bean Validationとは?
Wikipediaさんに聞いてみる。
Bean Validation defines a metadata model and API for JavaBean validation. The metadata source is annotations, with the ability to override and extend the meta-data through the use of XML validation descriptors.
Originally defined as part of Java EE, version 2 aims to work in Java SE apps as well.
Java Bean Validation (JSR 303) originated as a framework that was approved by the JCP as of 16 November 2009 and accepted as part of the Java EE 6 specification. The Hibernate team provides with Hibernate Validator the reference implementation of Bean Validation and also created the Bean Validation TCK any implementation of JSR 303 needs to pass.
⇧ Java言語独自の「Validation」ってことみたいね。「JSR(Java Specification Request)」っていう、Javaプラットフォームに関する技術や仕様についての公式文書らしい。
Bean Validation 2.0 is defined by JSR 380, approved 2017-07-31. This major release leverages language features in Java 8 that are very useful for the purposes of Bean Validation. So Java 8 is required as the minimum Java version.
⇧ 現在のところ、「Bean Validation」の仕様については「JSR 380」が最終稿なのかね。
ここで気になるのが、Javaで「Validation」と言ったら、「Bean Validation」以外は無いと考えて良いのだろうか...
「Bean」の必要条件を確認してみた。
Beanの必要条件
など。
⇧ う~ん、上記を満たす「クラス」であれば良い、ってことだとは思うんだけども、「文字列」とか「数値」とか「バリデーション」したいってなった場合は、「Bean」を作らないといけないってことなのかね?
ただ、HTTP通信のGETなんかで、渡ってくるパラメーターが「文字列」1つのみの場合も「Bean」を作成しておかないと「バリデーション」ができないんだとしたら、考えものな気がするんだが...
Spring FrameworkにおけるValidationとは?
公式のドキュメントによると、
⇧「core.pdf(英語)」を開いて、「validation」で検索してヒット。
日本語訳のドキュメントだと、
⇧ 「コア 」を選択して、「validation」で検索すると、
⇧「検証、データバインディング、型変換」の項目がヒットするので、
ということらしい。
ビジネスロジックとして検証を検討することには長所と短所があり、Spring は検証(およびデータバインディング)の設計を提供します。具体的には、検証は Web 層に結び付けられるべきではなく、ローカライズが容易である必要があり、利用可能な検証ツールをプラグインできる必要があります。これらの懸念を考慮して、Spring は Validator
契約を提供します。これは、基本的であり、アプリケーションのすべてのレイヤーで非常に有用です。
https://spring.pleiades.io/spring-framework/docs/current/reference/html/core.html#spring-core
データバインディングは、ユーザー入力をアプリケーションのドメインモデル(またはユーザー入力の処理に使用するオブジェクト)に動的にバインドできます。Spring は、まさにそれを行うために適切な名前の DataBinder
を提供します。Validator
および DataBinder
は validation
パッケージを構成し、これは主に Web レイヤーで使用されますが、これに限定されません。
https://spring.pleiades.io/spring-framework/docs/current/reference/html/core.html#spring-core
⇧「検証」自体はどのレイヤー層でも行えるべき、ってことなんですかね。
Spring は、セットアップインフラストラクチャと Spring 独自の Validator
契約へのアダプターを通じて Java Bean 検証をサポートします。アプリケーションは、Java Bean 検証に従って、Bean 検証をグローバルに一度有効にして、すべての検証ニーズに対してのみ使用できます。Web レイヤーでは、DataBinder
の構成に従って、アプリケーションは DataBinder
ごとにコントローラーローカル Spring Validator
インスタンスをさらに登録できます。これは、カスタム検証ロジックのプラグインに役立ちます。
https://spring.pleiades.io/spring-framework/docs/current/reference/html/core.html#spring-core
⇧ 気になるのは、『Spring は、セットアップインフラストラクチャと Spring 独自の Validator
契約へのアダプターを通じて Java Bean 検証をサポートします。』ってあって、英語版だと、
Spring supports Java Bean Validation through setup infrastructure and an adaptor to Spring’s own Validator contract. Applications can enable Bean Validation once globally, as described in Java Bean Validation, and use it exclusively for all validation needs.
In the web layer, applications can further register controller-local Spring Validator instances per DataBinder, as described in Configuring a DataBinder, which can be useful for plugging in custom validation logic.
https://docs.spring.io/spring-framework/docs/current/reference/pdf/core.pdf
⇧『Spring supports Java Bean Validation through setup infrastructure and an adaptor to Spring’s own Validator contract.』ってことなんだけど、「Spring Framework」が「Bean Validation」をサポートしてくれるのは分かったんだけど、「Validation」の全量が不明なんよね...
改めて、Javaで「Validation」って言った場合、「Bean Validation」以外ってのは存在しないと考えて良いのだろうか...
謎は深まるばかり...
Spring FrameworkのValidationがBean Validation以外は存在しないとして
「Spring Framework」での「validation」っていうものが、「Bean Validation」のみを考えるで良いとした場合、
Hibernate ValidatorはJSR 380の実装なので、基本的にJSR 380の規格に従った実装ですが、一部、Hibernate Validatorの独自拡張の要素があるので、その拡張についても併せて解説していきます。
Spring Frameworkでは、バリデーションの実装にHibernate Validatorを使用しているので、JSR 380で規格化されているバリデーションだけでなく、Hibernate Validatorの独自拡張のバリデーションも使用することができます。
⇧ 上記サイト様が「Spring Framework」で利用できる「Bean Validation」の「アノテーション」一覧をまとめてくれていました。
つまり、上記サイト様に記載のないような条件でチェックせざるを得ない場合は、自分で独自にコーディングとかしてあげないといけない模様。
⇧ 上記サイト様が参考になるかと。
実際に実施してみる
というわけで、
⇧ 毎度恒例の上記サイト様のお題を試していきますかね。
「パラメタage
が0以上の整数であり、パラメタname
が3文字以上の半角英数字かつ先頭文字は半角英字であることをバリデーションせよ。」とあるので、
で「バリデーション」していく感じになるのかな。
「バリデーション」失敗時のExceptionなんかについては、
⇧ 上記サイト様が詳しいです。
今回、POSTなので、
⇧ 上記サイト様を参考に、「curl」コマンドで疎通確認します。
Webの開発現場だと、
⇧ 上記サイト様の説明にあるように、ツールを導入していくのが一般的みたいですね。
で、EclipseでGradleプロジェクトを「サーバーで実行」してから、curlでPOSTしてみたところ、なんか、
警告: Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported] [月 6月 07 14:03:38 JST 2021]
⇧ ってなエラーが出たんだけど、どうやら、
Jackson には com.fasterxml.jackson
グループのモノと org.codehaus.jackson
のモノがあります。Jackson は 2.0.0 以降からネーミングスペースが前者の com.fasterxml.jackson
に移ったため、IDE で Jackson をインポートしようとすると、fasterxml, codehaus のどちらを選ぶかを尋ねられることがあります。ここで間違って codehaus を選ぶと古い Jackson が動いてしまい、なんとなく動きはするけれど細かい挙動が違ったりエラーが発生したりします。
⇧ 上記サイト様によりますと、依存関係に「jackson」パッケージを追加しないといけないらしい...知らんがな
さらなる悲報...
⇧ 「シングルコーテーション」使えない問題があるらしい...
「macOS」使ったことないけど、Web開発は断然「macOS」が向いてる状態が続いてるんですかね?
いろいろ、脱線しましたが、以下のようなディレクトリ構成になりました。
⇧ 例の如く、「Gradleプロジェクト」から作成しているので、
⇧ 手前味噌で恐縮ですが、上記を参考に、「プロジェクト・ファセット」 への変換や、「デプロイメント・アセンブリー」で『プロジェクトと外部の依存関係』の追加などの対応は忘れずに。(なんか、「build.gradle」に変更を加える度に、「デプロイメント・アセンブリー」で『プロジェクトと外部の依存関係』の追加をしないと駄目っぽい感じなんかな...面倒くさ過ぎる...)
そして、「Spring Boot」を使わずに「Spring Framework」で「バリデーション」する際のハマりどころがまだありました...
バリデーションエラーが起こった場合は、BindResultがホゲホゲではなくて、バリデーションエラーExceptionをハンドリングするメソッドを作ってやるのが特徴です。
⇧ へぇへぇへぇ~、逆に言うと、「JSON」の「バリデーション」について「BindResult」が使えるのか使えないのかをハッキリさせて欲しい気もしますが...
で、「Spring Boot」が使えないケースだと、
5.7.2 Configuring a Bean Validation Implementation
Spring provides full support for the JSR-303 Bean Validation API. This includes convenient support for bootstrapping a JSR-303 implementation as a Spring bean. This allows for a javax.validation.ValidatorFactory
or javax.validation.Validator
to be injected wherever validation is needed in your application.
Use the LocalValidatorFactoryBean
to configure a default JSR-303 Validator as a Spring bean:
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
The basic configuration above will trigger JSR-303 to initialize using its default bootstrap mechanism. A JSR-303 provider, such as Hibernate Validator, is expected to be present in the classpath and will be detected automatically.
⇧ 「XML(Extensible Markup Language)」に上記の一文を追加して上げないと、「JSR-303」の仕様を実装した「Validation API」が「Spring framework 」で利用できないってことらしい...
というか、どの「XML(Extensible Markup Language)」に追記すれば良いのか、全く記載がないというね...初見殺しのドキュメントだな~...
一応、最新の「Spring Framework」のドキュメントを確認してみると、
⇧ 上記のような感じで、
のどっちかの設定をすることで「Spring Framework」で「バリデーション」が使えるようになるらしい。
初見の人が見たら、どっちも必要なんかな~って思ってしまう紛らわしいドキュメントですな...
今回は、「XML(Extensible Markup Language)」で設定していく感じにします。
というか、2021年6月9日(水)時点で、「Bean Validation」の仕様については「JSR-380」が最新だと思うんだけど、対応してるのかね?
公式のドキュメントを見る限り「JSR-330」は出てくるんだけど、「JSR-380」ってワードが出てこない...
ちなみに、「Hibernate Validator」のAPIがバージョン 7.x からパッケージ名が「javax」から「jakarta」に変わったことにより、
⇧ 上記サイト様のような対応が必要らしい。
つまり、もし、バージョン7.x 以降の「Hibernate Validator」のAPIを「Spring Framework」で使用する場合は、自分で「バリデーション」用のクラスを作成してあげないと駄目みたいね、「カスタムバリデーション」ってやつですかね?
というわけで、今回は、パッケージ名が変更になる前の「Hibernate Validator」のAPIを依存関係に追加する方針としました。(「カスタムバリデーション」作りたくなかったので...)
というか、「javax.validation.NoProviderFoundException」ってエラーが何で起こってるのか分かり辛くて滅茶苦茶に泥沼にハマったんですが、「org.springframework.validation.beanvalidation.LocalValidatorFactoryBean」を「依存性の注入(DI:Dependency injection)」すると、「javax」パッケージの「Validator」しか探してくれないってことなのかね?
まぁ、何が言いたいかというと、必要な依存関係のライブラリが分かり辛いんですよね...
準備が整ったら、ファイルを編集で。
■/Spring_Framework_Validation/build.gradle
/* * This file was generated by the Gradle 'init' task. * * This generated file contains a sample Java Library project to get you started. * For more details take a look at the Java Libraries chapter in the Gradle * User Manual available at https://docs.gradle.org/6.3/userguide/java_library_plugin.html */ plugins { // Apply the java-library plugin to add support for Java Library id 'java-library' } repositories { // Use jcenter for resolving dependencies. // You can declare any Maven/Ivy/file repository here. jcenter() } dependencies { // This dependency is exported to consumers, that is to say found on their compile classpath. api 'org.apache.commons:commons-math3:3.6.1' // This dependency is used internally, and not exposed to consumers on their own compile classpath. implementation 'com.google.guava:guava:28.2-jre' // https://mvnrepository.com/artifact/org.springframework/spring-core implementation group: 'org.springframework', name: 'spring-core', version: '5.3.7' // https://mvnrepository.com/artifact/org.springframework/spring-context implementation group: 'org.springframework', name: 'spring-context', version: '5.3.7' // https://mvnrepository.com/artifact/org.springframework/spring-webmvc implementation group: 'org.springframework', name: 'spring-webmvc', version: '5.3.7' // // https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator // runtimeOnly group: 'org.hibernate.validator', name: 'hibernate-validator', version: '7.0.1.Final' // https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator implementation group: 'org.hibernate.validator', name: 'hibernate-validator', version: '6.2.0.Final' // https://mvnrepository.com/artifact/org.glassfish/javax.el implementation group: 'org.glassfish', name: 'javax.el', version: '3.0.1-b12' // // https://mvnrepository.com/artifact/org.glassfish/jakarta.el // implementation group: 'org.glassfish', name: 'jakarta.el', version: '4.0.1' // // https://mvnrepository.com/artifact/jakarta.validation/jakarta.validation-api // implementation group: 'jakarta.validation', name: 'jakarta.validation-api', version: '3.0.0' // https://mvnrepository.com/artifact/javax.validation/validation-api implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final' // // https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor // implementation group: 'org.hibernate.validator', name: 'hibernate-validator-annotation-processor', version: '7.0.1.Final' // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.3' // Use JUnit test framework testImplementation 'junit:junit:4.12' }
⇧ 依存関係としては、「spring-core」「spring-context」「spring-webmvc」「hibernate-validator」「javax.el」「validation-api」「jackson-databind」あたりがあれば良さ気かと。
ただ、
⇧ 上記サイト様の説明を読んだ感じでは、「spring-context」あれば「spring-core」は不要かも。
というか「spring-context-support」 ってライブラリもあるみたいなんで、どれを追加すれば良いのか、正直よく分かりません...
■/Spring_Framework_Validation/src/main/resources/config/spring-web.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- Spring MVC の機能を使うことを宣言。 --> <!-- この宣言をすることで、 @Component などのアノテーションが使えるようになる。 --> <mvc:annotation-driven validator="validator"/> <!-- <context:annotation-config />--> <!-- AspectJスタイルのSpring AOPを有効化 --> <!-- <aop:aspectj-autoproxy/>--> <!-- Bean となるクラスファイルが格納されているパッケージを宣言。 --> <!-- Spring はこのパッケージ配下を自動でスキャンし、Bean として登録する。 --> <context:component-scan base-package="Spring_Framework_Validation.*" /> <!-- Springでhibernate validator使う場合に必要 --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> </beans>
■/Spring_Framework_Validation/WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 文字のエンコーディングを指定し --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class> <!-- org.Apache.catalina.filters.SetCharacterEncodingFilter --> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <!-- 上記フィルターをすべての URL で適用する。 --> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- リスナーを登録 --> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- spring.xml --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/config/spring-web.xml</param-value> </context-param> <!-- Spring MVC アプリの場合、だいたいは唯一のサーブレットを登録する。 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- すべての URL リクエストについて、上記で登録したサーブレットで処理する。 --> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
■/Spring_Framework_Validation/src/main/java/Spring_Framework_Validation/handler/AbstractRestControllerExceptionHandler.java
package Spring_Framework_Validation.handler; import javax.validation.ConstraintViolationException; import org.springframework.core.annotation.Order; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @RestControllerAdvice @Order(1) public abstract class AbstractRestControllerExceptionHandler extends ResponseEntityExceptionHandler { @Override protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) { if (body == null) { body = ex.getClass().toString(); } return super.handleExceptionInternal(ex, body, headers, status, request); } @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { return handleExceptionInternal(ex, "MethodArgumentNotValid",headers, status, request); } @Override protected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { return handleExceptionInternal(ex, "BindException",headers, status, request); } @ExceptionHandler(ConstraintViolationException.class) public ResponseEntity<Object> handleConstraintViolation( ConstraintViolationException ex, WebRequest request) { return handleExceptionInternal(ex, "Constraint", null, HttpStatus.BAD_REQUEST, request); } // すべての例外をキャッチする // どこにもキャッチされなかったらこれが呼ばれる @ExceptionHandler(Exception.class) public ResponseEntity<Object> handleAllException(Exception ex, WebRequest request) { return super.handleExceptionInternal(ex, "handleAllException", null, HttpStatus.INTERNAL_SERVER_ERROR, request); } }
■/Spring_Framework_Validation/src/main/java/Spring_Framework_Validation/entity/Person.java
package Spring_Framework_Validation.entity; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; public class Person { @NotNull @Pattern(regexp="^[a-zA-Z][a-zA-Z0-9 -/:-@\\[-\\`\\{-\\~]{3,}") private String name; @NotNull @Min(value=0) private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
■/Spring_Framework_Validation/src/main/java/Spring_Framework_Validation/controller/PersonController.java
package Spring_Framework_Validation.controller; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import Spring_Framework_Validation.entity.Person; import jakarta.validation.Valid; @RestController //@Validated public class PersonController { @RequestMapping(value="/", method=RequestMethod.GET) public String index() { return "Welcome!"; } @RequestMapping(value="/person", method=RequestMethod.POST) public String validPerson(@Valid @RequestBody Person person) { return HttpStatus.OK.getReasonPhrase(); } }
⇧ ってな感じで保存したらば、「アプリケーションサーバー(ここでは、Eclipse内蔵のTomcat)」を起動します。
起動されたら、
コマンドプロンプトから「curl」コマンドで、「アプリケーションサーバー(ここでは、Eclipse内蔵のTomcat)」に対してHTTP通信してみます。
■GETでHTTP通信(バリデーションOKな値)
curl http://localhost:8080/Spring_Framework_Validation/ -X GET -H "Content-Type: application/json" -d "{\"name\":\"Mr.pineapple\", \"age\":\"150\"}"
■POSTでHTTP通信(バリデーションOKな値)
curl http://localhost:8080/Spring_Framework_Validation/ -X GET -H "Content-Type: application/json" -d "{\"name\":\"Mr.pineapple\", \"age\":\"150\"}"
今度は、バリデーションエラーが出るような値で試してみます。
■POSTでHTTP通信(バリデーションNGな値)
curl http://localhost:8080/Spring_Framework_Validation/ -X GET -H "Content-Type: application/json" -d "{\"name\":\"33Mr.pineapple\", \"age\":\"150\"}"
⇧ ってな感じで、正常に「バリデーション」されてることが確認できました。
Eclipseの「コンソール」にも
警告: Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public java.lang.String Spring_Framework_Validation.controller.PersonController.validPerson(Spring_Framework_Validation.entity.Person): [Field error in object 'person' on field 'name': rejected value [33Mr.pineapple]; codes [Pattern.person.name,Pattern.name,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.name,name]; arguments []; default message [name],[Ljavax.validation.constraints.Pattern$Flag;@494ea20,^[a-zA-Z][a-zA-Z0-9 -/:-@\[-\`\{-\~]{3,}]; default message [正規表現 "^[a-zA-Z][a-zA-Z0-9 -/:-@\[-\`\{-\~]{3,}" にマッチさせてください]] ] [水 6月 09 13:54:22 JST 2021]
⇧ バリデーションが機能したことによる例外が投げられてることが確認できました。
それにしても、「Spring Framework」は、いろいろな決まり事が分かり辛いですね...
ネット上の情報も錯綜してますし、もうちょっと公式のドキュメントをどうにかして欲しい気がしますかね...
秘伝のタレみたいな感じで一見さんお断りみたいな書き方にするのは止めて欲しい...
あと、ドキュメントは実現したい機能ごとに完結してるようにして欲しいですね、情報が集約されてないとドキュメントを読む側は辛すぎる...
毎度、モヤモヤ感が半端ないですが、今回はこのへんで。