Home > Software design >  How to use @NotEmpty by combining 2 fields?
How to use @NotEmpty by combining 2 fields?

Time:11-13

I have the following request.

@Data
public class ProductRequest {
    @NotEmpty
    private String code;

    @NotEmpty
    private String name;
}

I use this request for 2 different methods and both of them use only one field, not need the other field. Let's say that methodA using code and methodB using name field in this request (not need other field). So, in this scene I think a solution for using the same request for both methods, instead of creating 2 separate request. So, is there anything that make it possible one of the field is not null? I am also not sure if it solves my problem, because in this scene request will not know which property should not be null. Any idea to fix this problem?

CodePudding user response:

  1. You can do it with a custom validator (spring, code validation, no javax.)

  2. With javax.validation:

    • Groups sound like a perfect match for your scenario.
    • of course also achievable with a Custom Constraint. (similar to 1.)

    Drawback: you'll have to deal with your "validation structure" (@Valid vs @validated/how to pass the group)

  3. ...

CodePudding user response:

You could group your constraints so that you can tell which properties to be validated in each case. The first step is to add the attribute groups to your javax validation annotations. For that you need to create some marker interfaces, one for each of your use cases:

public interface MethodA { } // You should name this properly, it is just for demonstration purposes

public interface MethodB { }

Then you need to configure the groups attribute in your annotations:

@Data
public class ProductRequest {
    @NotEmpty(groups = MethodA.class)
    private String code;

    @NotEmpty(groups = MethodB.class)
    private String name;
}

The final step is the usage of @Validated instead of @Valid to trigger data validation. Something along the following lines:

@RequestMapping(value = "/methodA", method = RequestMethod.POST)
public String methodA(@Validated(MethodA.class) @RequestBody ProductRequest productRequest) {
    (...)
}

@RequestMapping(value = "/methodB", method = RequestMethod.POST)
public String methodB(@Validated(MethodB.class) @RequestBody ProductRequest productRequest) {
    (...)
}

You can read more about this in the following online resources:

  • Related