I have a web service rest using jax-rs, my service return a List of objects but y don't know how to add custom status values to response, for example the result that I want to build is the following:
If its ok:
{
"status": "success",
"message": "list ok!!",
"clients": [{
"name": "john",
"age": 23
},
{
"name": "john",
"age": 23
}]
}
If is error:
{
"status": "error",
"message": "not found records",
"clients": []
}
my rest service:
@POST
@Path("/getById")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public List<Client> getById(Client id) {
try {
return Response.Ok(new ClientLogic().getById(id)).build();
//how to add status = success, and message = list! ?
} catch (Exception ex) {
return ??
// ex.getMessage() = "not found records"
//i want return json with satus = error and message from exception
}
}
The Response class is an abstract class that contains three simple methods. The getEntity() method returns the Java object you want converted into an HTTP message body. The getStatus() method returns the HTTP response code. The getMetadata() method is a MultivaluedMap of response headers.
Create a new ResponseBuilder for a created resource, set the location header using the supplied value. Create a new ResponseBuilder by performing a shallow copy of an existing Response. Return the response entity. Get metadata associated with the response as a map.
You can use: public abstract <T> T readEntity(Class<T> entityType) - Read the message entity input stream as an instance of specified Java type using a MessageBodyReader that supports mapping the message entity stream onto the requested type.
If you want full control on your output JSON structure, use a JsonObjectBuilder (as explained here, then convert your final json to String and write (for example for the success json):
return Response.Ok(jsonString,MediaType.APPLICATION_JSON).build();
and change your return value to a Response object.
However please note that you are trying to send redundant (and not standard) piece of information, which is already encoded into the HTTP error codes. When you use Response.Ok, the response will have code "200 OK", and you can study the Response class methods for returning any HTTP code you desire. In your case it would be:
return Response.status(Response.Status.NOT_FOUND).entity(ex.getMessage()).build();
returning a 404 HTTP code (look at Response.Status list of codes).
I was facing the same problem and here is how I solved it. If your service method succeeds, return Response with status 200 and with your desired entities. If your service method throws an exception, return Response with different status and with exception message bind to your RestError class.
@POST
@Path("/getById")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response getById(Client id) {
try {
return Response.Ok(new ClientLogic().getById(id)).build();
} catch (Exception ex) {
return Response.status(201) // 200 means OK, I want something different
.entity(new RestError(status, msg))
.build();
}
}
In client, I am using these utility methods to read entity from Response. If there is an error, I throw an exception containing status and msg of that error.
public class ResponseUtils {
public static <T> T convertToEntity(Response response,
Class<T> target)
throws RestResponseException {
if (response.getStatus() == 200) {
return response.readEntity(target);
} else {
RestError err = response.readEntity(RestError.class);
// my exception class
throw new RestResponseException(err);
}
}
// this method is for reading Set<> and List<> from Response
public static <T> T convertToGenericType(Response response,
GenericType<T> target)
throws RestResponseException {
if (response.getStatus() == 200) {
return response.readEntity(target);
} else {
RestDTOError err = response.readEntity(RestError.class);
// my exception class
throw new RestResponseException(err);
}
}
}
My client method will call (through proxy object) service method
public List<Client> getById(Client id)
throws RestResponseException {
return ResponseUtils.convertToGenericType(getProxy().getById(id),
new GenericType<List<Client>>() {});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With