Java HTTP Adapter

improve this page | report issue

Overview

This tutorial is a continuation of the Java adapters tutorial and assumes previous knowledge of the concepts that are described there.

Java adapters gives you control over connectivity to your back end. It is therefore your responsibility to ensure best practices regarding performance and other implementation details.

This tutorial shows an example of a Java adapter that connects to an RSS feed by using a Java HttpClient, and covers the following topics:

RSSAdapterApplication

RSSAdapterApplication extends MFPJAXRSApplication and is a good place to trigger any initialization required by your application.

	@Override
	protected void init() throws Exception {
		RSSAdapterResource.init();
		logger.info("Adapter initialized!");
	}
 

RSSAdapterResource

@Path("/")
public class RSSAdapterResource {
}
 

RSSAdapterResource handles the requests to your adapter.

@Path("/") means that the resources are available at this URL: http(s)://host:port/ProjectName/adapters/AdapterName/

HTTP client

	private static CloseableHttpClient client;
	private static HttpHost host;
	public static void init() {
		client = HttpClients.createDefault();
		host = new HttpHost("rss.cnn.com");
	}
 

Because each request to your resource creates a new instance of RSSAdapterResource, it is important to reuse objects that might impact performance. In this example, the Http client is a static object and is initialized in a static init method, which gets called by the init method of RSSAdapterApplication, as described above.

Procedure resource

	@GET
	@Produces("application/json")
	public void get(@Context HttpServletResponse response, @QueryParam("topic") String topic)
			throws ClientProtocolException, IOException, IllegalStateException, SAXException {
		if(topic!=null && !topic.isEmpty()){
			execute(new HttpGet("/rss/edition_"+ topic+".rss"), response);
		}
		else{
			execute(new HttpGet("/rss/edition.rss"), response);
		}
	}
 

This adapter exposes just one resource URL which allows you to retrieve the RSS feed from the back-end service.

  • @GET means that this procedure responds only to HTTP GET requests.
  • @Produces("application/json") specifies the Content Type of the response to send back. The adapter sends the response as a JSON object to make it easier on the client side.
  • Use @Context HttpServletResponse response to write to the response output stream. This enables more granularity than returning a simple string.
  • @QueryParam("topic") The topic String parameter enables the procedure to receive a parameter. The choice of QueryParam means that the parameter is to be passed in the query (/RSSAdapter/?topic=technology). Other options include @PathParam, @HeaderParam, @CookieParam, @FormParam, etc.
  • throws ClientProtocolException, ... means that any exception is forwarded back to the client. The client code is responsible for handling potential exceptions, which are received as HTTP 500 errors. Another solution (more likely in production code) is to handle exceptions in the server Java code and decide what to send to the client, based on the exact error.
  • execute(new HttpGet("/rss/edition.rss"), response). The actual HTTP request to the back-end service is handled by another method, which is defined later.

Depending on whether you pass a topic parameter, the execute method builds a different path and retrieve a different RSS file.

execute()

	public void execute(HttpUriRequest req, HttpServletResponse resultResponse)
			throws ClientProtocolException, IOException,
			IllegalStateException, SAXException {
		HttpResponse RSSResponse = client.execute(host, req);
		ServletOutputStream os = resultResponse.getOutputStream();
		if (RSSResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
			resultResponse.addHeader("Content-Type", "application/json");
			String json = XML.toJson(RSSResponse.getEntity().getContent());
			os.write(json.getBytes(Charset.forName("UTF-8")));
		}else{
			resultResponse.setStatus(RSSResponse.getStatusLine().getStatusCode());
			RSSResponse.getEntity().getContent().close();
			os.write(RSSResponse.getStatusLine().getReasonPhrase().getBytes());
		}
		os.flush();
		os.close();
	}
 

  • HttpResponse RSSResponse = client.execute(host, req). The static HTTP client is used to execute the HTTP request and store the response.
  • ServletOutputStream os = resultResponse.getOutputStream(). This is the output stream to write a response to the client.
  • resultResponse.addHeader("Content-Type", "application/json"). As mentioned before, the response is sent in JSON format.
  • String json = XML.toJson(RSSResponse.getEntity().getContent()). The adapter uses org.apache.wink.json4j.utils.XML to convert the XML RSS to a JSON string.
  • os.write(json.getBytes(Charset.forName("UTF-8"))) the resulting JSON string is written to the output stream.
  • The output stream is then flushed and closed.

If RSSResponse is not 200 OK, the status code and reason are written in the response instead.

Results

Use the testing techniques as described in the Java adapter tutorial to test your work.

The adapter should return the RSS feed converted to JSON.

{
   "rss": {
      "channel": {
         "copyright": "Copyright 2015 Cable News Network LP, LLLP.",
         "description": "CNN.com delivers up-to-the-minute news and information on the latest top stories, weather, entertainment, politics and more.",
         "image": {
            "description": "CNN.com delivers up-to-the-minute news and information on the latest top stories, weather, entertainment, politics and more.",
            "height": "33",
            "link": "http:\/\/edition.cnn.com\/index.html?eref=edition",
            "title": "CNN.com - Top Stories",
            "url": "http:\/\/i.cdn.turner.com\/cnn\/.e\/img\/1.0\/logo\/cnn.logo.rss.gif",
            "width": "144"
         },
         "info": {
            "uri": "rss\/edition"
         },
         "item": [
            {
               "content": {
                  "height": "51",
                  "medium": "image",
                  "type": "image\/jpeg",
                  "url": "http:\/\/i2.cdn.turner.com\/cnn\/dam\/assets\/150301114729-russia-nemtsov-protest-top-tease.jpg",
                  "width": "90"
               },
               "description": "It was supposed to be an opposition rally against Russia's policies in Ukraine, but following the slaying of Boris Nemtsov, the march has taken on a different theme.",
               "guid": "http:\/\/edition.cnn.com\/2015\/03\/01\/europe\/russia-opposition-leader-killed\/index.html",
               "link": "http:\/\/edition.cnn.com\/2015\/03\/01\/europe\/russia-opposition-leader-killed\/index.html?eref=edition",
               "pubDate": "Sun, 01 Mar 2015 07:03:36 EST",
               "thumbnail": {
                  "height": "51",
                  "url": "http:\/\/i2.cdn.turner.com\/cnn\/dam\/assets\/150301114729-russia-nemtsov-protest-top-tease.jpg",
                  "width": "90"
               },
               "title": "Thousands rally in Moscow for slain Putin critic"
            },
            {
               "content": {
                  "height": "51",
                  "medium": "image",
                  "type": "image\/jpeg",
                  "url": "http:\/\/i2.cdn.turner.com\/cnn\/dam\/assets\/150115214405-hunter-fight-boko-haram-top-tease.jpg",
                  "width": "90"
               },
               "description": "They share an apocalyptic \"end-of-days\" vision and now there are signs that Boko Haram may be edging towards a pledge of allegiance to IS leader Abu Bakr al-Baghdadi.",
               "guid": "http:\/\/edition.cnn.com\/2015\/02\/25\/world\/boko-haram-lister-analysis\/index.html",
               "link": "http:\/\/edition.cnn.com\/2015\/02\/25\/world\/boko-haram-lister-analysis\/index.html?eref=edition",
               "pubDate": "Sat, 28 Feb 2015 11:40:30 EST",
               "thumbnail": {
                  "height": "51",
                  "url": "http:\/\/i2.cdn.turner.com\/cnn\/dam\/assets\/150115214405-hunter-fight-boko-haram-top-tease.jpg",
                  "width": "90"
               },
               "title": "Boko Haram and ISIS: Planning an alliance?"
            },
            {
               "content": {
                  "height": "51",
                  "medium": "image",
                  "type": "image\/jpeg",
                  "url": "http:\/\/i2.cdn.turner.com\/cnn\/dam\/assets\/150223154312-wolf-intv-havlicek-isis-teen-girls-00020908-top-tease.jpg",
                  "width": "90"
              },
               "description": "Three teen British girls suspected of traveling to Syria appeared on surveillance video in Turkey before they went to their destination.",
               "guid": "http:\/\/edition.cnn.com\/2015\/03\/01\/europe\/turkey-uk-missing-girls\/index.html"
               "link": "http:\/\/edition.cnn.com\/2015\/03\/01\/europe\/turkey-uk-missing-girls\/index.html?eref=edition",
               "thumbnail": {
                  "height": "51",
                  "url": "http:\/\/i2.cdn.turner.com\/cnn\/dam\/assets\/150223154312-wolf-intv-havlicek-isis-teen-girls-00020908-top-tease.jpg",
                  "width": "90"
               },
               "title": "Syria: Missing UK teens caught on video"
            }
         ],
         "language": "en-US",
         "link": [
            "http:\/\/edition.cnn.com\/index.html?eref=edition",
            {
               "href": "http:\/\/rss.cnn.com\/rss\/edition",
               "rel": "self",
               "type": "application\/rss+xml"
            },
            {
               "href": "http:\/\/pubsubhubbub.appspot.com\/",
               "rel": "hub"
            }
         ],
         "pubDate": "Sun, 01 Mar 2015 10:14:59 EST",
         "title": "CNN.com - Top Stories",
         "ttl": "10"
      },
      "version": "2.0"
   }
}
 

Sample adapter and application

The attached sample includes an adapter, called RSSAdapter, and a hybrid application, called RSSReader, to test the adapter inside an application.

missing_alt

Last modified on November 09, 2016