質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

3439閲覧

React.jsにおけるPOSTの値がNULLになる

cantama

総合スコア20

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2022/01/05 23:14

前提・実現したいこと

reactjsからのPOSTの値に対して、spring bootでカスタムバリデーションを行いたいのですが、フロントエンドから送信されたRequestの中身がnullとして扱われ@NotNullアノテーションに引っ掛かってしまいます。

発生している問題・エラーメッセージ

バックエンド側のエラー

WARN .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<com.example.main.response.Response> com.example.main.controllers.Controller.process(com.example.main.requests.Request) throws java.lang.Exception with 2 errors:

フロント側では、Responseに@NotNullのメッセージが格納されたfieldErrorsが返ってきます。

該当のソースコード

form.js

javascript

1//エラーメッセージ 2const [firstError, setFirstError] = useState(''); 3const [lastError , setLastError ] = useState(''); 4 5const handleSubmit = (evt) =>{ 6 evt.preventDefault(); 7 8 fetch("http://localhost:8080/api/send", { 9 method: "POST", 10 headers: { 11 Accept: "application/json", 12 "Content-Type": "application/json", 13 "X-AUTH-TOKEN":'Bearer '+getToken(),//JWTトークン 14 }, 15 body: JSON.stringify({ 16 First: formData.get('First'), 17 Last: formData.get('Last'), 18 }), 19 }) 20 .then((response)=> response.json()) 21 .then((data) => { 22 if(data.fieldErrors) { 23 data.fieldErrors.forEach(fieldError => { 24 if(fieldError.field === 'First'){ 25 setNodeError(fieldError.message); 26 } 27 if(fieldError.field === 'Last'){ 28 setNetError(fieldError.message); 29 } 30 }); 31 } else { 32 alert("success") 33 } 34 }).catch((err) => err); 35 36const onFirstFocus = (e) =>{ 37 e.preventDefault(); 38 setFirstError(''); 39} 40const onLastFocus = (e) =>{ 41 e.preventDefault(); 42 setLastError(''); 43} 44 45return( 46<form className="col" onSubmit={handleSubmit} noValidate={false}> 47 48  <input className="form" type="text" value="" onFocus={onFirstFocus} name="First"/> 49  { 50   firstError ? <span style={{ color: 'red', fontSize: '12px'}}>{firstError}</span> : '' 51  } 52  <input className="form" type="text" value="" onFocus={onLastFocus} name="Last"/> 53  { 54   lastError ? <span style={{ color: 'red', fontSize: '12px'}}>{lastError}</span> : '' 55  } 56 57  <button type="submit">送信</button> 58</form> 59)

Request.java

java

1@Data 2public class Request{ 3 @NotNull(message = "First is required.") 4 @Pattern(regexp="^[1-9]|[1-9][0-9]|[1-4][0-9]{2}|500$",message = "First is outside the range.")//500まで 5 private String First; 6 7 @NotNull(message = "Last is required.") 8 @Pattern(regexp="^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$",message = "Last is invalid.")//IPv4 9 private String Last; 10}

Controll.java

java

1@RestController 2@RequestMapping("/api") 3@CrossOrigin(origins = "http://localhost:3000") 4public class AuthenticationController { 5 @PostMapping("/send") 6 public ResponseEntity<Response> process(@Validated @RequestBody Request Request) throws Exception{ 7 8 Response Response = new Response(); 9 Response.setData("ok !"); 10 return ResponseEntity.ok(Response); 11 } 12}

ControllerErrorHandler.java

java

1@ControllerAdvice 2public class ControllerErrorHandler extends ResponseEntityExceptionHandler { 3 4 @Override 5 protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, 6 HttpStatus status, WebRequest request) { 7 FieldErrorResponse fieldErrorResponse = new FieldErrorResponse(); 8 9 List<CustomFieldError> fieldErrors = new ArrayList<>(); 10 ex.getBindingResult().getAllErrors().forEach((error) -> { 11 CustomFieldError fieldError = new CustomFieldError(); 12 fieldError.setField(((FieldError) error).getField()); 13 fieldError.setMessage(error.getDefaultMessage()); 14 fieldErrors.add(fieldError); 15 }); 16 17 fieldErrorResponse.setFieldErrors(fieldErrors); 18 return new ResponseEntity<>(fieldErrorResponse, headers, status); 19 } 20}

CustomFieldError.java

java

1public class CustomFieldError { 2 3 private String field; 4 private String message; 5}

FieldErrorResponse.java

java

1public class FieldErrorResponse { 2 3 private List<CustomFieldError> fieldErrors; 4}

Getter,Setterは省略しています。

###試したこと
Request.java内のアノテーションをすべて外しControllクラス内でformからのリクエストを確認しましたが、First,Lastどちらの値もnullになっていました。

補足情報(FW/ツールのバージョンなど)

SpringBoot version : 2.6.2

package.json

"dependencies": { "@testing-library/jest-dom": "^5.16.1", "@testing-library/react": "^12.1.2", "@testing-library/user-event": "^13.5.0", "axios": "^0.24.0", "bootstrap": "^5.1.3", "react": "^17.0.2", "react-bootstrap": "^2.0.4", "react-dom": "^17.0.2", "react-redux": "^7.2.6", "react-router-dom": "^6.2.1", "react-scripts": "5.0.0", "redux": "^4.1.2", "styled-components": "^5.3.3", "web-vitals": "^2.1.2" },

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2022/01/05 23:21

stringifyすると単なる文字列になるように思うのですが、stringifyなしだとどうでしょうか。
cantama

2022/01/05 23:41

stringifyなしというのが分からないのですが、 JSON()で送信した場合は、JSON is not a functionとなりました。 また、PostmanでJSONにして送りましたが、nullが返ってきました。
m.ts10806

2022/01/06 00:51

いえ body: JSON.stringify({ First: formData.get('First'), Last: formData.get('Last'), }), ↓ body: { First: formData.get('First'), Last: formData.get('Last'), },
m.ts10806

2022/01/06 00:51

ただ、見た感じbodyにそのままformDataを指定するだけで良いような
cantama

2022/01/06 01:27

body: { First: formData.get('First'), Last: formData.get('Last'), }, で送信しましたが、 http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `com.example.main.requests.Request` from Array value (token `JsonToken.START_ARRAY`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.example.main.requests.ApiRequest` from Array value (token `JsonToken.START_ARRAY`)<EOL> at [Source: (PushbackInputStream); line: 1, column: 1]] 逆シリアル化に失敗と出ました。 この場合はどう対処すればいいのでしょうか?
m.ts10806

2022/01/06 03:14

となると、 body:formData, でも同じですかね。 formDataに想定の値は入ってきてますか? 何も入ってなければnullと判断されるのは合点がいきます
cantama

2022/01/06 04:14

Requestクラスの変数定義に頭文字を大文字にしており、そのGetter名とSetter名と重複していたためにPOST出来ていなかった可能性がありました。 ちゃんと確認しておりませんが、頭文字をすべて小文字に訂正することでエラーが起きなくなりました。
guest

回答1

0

自己解決

@Data
public class Request{

private String first; //First => first private String last; //Last => last

}
Getter名とSetter名がそれぞれFirst,Lastとなって重複していたので、頭文字を小文字に訂正

投稿2022/01/06 04:23

cantama

総合スコア20

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問