Skip to content

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

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

Closed
spring-projects-issues opened this issue May 14, 2017 · 2 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues 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:

Referenced from: commits 61cdc84

@spring-projects-issues
Copy link
Collaborator Author

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-projects-issues
Copy link
Collaborator Author

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
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants