Spring: Best Ways to return HTTP 400 Bad Request


In HTTP requests, a 400 Bad Request response status code indicates that the server cannot process the request due to a client error (eg. malformed request syntax, invalid request message framing, or deceptive request routing).

In Spring controller in most cases, the Spring framework handles most of the syntax and payload validation and responds 400 bad requests. But many times we need to do more validation of the request payload or during processing, our code determines the wrong parameters and returns a Bad request.

To do this first of all you need to change the return type to ResponseEntity<>, and then you can use the below for return 400 status:

    @ApiOperation(value = "Add new email and company for 2F authentication",response = TotpResource.class)
    @PostMapping(consumes = "application/json", produces = "application/json")
    public ResponseEntity<TotpResource> addNew(@Valid @RequestBody TotpResource totpResource) {
        if(Strings.isStringEmpty(totpResource.getEmailId()){
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
        totpResource = this.totpService.addNew(totpResource);

        return ResponseEntity.created(URI.create("/" + totpResource.getEmailId())).body(totpResource);
    }

After Spring 4.1 there are helper methods in ResponseEntity util class which could be used as:

    @ApiOperation(value = "Add new email and company for 2F authentication",response = TotpResource.class)
    @PostMapping(consumes = "application/json", produces = "application/json")
    public ResponseEntity<?> addNew(@Valid @RequestBody TotpResource totpResource) {
        if(Strings.isStringEmpty(totpResource.getEmailId()){
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(Arrays.asList(new String[]{"err1, err2"}));
        }
        totpResource = this.totpService.addNew(totpResource);

        return ResponseEntity.created(URI.create("/" + totpResource.getEmailId())).body(totpResource);
    }

It is always good to return a detailed error message in a bad request response body, that will be used to understand the problem by the client.

Another way but not the best ways if you don't want to change the the return type and other things then you just add HttpServletResponse response in the existing method, if not present already, and set the response status as given below.

@RequestMapping(value = "/matches/{matchId}", produces = "application/json")
@ResponseBody
public String matchMethod(@PathVariable String matchId, @RequestBody String body,
            HttpServletRequest request, HttpServletResponse response) {
    String json = matchService.getMatchJson(matchId);
    if (json == null) {
        response.setStatus( HttpServletResponse.SC_BAD_REQUEST  );
    }
    return json;
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.