Apache CXF: JAX-RS Restful web service using @HeaderParam/@Context annotation

In this article, we will learn and implement an example to get header details of Restful web service using @HeaderParam and @Context annotations

 

@HeaderParam binds HTTP header to formal arguments of Java method
Using @Context annotation in the program, you can get all possible headers passed in the request like

  • Content-Type
  • Accept
  • User-Agent
  • Connection
  • Host
  • etc

Annotation Used

  • @HeaderParam (javax.ws.rs.FormParam)
  • @Context (javax.ws.rs.core.Context)
  • @Path (javax.ws.rs.Path)
  • @GET (javax.ws.rs.GET)
  • @Service (org.springframework.stereotype.Service)

Files like

  • pom.xml,
  • web.xml,
  • apache-cxf-service.xml

Remain the same with little modification in the package name used for the project from the previous one. Take a look at one of the following articles to understand these files and their description in detail

Now, we move on to the implementation to retrieve HTTP headers from the requesting client

Let’s see coding in action

 

Player Service interface

Defines two simple methods to retrieve HTTP header details from the requesting client

  • First method takes three-arguments which are mapped to the formal arguments using @HeaderParam annotation
  • Second method retrieves all possible header sent in the requesting client and their values using HttpHeaders which are mapped using @Context annotation

NOTE: It’s always a good programming practice to do code- to-interface and have its implementation separately

IPlayerService.java

package com.apache.cxf.headerparam.service;

import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;

@Path("/player")
public interface IPlayerService {

	// http://localhost:8080/ApacheCXF-HeaderParam/services/player/getheader
	@GET
	@Path("getheader")
	public Response getHeaderDetails(
			@HeaderParam("User-Agent") String userAgent,
			@HeaderParam("Content-Type") String contentType,
			@HeaderParam("Accept") String accept
			);

	// http://localhost:8080/ApacheCXF-HeaderParam/services/player/getallheader
	@GET
	@Path("getallheader")
	public Response getAllHeader(@Context HttpHeaders httpHeaders);
}

Player Service implementation

Implements above interface returning Response object to the requesting client

PlayerServiceImpl.java

package com.apache.cxf.headerparam.service;

import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;

import org.springframework.stereotype.Service;

@Service("playerService")
public class PlayerServiceImpl implements IPlayerService {

	@Override
	public Response getHeaderDetails(String userAgent, String contentType, String accept) {

		String header = "User-Agent: " + userAgent +
				"\nContent-Type: " + contentType +
				"\nAccept: " + accept;
		return Response.status(200).entity(header).build();
	}

	@Override
	public Response getAllHeader(HttpHeaders httpHeaders) {

		// local variables
		StringBuffer stringBuffer = new StringBuffer();
		String headerValue = "";

		for(String header : httpHeaders.getRequestHeaders().keySet()) {
			headerValue = httpHeaders.getRequestHeader(header).get(0);
			stringBuffer.append(header + ": " + headerValue + "\n");
		}
		return Response.status(200).entity(stringBuffer.toString()).build();
	}
}

 

Deployment

  • Run maven command to build the war : mvn clean install (use command prompt or integrated maven in eclipse IDE
  • Copy the war file from the target folder
  • Paste it into apache tomcat (webapps folder)
  • Start the tomcat server

Test the service !!

 

Testing

 

1. Using Google chrome web browser client

Enter URL for the 1st service: http://localhost:8080/ApacheCXF-HeaderParam/services/player/getheader

1_ApacheCXF-HeaderParam_first_service

 

Enter URL for the 2nd service: http://localhost:8080/ApacheCXF-HeaderParam/services/player/getallheader
2_ApacheCXF-HeaderParam_second_service

 

2. Java client

Uses Apache’s HttpGet class to invoke Restful web service

TestHeaderParam.java

package com.apache.cxf.headerparam.test;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

public class TestHeaderParam {

	public static void main(String[] args) {

		// invokes for first method with one argument
		String returnValue1 = testToRetrieveHeaderParams("http://localhost:8080/ApacheCXF-HeaderParam/services/player/getheader");
		System.out.println("Response from first service : \n" + returnValue1);

		// invokes for first method with three argument
		String returnValue2 = testToRetrieveHeaderParams("http://localhost:8080/ApacheCXF-HeaderParam/services/player/getallheader");
		System.out.println("\n\nResponse from second service : \n" + returnValue2);
	}

	@SuppressWarnings({ "deprecation", "resource" })
	public static String testToRetrieveHeaderParams(String uri) {

		// local variables
		HttpGet httpGet = null;
		DefaultHttpClient defaultHttpClient = null;
		HttpResponse httpResponse = null;
		HttpEntity httpEntity = null;
		InputStream inputStream = null;
		BufferedReader bufferedReader = null;
		StringBuilder stringBuilder = null;

		try {
			// http post request headers
			httpGet = new HttpGet(uri);

			// actual execution of http post
			defaultHttpClient = new DefaultHttpClient();
			httpResponse = defaultHttpClient.execute(httpGet);
			httpEntity = httpResponse.getEntity();

			// get the response content
			inputStream = httpEntity.getContent();
			bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
			stringBuilder = new StringBuilder();
			String strReadLine = bufferedReader.readLine();

			// iterate to get the data and append in StringBuilder
			while (strReadLine != null) {
				stringBuilder.append(strReadLine);
				strReadLine = bufferedReader.readLine();
				if (strReadLine != null) {
					stringBuilder.append("\n");
				}
			}
		}
		catch (UnsupportedEncodingException usee) {
			usee.printStackTrace();
		}
		catch (Exception ex) {
			ex.printStackTrace();
		}
		finally {
			// shuts down, when work done
			defaultHttpClient.getConnectionManager().shutdown();
		}
		return stringBuilder.toString();
	}
}

Output in console

Response from first service : 
User-Agent: Apache-HttpClient/4.3.2 (java 1.5)
Content-Type: null
Accept: null


Response from second service : 
connection: Keep-Alive
Content-Type: null
host: localhost:8080
user-agent: Apache-HttpClient/4.3.2 (java 1.5)

 

Conclusion: When it is required to get HTTP header details along with requesting parameters either via query/path then @HeaderParam or @Context will be quite useful

Download project

ApacheCXF-@HeaderParam-annotation (5kB)

 

Happy Coding !!
Happy Learning !!

Apache CXF: JAX-RS Restful web service using JAXB + XML example
Apache CXF: JAX-RS Restful web service using @FormParam annotation