Ithar
Ithar

Reputation: 5465

Spring MVC Restful service response

Any idea why I get a "HTTP/1.1 200 OK" when I set

Response.status(Response.Status.NOT_FOUND)

I can see that this has been set correctly in the response body?

curl -v http://my_host/api/v1/user/99999999

HTTP/1.1 200 OK

Access-Control-Allow-Origin: *

Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE

....

{"statusType":"NOT_FOUND","entity":"Unable to retrieve product with id:99999999","entityType":"java.lang.String","status":404,"metadata":{}}

@RequestMapping(value="/product/{id}", method=RequestMethod.GET)
@ResponseBody
public Response getProduct(@PathVariable String id) {

    Product product = null; //productService.getProduct(id);
    if (product == null) {
        // I KNOW I GET HERE !!!
        return Response.status(Response.Status.NOT_FOUND).entity("Unable to retrieve product with id:"+id). build();
    }

    // AS EXPECTED I DO NOT GET HERE
    Map<String, Object> json = productRenderer.renderProduct(....);
    return Response.ok(json, MediaType.APPLICATION_JSON).type("application/json").build();
}

BTW am using Spring version 3.2.10

Upvotes: 1

Views: 10619

Answers (2)

Ithar
Ithar

Reputation: 5465

The cause of this issue was due to the fact that the Response object was been rendered as a JSON due to the setting of the MappingJacksonHttpMessageConverter bean. Hence the HTTP response was always going to be 200 and the response body contained the JSON representation of javax.ws.rs.core.Response.

<bean id="..." class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />

To get around the problem I throw a custom exception with org.springframework.web.bind.annotation.ResponseStatus annotation :

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ProductNotFoundException extends Exception {
    ... 
}

Hence my original method now looks like:

@RequestMapping(value="/product/{id}", method=RequestMethod.GET)
@ResponseBody
public Response getProduct(@PathVariable String id) throws ProductNotFoundException {
    ...
}

Upvotes: 0

Bohuslav Burghardt
Bohuslav Burghardt

Reputation: 34826

Try returning Spring's ResponseEntity instead. It works for me and sets the correct response status:

For example:

return new ResponseEntity<>(HttpStatus.NOT_FOUND);

or with body:

return new ResponseEntity<>(body, HttpStatus.OK);

You can also use builder pattern as you do with Response in your question (following example is from ResponseEntity's JavaDoc:

return ResponseEntity
        .created(location)
        .header("MyResponseHeader", "MyValue")
        .body("Hello World");

More details can be found in the documentation:

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/ResponseEntity.html

Upvotes: 2

Related Questions