Reputation: 677
I have a form with a Double field. When I add a value which is not a Double ('foo') it should give me a BeanPropertyBindingResult
with an error for that field. But instead i get a HttpMessageNotReadableException
.
The strange thing is that from my JUnit test I do get the BeanPropertyBindingResult
Here is my code (i try to focus on what I think is needed if more is needed I will provide it).
I have an Angular frontend:
First here is the error i get from Angular:
2018-05-22 11:28:59.143 WARN 1262 --- [ XNIO-8 task-4] o.z.p.spring.web.advice.AdviceTrait : Bad Request: JSON parse error: Can not deserialize value of type java.lang.Double from String "dddddddd": not a valid Double value; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.lang.Double from String "dddddddd": not a valid Double value at [Source: java.io.PushbackInputStream@36d5105f; line: 1, column: 1294] (through reference chain: nl.tibi.sbys.service.dto.ProjectDTO["travelRate"]) 2018-05-22 11:28:59.146 WARN 1262 --- [ XNIO-8 task-4] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize value of type java.lang.Double from String "dddddddd": not a valid Double value; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.lang.Double from String "dddddddd": not a valid Double value at [Source: java.io.PushbackInputStream@36d5105f; line: 1, column: 1294] (through reference chain: nl.tibi.sbys.service.dto.ProjectDTO["travelRate"])
when i run the code from my junit test i get this, which is what i think is best:
2018-05-22 11:32:00.516 WARN 18426 --- [ main] o.z.p.spring.web.advice.AdviceTrait : Bad Request: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'projectDTO' on field 'travelRate': rejected value [3,5]; codes [typeMismatch.projectDTO.travelRate,typeMismatch.travelRate,typeMismatch.java.lang.Double,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [projectDTO.travelRate,travelRate]; arguments []; default message [travelRate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Double' for property 'travelRate'; nested exception is java.lang.NumberFormatException: For input string: "3,5"]
My angular code sends like this:
update( project: Project ): Observable<EntityResponseType> {
const copy = this.convert( project );
return this.http.put<Project>( this.resourceUrl, copy, { observe: 'response' } )
.map(( res: EntityResponseType ) => this.convertResponse( res ) );
}
my junit test is this:
restMockMvc.perform(post(url()).param("travelRate", "3,5").param("name", "name")).andExpect(status().isUnprocessableEntity());
My method (which is not reached because of the wrong decimal value):
@PostMapping()
@Timed
public ResponseEntity<ProjectDTO> createProject(@Valid ProjectDTO projectDTO) throws URISyntaxException {
log.debug("REST request to save Project : {}", projectDTO);
....
}
How can I get the same result from Angular as from my JUnit test? ie how do I get a BeanPropertyBindingResult?
my workaround can be adding an ExceptionHandler and parsing the string message and create the BeanPropertyBindingResult myself
Upvotes: 0
Views: 693
Reputation: 18235
The message is clear: Cannot convert a string parameter to your Double
property.
The request body reader happens before your bean validation logic so BeanPropertyBindingResult
exception does not occur.
If you want to verify input was correctly a double, you have to declare it as String
in your DTO and valid it using custom validator:
public class ProjectDTO {
@Double
String travelRate;
}
Here @Double
is your custom validator. Which is easily implemented.
Upvotes: 1