custom http status codes with spring mvc 3.2

POST response - Poster

POST response – Poster

I never thought creating customized http status codes would forces me to start an own sample project.

Some time ago I wanted to return customized http codes for rest resources in one of my sample projects. I started searching the web and found amongst many results some interesting such as this and that this and that . Although those websites contain detailed information, I wanted to dive deep into the subject and decided to code my own piece of code. I decided to use spring 3.2 as base of the resulting project.

Two ways of returning http status codes are implemented in the code:

  • returning a ResponseEntity
  • throwing an Exception

(both in the controller class of the sample project) .
Returning a ResponseEntity instance is quite easy. There is a list of several constructors you can choose from.
This code snippet shows two different constructor calls:

    @RequestMapping(value = "/{itemID}", method = RequestMethod.PUT, produces="application/json")
    ResponseEntity addItem(@PathVariable final String itemID, @RequestBody final Item item, HttpServletRequest request  ) {
        RESTItem inserted = null;
            inserted = itemService.insertItem(itemID, item);
        }catch(ItemAlreadyExistsException iaee){
            HttpHeaders responseHeaders = new HttpHeaders();
            ResponseEntity re;
                responseHeaders.setLocation(new URI(request.getRequestURL().toString()));
                re = new ResponseEntity(responseHeaders, HttpStatus.SEE_OTHER);
            }catch (URISyntaxException urise){
                log.error("URISyntaxException: " + urise + " n");
                re = new ResponseEntity(HttpStatus.SEE_OTHER);
            return re;
        return new ResponseEntity(HttpStatus.CREATED);

The other approach is throwing an Exception.

    @RequestMapping(value = "/{itemID}", method = RequestMethod.POST, produces="application/json")
    RESTItem udpateItem(@PathVariable final String itemID, @RequestBody final Item item) {
        RESTItem updated = itemService.updateItemByExternalID(itemID, item.getDescription(), item.getLabel());
        if (null == updated) {
            throw new BadRequestException();
        return updated;

The exception class should extend RuntimeException and utilize spring’s @ResponseStatus annotation.
This annotation allows you to define the http code that is produced once the exception is thrown.

@ResponseStatus( value = HttpStatus.BAD_REQUEST )
public class BadRequestException extends RuntimeException{
PUT response - Poster

PUT response – Poster

The other classes in this sample project follow spring’s proposed mvc structure. My deployment uses maven’s tomcat7 plugin ( mvn tomcat7:(re)/(un)deploy ). This way the application is available via localhost on a local machine.

Often I used Poster for smoke test – so I did for this sample. One interesting detail about Poster is that it follows redirects. The addItem method showed above returns a SEE_OTHER http code including a location header if the item already exists. If the location header is followed with a get request that produces a 200/OK answer (see screenshot “PUT response – Poster” for details). Also the catalina.out log points to a 303 followed by a get request:

16962 [http-bio-8080-exec-21] DEBUG ItemController.java, addItem, 61   - e: info.lotharschulz.item.model.data.exception.ItemAlreadyExistsException: RESTItem already exists.
16963 [http-bio-8080-exec-21] DEBUG ItemController.java, addItem, 71   - re:
16969 [http-bio-8080-exec-30] DEBUG ItemController.java, getItem, 36   - RESTItem{externalID=id123,description=description,label=label}
16985 [http-bio-8080-exec-30] DEBUG AbstractMessageConverterMethodProcessor.java, writeWithMessageConverters, 150   - Written [RESTItem{externalID=id123,description=description,label=label}] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@7326cbb1]

Postman, another tool to test (RESTful) APIs shows the same follow redirection behaviour.

PUT response - POSTMAN

PUT response – POSTMAN

Automated test are not included in the project ( yet ), however one tasks would be to check the SEE_OTHER status code rather then the redirected url status code.

You can find the sample code on github: https://github.com/lotharschulz/customHTTPcodes/tree/v0.1.


Lothar Schulz

Leave a Reply

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