Issue
Controller Code:
@RequestMapping(value="/update", method=RequestMethod.POST, produces =
"application/json; charset=utf-8")
@ResponseBody
public ResponseEntityWrapper update(
HttpServletRequest request,
@RequestBody @Valid InputForm form,
HttpServletResponse response
) {
//logic
}
InputForm:
public class InputForm{
@NotNull
private String formId;
private List<Employee> addEmpList;
private List<Employee> removeEmpList;
//Other fields & getters & setters.....
}
Employee:
public Employee{
@NotNull
private String empId;
private String name;
//Other fields and getters and setters.....
}
When the request to Controller's update is method, I would like to have InputForm validated - Atleast one of the fields in it is mandatory. ie., both addEmpList, removeEmpList cannot be null. And empId in Employee should not be null.
How do I do this?
Solution
This can be achieved using javax.validation.Constraint
. Annotate your controller using @Validated
annotation, and you can create your constraints as below:
Controller
import com.example.model.Employee;
import com.example.model.InputForm;
import com.example.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
@RestController
@Validated
public class MyController {
@Autowired
private MyService myService;
@RequestMapping(value="/update", method= RequestMethod.POST, produces = "application/json; charset=utf-8")
@ResponseBody
public ResponseEntity<List<Employee>> update(
HttpServletRequest request,
@CheckAtLeastOnePresentConstraint @RequestBody @Valid InputForm form,
HttpServletResponse response
) {
return new ResponseEntity<List<Employee>>(myService.getEmployees(form), HttpStatus.OK);
}
}
Contraint Interface:
import java.lang.annotation.*;
import javax.validation.Constraint;
import javax.validation.Payload;
@Constraint(validatedBy = CheckOneValuePresent.class)
@Target( { ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckAtLeastOnePresentConstraint {
String message() default "At least one of the values removeEmpList or addEmpList must be present";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
And your CustomValidator class
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class CheckOneValuePresent implements ConstraintValidator<CheckAtLeastOnePresentConstraint, InputForm> {
@Override
public boolean isValid(InputForm inputForm,
ConstraintValidatorContext cxt) {
return inputForm.getAddEmpList() != null || inputForm.getRemoveEmpList() != null;
}
}
Hope this will help.
Answered By - YoManTaMero
Answer Checked By - Katrina (JavaFixing Volunteer)