0

My url is http://localhost:8090/employee/?emp_id=1551&name=

I am using Spring boot for designing REST application. I have used @RequestMapping and @RequestParam annotation for get resource. When I pass empty value to request parameter (for eg. name = ), I get below validation response(actual output section below).

However I wanted to override this output to display customized error response as below(expected section below).
How can I achieve this? How to avoid Spring's auto validation for input parameters in Get request?

Output
======
{
    "timestamp": 1511144660708,
    "status": 400,
    "error": "Bad Request",
    "message": "Required String parameter 'name' is not present",
    "path": "/employee"
}



Expected
========

{
    "errors":[
        {
        "id":"123144",
        "detail": "invalid user input"
        "status": "400"
        }
    ]
}
Akshay
  • 3
  • 1
  • 4

1 Answers1

0

Following sample code demonstrates how to customize error message for exception handling.

  • Create 2 POJOs for your customized response body.
  • Implement 1 method to catch the MissingServletRequestParameterException exception with @ExceptionHandler annotation for missing paramters.
  • Generate the response as you expected.

Class: ResponseProperty.java

public class ResponseProperty {
    private int id;

    private String detail;

    private int status;

    //getters and setters produced by IDE
}

Class: ResponsePOJO.java

public class ResponsePOJO {
    List<ResponseProperty> errors;

    public List<ResponseProperty> getErrors() {
        return errors;
    }

    public void setErrors(List<ResponseProperty> errors) {
        this.errors = errors;
    }
}

Method: handleMethodArgumentTypeMismatch

@ExceptionHandler({ MissingServletRequestParameterException.class })
public ResponseEntity<Object> handleMethodArgumentTypeMismatch(MissingServletRequestParameterException ex) {
    ResponseProperty property = new ResponseProperty();
    property.setId(123144);
    property.setDetail("invalid user input");
    property.setStatus(400);

    ResponsePOJO responsePOJO = new ResponsePOJO();
    List<ResponseProperty> propertyList = new ArrayList<ResponseProperty>();
    propertyList.add(property);
    responsePOJO.setErrors(propertyList);

    return new ResponseEntity<Object>(responsePOJO, HttpStatus.BAD_REQUEST);
}

If you visit the endpoint /employee without required parameter, then you are going to see the response as follows:

Http Response

{
    "errors": [
        {
            "id": 123144,
            "detail": "invalid user input",
            "status": 400
        }
    ]
}

Hope this helps you! :)

UPDATE
If you want to get the request ID from header named requestId for response, you can use WebRequest to get this information as follows:

@ExceptionHandler({ MissingServletRequestParameterException.class })
public ResponseEntity<Object> handleMethodArgumentTypeMismatch(MissingServletRequestParameterException ex,
                                                               WebRequest request) {
    ResponseProperty property = new ResponseProperty();
    property.setId(Integer.valueOf(request.getHeader("requestId")));
    ...
}
LHCHIN
  • 3,679
  • 2
  • 16
  • 34
  • Thank you very much LHCHIN for detailed comment, you are awesome :) , will try that out and update you. – Akshay Nov 20 '17 at 13:23
  • LHCHIN, It worked thanks. I was trying to get the header information (request id) that comes as part of incoming request, for displaying the id attribute in response. I couldn't find that header info in handleMethodArgumentTypeMismatch method argument i.e in exception object argument. – Akshay Nov 20 '17 at 18:21
  • You are welcome! I have updated the answer above, now you can get the request ID as a part of response body. :) – LHCHIN Nov 21 '17 at 00:01
  • Yeah thanks again it worked. Just wondering whether id is more specific to system? I don't have to explicitly set/maintain id parameter in header request? As, for every request I send from SoapUI client, I always get same id. like 44444. Even though I have explicitly set the header id to some other value like 83445. However if I change the 'id' name to 'req_id', I am able to see 83445 in response. – Akshay Nov 21 '17 at 15:51
  • Where should the method `handleMethodArgumentTypeMismatch` be added? – magmine Dec 27 '21 at 22:01
  • 1
    @magmine, Hi, you can add this method in any class annotated by `@ControllerAdvice` if you're using Spring Boot. – LHCHIN Dec 28 '21 at 00:28