You are on page 1of 8

012 SENDING STATUS CODES & LOCATION HEADERS

SO FAR, WE HAVE BEEN LOOKING INTO SENDING ACTUAL RESPONSE, BUT IN THIS WE WILL LOOK AT
SENDING SOME OTHER THINGS WITH RESPONSE.
WHAT IF YOU WANNA CONTROL THE STATUS CODES LIKE 200 OR 404 OR ETC..WHAT IF HEADERS IN
RESPONSE SHOULD BE LITTLE MODIFIED ??
HOW TO DO THAT ??? WELL WITH PREVIOUS ALL EXAMPLES IT WAS NOT POSSIBLE, AS WE ARE JUST
SENDING RESPONSE CONTENTS ONLY.
SO HERE WE ARE GOING TO LOOK INTO HOW TO CONTROL AND SEND SOME OTHER THINGS WITH
RESPONSE APART FROM JUST CONTENTS OF MESSAGE.

AS WE HAVE DISCUSSED EARLIER WHEN A RESOURCE IS CREATED THE MOST PROPER RESPONSE
STATUS CODE WOULD BE 201 AND NOT THE 200 (WHICH IS DEFAULT & SENT TO REPRESENT
SUCCESS).

1. Before that look at what used to happen before to understand the problem definition
correctly :-

As shown above, normally 200 will be sent as status code even on completion as a success
status code and header will have 4 values by default Content-type, content-length, date
and server…
What we want is :-
1.1 when a resource is created client should get status code as 201…
1.2 Along with that there should be URI in response header which will be getting a newly
created message with this post request..
2. Lets look at sending status code first… That’s very simple and code itself will explain the
way to do that.

package com.module;

import java.util.List;

import javax.ws.rs.BeanParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.jboss.resteasy.plugins.server.servlet.FilterBootstrap;

import com.module.beans.MessageFilterBeans;
import com.module.model.Message;
import com.module.service.MessageService;

@Path("/messages")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public class MessageResource {

MessageService messageService=new MessageService();

@GET
public List<Message> getMessages(@QueryParam("year") int
year,@QueryParam("start") int start,@QueryParam("size") int size){
if(year>0){
return messageService.getAllMessagesForYear(year);
}
if(start>=0 && size>0){
return messageService.getMessagesPaginated(start,
size);
}
return messageService.getAllMessages();
}
@GET
@Path("/test")
@Produces(MediaType.TEXT_PLAIN)
public String test1(){
return "test";
}

@GET
@Path("/{messageId}")

public Message getPerticularMessage(@PathParam("messageId")long


id){
return messageService.getMessage(id);
}

@PUT
@Path("/{messageId}")
public Message updateMessage(@PathParam("messageId") long id,
Message message){
message.setId(id);
return messageService.updateMessage(message);
}

@DELETE
@Path("/{messageId}")
public void deleteMessage(@PathParam("messageId") long id){
messageService.removeMessage(id);
}

//################# FOR STATUS & HEADERs


##########################
//THERE ARE MULTIPLE WAYS TO SET THESE VALUES..
//ONE IS USING RESPONSE CLASS FROM THE DEFAULT CORE PACKAGE -
JAVAX.WS.RS.CORE.
// IN THAT YOU WILL HAVE TO TO USE RESPONSEBUILDER TO ACTUALLY
BUILD THE RESPONSE.
// SO LET US MODIFY THE ADD MESSAGE METHOD AS FOLLOWS

@POST
public Response addMessage(Message message){
//Response.status(Status.CREATED) => setting status code 201
which is for created..
//.entity(newMessage) along with status...response contains
the entity specified here..
//.build() => to finally build the whole response before sending.
Message newMessage=messageService.addmessage(message);;
return Response.status(Status.CREATED)
.entity(newMessage)
.build();

//return messageService.addmessage(message);
}
@Path("/{messageId}/comments")
public CommentResource getComment(){
//we are creating new instance of resource which actually does
work for us
//we are creating instance of CommentResource class
return new CommentResource();
}

3. After doing above step for setting only status code of created, lets look at POSTMAN
screenshot showing status code as 201.

4. Now let us have look at setting header value too. In this there are multiple ways to set it.
We can add that by doing like following too

@POST
public Response addMessage(Message message){
//Response.status(Status.CREATED) => setting status code 201
which is for created..
//.entity(newMessage) along with status...response contains
the entity specified here..
//.build() => to finally build the whole response before sending.

Message newMessage=messageService.addmessage(message);;
return Response.status(Status.CREATED)
.entity(newMessage)
.header(key,value) //ie:-header(location , actual URI)
.build();

//return messageService.addmessage(message);
}

5. But above way is not correct or standard way to do that. There is better way than this.
@POST
public Response addMessage(Message message) throws
URISyntaxException{
//Response.status(Status.CREATED) => setting
status code 201 which is for created..
//.entity(newMessage) along with
status...response contains the entity specified here..
//.build() => to finally build the whole response
before sending.
Message
newMessage=messageService.addmessage(message);;

/* return Response.status(Status.CREATED)
.entity(newMessage)
.build();
*/ //return messageService.addmessage(message);

//there is a shortcut to set response status


code and header at once

//1. Response.created(location); => sets status


code to 201..as it says word CREATED...and also takes
location as URI in argument

return Response.created(new
URI("/TEST_D_REST_StatusCodes_LocationHeaders/messages"+newM
essage.getId()))
.entity(newMessage)
.build();
}

6. Now after doing above step, we are setting not on ly the status code to 200 but also we
are sending URI to access the location of Newly created message.
Look at following screenshot from POSTMAN

7. Now we got both status code and response as we decided in the response… But see in
above example response header location was hard coded..as
application_name/resource…. It was hard coded…and also we were throwing
exception..ITS BAD PRACTICE
So there can even be a better way than this for doing it.
The above code is modified as follows with some good practice

//################# FOR STATUS & HEADERs ##########################

//see below..as we are not going to do any conversion of URIs so


the throws also gone from method

@POST
public Response addMessage(Message message,@Context UriInfo
uriInfo) {
//Response.status(Status.CREATED) => setting status
code 201 which is for created..
//.entity(newMessage) along with status...response
contains the entity specified here..
//.build() => to finally build the whole response
before sending.

/* return Response.status(Status.CREATED)
.entity(newMessage)
.build();
*/ //return messageService.addmessage(message);

//there is a shortcut to set response status code and


header at once

//1. Response.created(location); => sets status code to


201..as it says word CREATED...and also takes location as URI in
argument

/*return Response.created(new
URI("/TEST_D_REST_StatusCodes_LocationHeaders/messages/"+newMessage
.getId()))
.entity(newMessage)
.build();*/

//the problem with above code is that


//response header location was hard coded..as
application_name/resource….
//It was hard coded…and also we were throwing
exception..ITS BAD PRACTICE
//So there can even be a better way than this for doing
it.
//how can you get header location value ???? ANY
GUESS???? => we have used it previously...
//using @Context annotation
//@Context uriInfo will give us complete URI...
//so the same is added in method parameter here

Message newMessage=messageService.addmessage(message);;
// suppose getting URI info as below
/*
URI uri=uriInfo.getAbsolutePath();
String newId=String.valueOf(newMessage.getId());
*/
//to add this newId to uri..we need to follow
// 1. convert uri to string
// 2. concatinate it..String abc=uri.toString()+newId;
// 3. again covert back from string to URI

//Rahter than doing so many steps..we can directly use


getAbsolutePathBuilder and do both work at once..

String newId=String.valueOf(newMessage.getId());
URI
uri=uriInfo.getAbsolutePathBuilder().path(newId).build();
// adding newId in the path we have got from uriInfo

//thats it...done...a single line to remove whole


procedure
//we can directly use above uri while bulding our
response
return Response.created(uri)
.entity(newMessage)
.build();
}
8. Same result will be displayed in POSTMAN.

You might also like