Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

After I wrote my own HttpClient ResponseHandler in Apache HttpClient 4 Custom Bytes ResponseHandler, I discovered that there might be a better way. I had used the following utility to get the bytes. I found that one of their classes also used it.

EntityUtils.toByteArray(entity);

Here is what I came up with…

    /**
     * Get the weather radar bytes image.
     * @return byte[] of weather radar data
     */
    @Nullable
    public BufferedHttpEntity getWeatherRadarBytes() {
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet("http://services.intellicast.com/200904-01/387694749/Image/Radar/Winter%20Storm%20Mosaic/Loop/SectorName/bwg");


        BufferedHttpEntity bufferedHttpEntity = null;
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            bufferedHttpEntity = new BufferedHttpEntity(httpEntity);
        } catch (IOException e) {
            log.error("IOException", e);
        } finally {
            // When HttpClient instance is no longer needed,
            // shut down the connection manager to ensure
            // immediate deallocation of all system resources
            httpClient.getConnectionManager().shutdown();
        }
        return bufferedHttpEntity;
    }

An example of using it would be something like the following. NOTE: I never ran this code. Use at your own risk.

    @Test
    public void testGetWeatherRadar() {
        BufferedHttpEntity bufferedHttpEntity = httpService.getWeatherRadarBytes();
        assertNotNull(bufferedHttpEntity);
        assertTrue(bufferedHttpEntity.getContentLength() > 0);

        FileOutputStream fileOutputStream = null;
        try {
            File file = new File("/staticfiles/weather-portlet/kyRadarImage.gif");
            fileOutputStream = new FileOutputStream(file);
            byte[] bytes = new byte[bufferedHttpEntity.getContent().available()];
            bufferedHttpEntity.getContent().read(bytes);
            fileOutputStream.write(bytes);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            fail(e.getMessage());
        } catch (IOException e) {
            fail(e.getMessage());
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    fail(e.getMessage());
                }
            }
        }
    }

December 11th, 2014

Posted In: Java

Tags: , , , ,

Leave a Comment

An interesting thing I needed was to retrieve an image from a URL. HttpClient provides a BasicResponseHandler, which returns a String. I needed bytes in order to accomplish this, I had to implement my own response handler.

    /**
     * Get the weather radar bytes image.
     * @return byte[] of weather radar data
     */
    @Nullable
    public byte[] getWeatherRadarBytes() {
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet("http://services.intellicast.com/200904-01/387694749/Image/Radar/Winter%20Storm%20Mosaic/Loop/SectorName/bwg");

        ResponseHandler<byte[]> responseHandler = new ResponseHandler<byte[]>() {
            @Nullable
            public byte[] handleResponse(
                HttpResponse response) throws IOException {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    return EntityUtils.toByteArray(entity);
                } else {
                    return null;
                }
            }
        };

        byte[] responseBody = null;
        try {
            responseBody = httpClient.execute(httpGet, responseHandler);
        } catch (IOException e) {
            log.error("IOException", e);
            //e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } finally {
            // When HttpClient instance is no longer needed,
            // shut down the connection manager to ensure
            // immediate deallocation of all system resources
            httpClient.getConnectionManager().shutdown();
        }
        return responseBody;
    }

December 11th, 2014

Posted In: Java

Tags: , , , , ,

One Comment

In a previous post HttpClient 4 Json Post I showed how to post a Json object to a URL. That was useful, but required writing a method for each type of object you needed posted. A cleaner way is to use Java Generics to make a method that can accept multiple types of objects and can even return specific objects instead of a Json string.

    /**
     * Returns the http response as the specified object.
     * @param url the url to request
     * @param object the object to convert to the json payload
     * @param responseType the object type to convert the json response into
     * @throws IOException
     */
    public static <T> T postForObject(String url, Object object, Class<T> responseType) throws IOException {
        log.debug("Post: " + url);
        String response = "";
        HttpClient httpclient = new DefaultHttpClient();
        try {
            HttpPost httpPost = new HttpPost(url);
            StringEntity stringEntity = new StringEntity(JsonUtils.toJson(object));
            httpPost.setEntity(stringEntity);
            httpPost.setHeader("Content-type", "application/json");
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            response = httpclient.execute(httpPost, responseHandler);
        } catch (IOException e) {
            log.error("IOException from " + url + " with " + object , e);
            throw e;
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
        return JsonUtils.toObject(response, responseType);
    }

The method return type is modified to return T and the method signature is changed to include Class responseType. Then responseType is used to tell the Json library what type of object is desired.

Here is a simple usage of the post method.

            AccountResponse accountResponse =
                    HttpUtils.postForObject(Server.IGP_ADAPTER_URL + "/accountBalances",
                            accountRequest,
                            AccountResponse.class);

December 11th, 2014

Posted In: Java

Tags: , , , , , , ,

Leave a Comment

Posting JSON to a URL is a common use case. Here is a follow-on to HttpClient Post for a String.

    /**
     * Performs HTTP post.
     * @param url http resource to post
     * @return string response
     */
    protected String post(String url, MyJsonObject myJsonObject) {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        String responseBody = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            StringEntity stringEntity = new StringEntity(JsonUtils.toJson(myJsonObject));
            httpPost.setEntity(stringEntity);
            httpPost.setHeader("Content-type", "application/json");
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            responseBody = httpclient.execute(httpPost, responseHandler);
        } catch (IOException e) {
            log.error("IOException from " + url + " with " + object , e);
            throw e;
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
        return responseBody;
    }

Line 13 and 14 convert the object to be posted into a Json string and set it as the payload to be sent to the URL.
Line 15 sets the content type so the URL knows that you can accept JSON as a response.

December 11th, 2014

Posted In: Java

Tags: , , , ,

5 Comments

LinkedIn Auto Publish Powered By : XYZScripts.com