//
you're reading...
GZIP, Java, REST

REST Services solutions for (GZIP , DATE)

I am writing this just to help people if they are working on rest services and there are some issues which they will encounter and may spend a good amount of time figuring out the solution.
And once you get the solution , you would not find it something very tricky, they are very simple stuff but still on the web they are not specified very well in a single place. So you search and serach and then combined different information to solve the puzzle.

So Couple of issues which might help some REST guy somewhere in some corner of world looking for this solution

1.GZIP data in REST SERVICES

I had to automate one of the Rest Services and the post method would accept the request data in zipped(Gzip) format.
I was using Apache Httpclient. At first I thought it would be nothing and I would just call some method to set that data needs to be zipped before sending. But it was not the same way.
I had to explicitly do the zipping stuff and make the entity as ByteArrayEntity. I am copying the code so that it can help.

 private static byte[] gzipDataString(String requestString)
   {
	   ByteArrayOutputStream baos = new ByteArrayOutputStream();
	   GZIPOutputStream gzos = null;

	   try {
	       gzos = new GZIPOutputStream(baos);
	       gzos.write(requestString.getBytes());
	   } catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	   		} 
	   finally {
	       if (gzos != null) try { gzos.close(); } catch (IOException ignore) {};
	   	}
	   byte[] gzippedBytes = baos.toByteArray();
	   return gzippedBytes;
   }

Here requestString is the body of the request.It will be converted into byte array and then returned.

After that ByteArrayEntity is created from the byte Array and it is set into the httpPost like this

if(requestEntity.getRequestHeaders().containsKey("Content-Encoding"))
httpEntity = new ByteArrayEntity(gzipDataString(requestEntity.getRequestString()));
}
[/sourcecode ]


 http = new HttpPost(uri);<br /> ((HttpPost) http).setEntity(ent);

I faced a lot of confusion as the service which was jersey based was throwing error as it was not recognizing the data.
So had to set header Content-Type in the http request.I was using json format so I set it to application/json .
Other header which I had to set was Content-Encoding to gzip.

Also in case your service also return the data in the zipped format and you want to parse it , then you can use the following code

 public void checkCompressedData(String response)
    {
    GZIPInputStream gis=null;
	try {
		gis = new GZIPInputStream(new ByteArrayInputStream(response.getBytes()));
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
    BufferedReader bf = new BufferedReader(new InputStreamReader(gis));
    String responseString = "";
    String line;
    try {
		while ((line=bf.readLine())!=null) {
			responseString += line;
		}
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
    }

2.Alternative for sending body with the delete method call
Next a very small thing that you may encounter is that somehow the delete may contain the body.
In my case the service was recording the deleter information.
But most the of the clients supports no entity attachement with DELETE call.So the alternate is to use X-HTTP-Method-Override header.

Basically we need to send POST request and set the header with the method we would like to actually call.

http = new HttpPost(uri);
((HttpPost) http).setEntity(ent);
http.setHeader("X-HTTP-Method-Override", "DELETE");

3.Date Conversion
Jersey was used for the REST service implementation. And jersey was using Jackson parser for request processing.
The request contained of the date fields.One issue we faced was the automatic date conversion in the server’s timezone by Jackson.
So even if we sent 01-10-2010 it was converted into 31-09-20 10 since the server wasin PST timezone.We did not want that behavior.Our requirement was just to keep the data as it is in the request.
Looked for the Jackson Parser documentation and found that a deserializer needs to be implemented.So for every date field in the request this class will take care of it.Code below:

@Component
public class JsonDateDeserializer extends JsonDeserializer<Date>
{

	@Override
    public Date deserialize(JsonParser jsonparser,
            DeserializationContext deserializationcontext) throws IOException, JsonProcessingException {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String date = jsonparser.getText();
        try {
            return format.parse(date);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

}

And then mark your field with this Deserializer

@JsonProperty("start_date")
@JsonDeserialize(using = JsonDateDeserializer.class)
public Date startDate;

Now we can handle the data in according to our requirement.Also you can write a Serializer like this also if you want to convert data in response to some specific format.

Hope this post might prove helpful to somebody.

Gaurav….

Advertisements

About Gaurav Mutreja

Well I think a lot !! Now I would like to speak a bit!

Discussion

One thought on “REST Services solutions for (GZIP , DATE)

  1. Hi Gaurav, nice article, the date deserialization resolution helped me resolve something similar we were facing

    Posted by Rishi Sachania | January 12, 2017, 2:05 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: