2

I am trying to implement a static validation that prevents a value from being passed into a JSON payload to POST and PUT endpoints.

For example, I have this DTO:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class SampleApiDto {
    
    private long id;

    private String description;

    private String columnName;

    private String code;
}

id is a generated value on our data service side. Right now, if you provide a payload like this:

{
    "id": 123,
    "description": "test10",
    "columnName": "test",
    "code": "1"
}

it throws a detached entity error and returns 500. Ideally, I would like it to return a 400 error with a static validation that id is present in the payload. Due to the size of our codebase, we do not want to implement if statements in the controller. We would rather this be an annotation, even if it were a custom annotation.

I have tried using @Null and @JsonIgnore on the getter method, and these did not work both ways. The ID should be accessible afterwards in the DTO object from the data service.

Thanks so much!

zakpruitt
  • 162
  • 2
  • 11
  • you can check here, it is simular problem with jsonIgnore https://stackoverflow.com/questions/19894955/spring-jsonignore-not-working – Mario Petrovic May 22 '23 at 16:45

3 Answers3

0

Maybe its better to have another DTO to map requested object(here SampleApiDto) to what data layer wants.

0

You can utilize Bean Validation capabilities with validation groups to achieve your desired outcome. A validation group is a concept in Java Bean Validation that allows you to group validation constraints and apply them selectively based on different scenarios or use cases.

First, you need to define validation group marker interface:

interface OnCreate {}

Then you should add validation to your id field (I've changed a type from primitive to Long wrapper). We suppose that the client should not send id, so the field should be null:

@Null(groups = OnCreate.class)
private Long id;

Finally, in your controller, you should specify the validation group in desired endpoint:


@PostMapping("/sample")
public ResponseEntity<?> createSample(@Validated(OnCreate.class) @RequestBody SampleApiDto dto, BindingResult result) {
    if (result.hasErrors()) {
        // Handle validation errors
        return ResponseEntity.badRequest().body("Validation error");
    }
        
    // Process the payload and return appropriate response
    // ...
}

You can read more here:

https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html#validationapi-validatorapi-groups

https://jakarta.ee/specifications/bean-validation/3.0/jakarta-bean-validation-spec-3.0.html#constraintdeclarationvalidationprocess-groupsequence

And make sure your spring application is configured properly to use bean validation:

https://docs.spring.io/spring-framework/reference/core/validation/beanvalidation.html#validation-beanvalidation-overview

Yevhenii Semenov
  • 1,587
  • 8
  • 18
0

If you want to ignore this field when deserializing, you should add @ JsonIgnore to the setter method

winston
  • 37
  • 6