APR
APR

Reputation: 21

Validate request parameter Date in spring rest controller

I want to validate date as request parameter.

My endpoint url is like

http://localhost:8080/api/get/getCurrencyRate?date=02-20-2017

Controller:

@RequestMapping(value = "/getCurrencyRate", produces={"application/json"}, 
method = RequestMethod.GET)
public CurrenctRate getCurrencyrate(@RequestHeader ("Authorization") String 
authorization, @RequestParam(value="date") @DateTimeFormat(pattern="MM-dd-
yyyy") @Valid Date date) throws Exception {

For the above input (02-20-2017) service is working fine. I want to validate the request param send appropiate response to the user. How can I do that.

e.g. if the request is like

http://localhost:8080/api/get/getCurrencyRate?date=02/20/2017

response should be "Please enter date in "MM-DD-YYYY" format"

whereas now I am getting

Error code **400**
<b>JBWEB000069: description</b>
        <u>JBWEB000120: 

 - The request sent by the client was syntactically incorrect.

</u>

Please advice.

Upvotes: 2

Views: 18419

Answers (3)

APR
APR

Reputation: 21

I created custom exception handler extending ResponseEntityExceptionHandler with @ControllerAdvice. where I override handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request). This way I created handled the exception and created my own response.

Please refer below:

@Override
protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
    char quotes='"';
    String error ="Invalid date "+ quotes+ ex.getValue()+quotes +".. Please enter date in  MM/dd/YYYY.";
    err (error);
    CustomException customExcepton = new CustomException (HttpStatus.BAD_REQUEST, "101", ex.getLocalizedMessage(), error);
    return new ResponseEntity <Object> (customExcepton, new HttpHeaders(), customExcepton.getStatus());

}

My CustomException class is:

@JsonInclude(Include.NON_NULL) public class CustomException implements Serializable {

private static final long serialVersionUID = -6839345326601547899L;

private HttpStatus status;

private String exceptionCode;

private String exceptionMessage;

private List <String> errors = null;

public CustomException() {
    // Default
}
public CustomException (HttpStatus status, String exceptionCode, String exceptionMessage, String error) {
    super();
    this.status = status;
    this.exceptionCode = exceptionCode;
    this.exceptionMessage = exceptionMessage;
    this.errors = Arrays.asList (error);
}

//getters and setters

Upvotes: 0

Amit K Bist
Amit K Bist

Reputation: 6818

You have to use @ControllerAdvice, create exception handler for MethodArgumentTypeMismatchException exception type and also create class for your proper exception class which you need to send as a response to the client. For instance,

I have @ControllerAdvice class RestErrorHandler with below exceptionhandler for HttpMessageNotReadableException exception.

@ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ResponseEntity<ValidationErrorDTO> processValidationIllegalError(HttpMessageNotReadableException ex,
            HandlerMethod handlerMethod, WebRequest webRequest) {

        Throwable throwable = ex.getMostSpecificCause();
        ValidationErrorDTO errorDTO = new ValidationErrorDTO();
        if (throwable instanceof EnumValidationException) {

            EnumValidationException exception = (EnumValidationException) ex.getMostSpecificCause();

            errorDTO.setEnumName(exception.getEnumName());
            errorDTO.setEnumValue(exception.getEnumValue());
            errorDTO.setErrorMessage(exception.getEnumValue() + " is an invalid " + exception.getEnumName());
        }

        return new ResponseEntity<ValidationErrorDTO>(errorDTO, HttpStatus.BAD_REQUEST);
    }

ValidationErrorDTO is the class having few setter/getters and when HttpMessageNotReadableException exception occurs then send ValidationErrorDTO in the response with the message which I want the client to see.

Upvotes: 0

Buhake Sindi
Buhake Sindi

Reputation: 89169

The best solution I can think of is to have methods for all types of date format BUT formation the path, or use path parameters, like so:

//Using Path
@RequestMapping(value = "/getCurrencyRate/{date}", produces={"application/json"}, method = RequestMethod.GET)
public CurrenctRate getCurrencyRateOfDate(@RequestHeader ("Authorization") String authorization, @PathVariable("date") @DateTimeFormat(pattern="MM/dd/yyyy") @Valid Date date) throws Exception {

OR, with request parameter

//Using Request Parameter
@RequestMapping(value = "/getCurrencyRate", produces={"application/json"}, method = RequestMethod.GET)
public CurrenctRate getCurrencyrate(@RequestHeader ("Authorization") String authorization, @RequestParam(value="date") @DateTimeFormat(pattern="MM/dd/yyyy") @Valid Date date) throws Exception {

That way, Spring REST can match your request to your API call.

Upvotes: 2

Related Questions