Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BindingResult support for constructor argument mismatch on immutable data object [SPR-15542] #20101

Closed
spring-issuemaster opened this issue May 14, 2017 · 2 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented May 14, 2017

Kazuki Shimizu opened SPR-15542 and commented

I've tried the the request data binding feature for immutable object. It's work fine. However binding error(such as type conversion error) can not handle using the BindingResult as follow:

package com.example;

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.time.LocalDate;

@RestController
public class ImmutableObjectRestController {

	@GetMapping("/immutable")
	Query search(@Validated Query query, BindingResult bindingResult) {
		System.out.println(bindingResult);
		return query;
	}

	public static class Query {

		@NotNull private final String name;
		private final String mail;
		private final String tel;
		private final LocalDate baseDate;

		public Query(String name, String mail, String tel,
				@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate baseDate) {
			this.name = name;
			this.mail = mail;
			this.tel = tel;
			this.baseDate = baseDate;
		}

		public String getName() {
			return name;
		}

		public String getMail() {
			return mail;
		}

		public String getTel() {
			return tel;
		}

		public LocalDate getBaseDate() {
			return baseDate;
		}

	}

}

A validation error(e.g. name parameter is null) can handle above implementation.

$ curl -D - http://localhost:8080/immutable?mail=kazuki43zoo@gmail.com\&tel=09012345678\&baseDate=2017-08-01

print on console as follow:

org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'query' on field 'name': rejected value [null]; codes [NotNull.query.name,NotNull.name,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [query.name,name]; arguments

However a binding error(e.g. baseDate parameter is nonexistence date) can not handle above implementation.

$ curl -D - http://localhost:8080/immutable?mail=kazuki43zoo@gmail.com\&tel=09012345678\&baseDate=2017-08-32
HTTP/1.1 400 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 14 May 2017 11:20:29 GMT
Connection: close

{"timestamp":"2017-05-14T11:20:29.495+0000","status":400,"error":"Bad Request","message":"Failed to convert value of type 'java.lang.String[]' to required type 'java.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.format.annotation.DateTimeFormat java.time.LocalDate] for value '2017-08-32'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2017-08-32]","path":"/immutable"}

Is specification this behavior ?


Affects: 5.0 RC1

Reference URL: #19763

Issue Links:

  • #19763 Data binding with immutable objects (Kotlin / Lombok / @ConstructorProperties)
  • #20232 Kotlin class instantiation with optional parameters and default values
  • #20994 Cannot create BindStatus for valid field on immutable form object in case of bind errors
  • #20432 Revisit handling of missing fields (without default values) for immutable data classes
  • #20426 Immutable object constructor arguments not considering WebDataBinder's FIELD_MARKER_PREFIX

Referenced from: commits 61cdc84

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented May 15, 2017

Juergen Hoeller commented

The problem there is that we can't even construct the parameter object in such a case, since such validation fails at constructor argument level. We'd have to pass in null for the Query object in your case, exposing just a BindingResult for it. I'll revisit this for RC2.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Aug 17, 2017

Juergen Hoeller commented

We're explicitly handling a constructor argument resolution mismatch as binding failure now, manually registering FieldErrors for such arguments and exposing them the same way as bean property binding exceptions or post-construction validation exceptions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.