4

I want to create Spring endpoint for validating Java Object. I tried to implement this example:

https://www.baeldung.com/validation-angularjs-spring-mvc

I tried this:

public class WpfPaymentsDTO {

    @NotNull
    @Size(min = 4, max = 15)
    private String card_holder;

    private String card_number;
    ....
}

End point:

 @PostMapping(value = "/payment/{unique_transaction_id}", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
      public ResponseEntity<StringResponseDTO> handleWpfMessage(@PathVariable("unique_transaction_id") String unique_transaction_id,
          @RequestBody WpfPaymentsDTO transaction, BindingResult result, HttpServletRequest request) throws Exception {

        if (result.hasErrors()) {
            List<String> errors = result.getAllErrors().stream()
              .map(DefaultMessageSourceResolvable::getDefaultMessage)
              .collect(Collectors.toList());
            return new ResponseEntity<>(errors, HttpStatus.OK);
        } 

        return ResponseEntity.ok(new StringResponseDTO("test"));
      }

When use submits Angular form I would like to validate all fields. But currently I get this error: Cannot infer type arguments for ResponseEntity<>

What is the proper wya to implement this?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808
  • Method returns `ResponseEntity` but when `hasErrors` is true, you return `ResponseEntity>`. In the example you posted, `ResponseEntity` is returned. You can make changes accordingly, either change method's return type, or set errors info in `StringResponseDTO` object and return it. – lzagkaretos Mar 31 '19 at 11:01
  • Can you paste working example please? – Peter Penzov Mar 31 '19 at 11:51
  • 1
    Show what are your expectations of responses (with/without errors) – Ori Marko Mar 31 '19 at 13:00

2 Answers2

2

try using Angular Reactive Forms (FormGroup and FormControl). I think it's easier that way.

2

You are missing the @Valid annotation in your method signature. If you look at the example you are quoting, you will see that it's used on the User object.

So in your case:

@Valid @RequestBody WpfPaymentsDTO transaction

Also you are returning two different class types in ResponseEntity<T>

1) ResponseEntity<StringResponseDTO> in a validation successful scenario

2) ResponseEntity<List<String>> in a validation failure scenario

The above is the reason for:

But currently I get this error: Cannot infer type arguments for ResponseEntity<>

If you look at the example you are quoting, the method return type is ResponseEntity<Object>.

So your method should change to:

  @PostMapping(value = "/payment/{unique_transaction_id}", 
     consumes = { MediaType.APPLICATION_JSON_VALUE }, 
     produces = { MediaType.APPLICATION_JSON_VALUE })
  public ResponseEntity<Object> handleWpfMessage(
                 @PathVariable("unique_transaction_id") String unique_transaction_id,
                 @Valid @RequestBody WpfPaymentsDTO transaction, 
                 BindingResult result, 
                 HttpServletRequest request) throws Exception {

Update:

Is there a way to find out for which variable the validation error is raised?

Yes, you can get all field binding errors like this:

List<FieldError> errors = bindingResult.getFieldErrors();
for (FieldError error : errors ) {
    System.out.println ("Validation error in field: " + error.getField() 
                    + "! Validation error message: " + error.getDefaultMessage() 
                    + "! Rejected value:" + error.getRejectedValue());
}
hovanessyan
  • 30,580
  • 6
  • 55
  • 83