Hi,

Many times due to some specific requirement it is required to get the Http Headers while a webservice operation (method) is invoked. The “javax.xml.ws.WebServiceContext” and the “javax.xml.ws.handler.MessageContext” together can be used to extract the Http headers informationes inside a WebService call. MessageContext.SERVLET_REQUEST provides the access to the HttpServletRequest object from where we can even get the HttpSession.

In the following demo/sample/example we will see how we can build a WebService application using standard WebService tools like “apt” to build a webservice from POJO class and “wsimport” to generate the clientside artifacts using the ANT script. These tools are available with the JDK only so we need not to even use any Application server specific tools in order to build and deploy our webservice.

NOTE For JBoss AS7.1.1 the same Demo is available in Github:
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/WebService_HttpRequest_HttpSession_AS7

Step1). Create a directory somewhere in your file system with some name like “C:/WebService_HttpRequest_HttpSession”.

Step2). Create another directory with name “src” under “C:/WebService_HttpRequest_HttpSession” where we can place our WebService related source codes and deployment descriptors.

Step3). Write the “Greeting.java” program inside “C:/WebService_HttpRequest_HttpSession/src” directory like following:

package ws;
import javax.jws.WebService;
import javax.jws.WebMethod;
import java.util.Enumeration;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;

@WebService
public class Greeting
{
   @Resource
   WebServiceContext context;

   @WebMethod
   public String hello(String userName)
   {
      System.out.println("nt[Greeting WebService] hello() called: Welcome Mr./Ms. " + userName + "! Have a nice day...");
      return "Welcome Mr./Ms. " + userName + "! Have a nice day...";
   }

   @WebMethod
   public String getRequestHeaders()
   {
      System.out.println("nt[Greeting WebService] exploreHttpSession() called");
      MessageContext mc = context.getMessageContext();   // This is line that causes the NullPointer exception
      HttpServletRequest request = (HttpServletRequest) mc.get(MessageContext.SERVLET_REQUEST);
      HttpSession session = request.getSession(true);
      System.out.println("nt Got HttpSession  session.getId(): "+session.getId());

      System.out.println("nt Exploring HttpServletRequest Headers");
      Enumeration en = request.getHeaderNames();
      String allHttpHeaders="HEADERS: ";
      while(en.hasMoreElements())
        {
            String headerKey=(String)en.nextElement();
            String headerValue=request.getHeader(headerKey);
            System.out.println("n"+headerKey+" = "+headerValue);
            allHttpHeaders=allHttpHeaders+ "n"+headerKey+" = "+headerValue;
        }
      return allHttpHeaders;
   }
}

Step4). Write the “GreetingServiceClient.java” program to invoke the WebService. Put it inside inside “C:/WebService_HttpRequest_HttpSession/src” directory like following:

package ws;
public class GreetingServiceClient
{
   public static void main(String ar[]) throws Exception
     {
        //String WSDL_URL=ar[0];
        GreetingService service=new GreetingService();
        Greeting port=service.getGreetingPort();
        System.out.println("**********************************");
        System.out.println("nntport.hello("Jack") = "+port.hello("Jack"));
        System.out.println("nn**********************************");
        System.out.println("nntport.getRequestHeaders() = "+port.getRequestHeaders());

     }
}

Step5). Create a “web.xml” file inside “C:/WebService_HttpRequest_HttpSession/src” to describe the WebService servlet declaration like following:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"  "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
  <servlet>
    <servlet-name>GreetingService</servlet-name>
    <servlet-class>ws.Greeting</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>GreetingService</servlet-name>
    <url-pattern>/Greeting</url-pattern>
  </servlet-mapping>
</web-app>

Step6). to automate the WebService build and deployment process we will need to write an ANT build script “build.xml” file inside “C:/WebService_HttpRequest_HttpSession” directory as following:
NOTE: Make sure that you are changing the “jboss.home”, “java.home.dir”,”jboss.profile” propert values according to your setup.

<project name="JBoss_Service" default="client">
<property name="jboss.home" value="/home/jsenshar/JBoss_All/JBossAS6/jboss-as" />
<property name="jboss.profile" value="${jboss.home}/server/default_Audit" />
<property name="java.home.dir" value="/home/jsenshar/MyJdks/jdk1.6.0_05" />
<property name="basedir" value="." />
<property name="war.name" value="GreetingService.war" />
<property name="src.dir" value="src" />
<property name="dest.dir" value="build" />
<property name="client.dir" value="clientStuff" />

<path id="jboss.classpath">
   <fileset dir="${jboss.home}/common/lib">
      <include name="*.jar"/>
   </fileset>
   <fileset dir="${jboss.home}/lib">
      <include name="*.jar"/>
   </fileset>
   <fileset dir="${java.home.dir}/jre/lib">
       <include name="rt.jar" />
   </fileset>
   <fileset dir="${java.home.dir}/lib">
       <include name="tools.jar" />
   </fileset>
</path>

<path id="jboss.client.classpath">
   <fileset dir="${jboss.home}/client">
      <include name="*.jar"/>
   </fileset>
   <fileset dir="${java.home.dir}/jre/lib">
       <include name="rt.jar" />
   </fileset>
   <fileset dir="${java.home.dir}/lib">
       <include name="tools.jar" />
   </fileset>
</path>

<path id="run.client.classpath">
   <fileset dir="${jboss.home}/client">
      <include name="*.jar"/>
   </fileset>
   <fileset dir="${jboss.home}/lib/endorsed">
      <include name="*.jar"/>
   </fileset>
   <fileset dir="${java.home.dir}/jre/lib">
       <include name="rt.jar" />
   </fileset>
   <fileset dir="${java.home.dir}/lib">
       <include name="tools.jar" />
   </fileset>
</path>
        <taskdef name="apt" classname="com.sun.tools.ws.ant.Apt">
 	  <classpath refid="jboss.classpath"/>
	</taskdef>
        <taskdef name="wsimport" classname="com.sun.tools.ws.ant.WsImport">
          <classpath refid="jboss.client.classpath"/>
        </taskdef>

        <target name="prepare">

           <mkdir dir="${dest.dir}/${war.name}"/>
           <mkdir dir="${dest.dir}/${war.name}/WEB-INF"/>
           <mkdir dir="${dest.dir}/${war.name}/WEB-INF/classes"/>
                    <delete dir="${dest.dir}" />
                     <mkdir dir="${dest.dir}" />
                     <delete dir="${client.dir}" />
                     <mkdir dir="${client.dir}"/>
        </target>

	<target name="build-service" depends="prepare">
	    <apt    fork="true"
	            destdir="${dest.dir}/${war.name}/WEB-INF/classes"
	            sourcedestdir="${dest.dir}/${war.name}/WEB-INF/classes"
	            sourcepath="${src.dir}">
	        <classpath>
	            <path refid="jboss.classpath"/>
	            <pathelement location="${basedir}/src"/>
	        </classpath>
	        <source dir="${basedir}">
	            <include name="src/**/Greeting.java"/>
	        </source>
	    </apt>
	    <!-- copy handlers descriptor file -->
	    <copy todir="${dest.dir}/${war.name}/WEB-INF">
	        <fileset dir="${basedir}/src">
	            <include name="**/web.xml"/>
	        </fileset>
	    </copy>
	</target>

        <target name="deploy" depends="build-service">
             <copy todir="${jboss.profile}/deploy">
                  <fileset dir="./build"/>
             </copy>
        </target>

        <target name="client" depends="deploy">
            <!-- Sleeping for 5 Seconds sothat the WSDL gets generated after the deployment so that we can generate client artifacts -->
            <sleep seconds="5"/>
            <wsimport destdir="${client.dir}"
                      wsdl="http://localhost:8080/GreetingService/Greeting?wsdl"
                      keep="true">
            </wsimport>
            <jar jarfile="${client.dir}/Greeting-Client.jar" basedir="${client.dir}" compress="true" />
        </target>

        <target name="run">
            <javac srcdir="${src.dir}" destdir="${client.dir}"  includes="GreetingServiceClient.java"/>
            <java classname="ws.GreetingServiceClient" >
	        <classpath>
	            <path refid="run.client.classpath"/>
                    <path refid="jboss.classpath"/>
	            <pathelement location="${client.dir}/Greeting-Client.jar"/>
	            <pathelement location="${client.dir}"/>
	        </classpath>
                <!-- <arg line="http://localhost:8080/GreetingService/Greeting?wsdl" />    -->
            </java>
        </target>
</project>

Step7). Now make sure that ANT bin directory is set in your PATH environment variable and JAVA_HOME is also set. Now you can open a Shell/command prompt and then build the WebService by running ANY like following:

[userone@localhost WebService_HttpRequest_HttpSession]echo $PATH
/home/userone/MyJdks/jdk1.6.0_21/bin:/home/userone/JBossAS6/jboss-as/bin:/home/userone/org.apache.ant_1.6.5/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/userone/bin:

[userone@localhost WebService_HttpRequest_HttpSession]$ ant
Buildfile: build.xml

prepare:
    [mkdir] Created dir: /home/userone/WebService_HttpRequest_HttpSession/build/GreetingService.war
    [mkdir] Created dir: /home/userone/WebService_HttpRequest_HttpSession/build/GreetingService.war/WEB-INF
    [mkdir] Created dir: /home/userone/WebService_HttpRequest_HttpSession/build/GreetingService.war/WEB-INF/classes
   [delete] Deleting directory /home/userone/WebService_HttpRequest_HttpSession/build
    [mkdir] Created dir: /home/userone/WebService_HttpRequest_HttpSession/build
    [mkdir] Created dir: /home/userone/WebService_HttpRequest_HttpSession/clientStuff

build-service:
      [apt] warning: Annotation types without processors: [javax.annotation.Resource]
      [apt] 1 warning
      [apt] warning: Annotation types without processors: [javax.xml.bind.annotation.XmlRootElement, javax.xml.bind.annotation.XmlAccessorType, javax.xml.bind.annotation.XmlType, javax.xml.bind.annotation.XmlElement]
      [apt] 1 warning
     [copy] Copying 1 file to /home/userone/WebService_HttpRequest_HttpSession/build/GreetingService.war/WEB-INF

deploy:
     [copy] Copying 10 files to /home/userone/JBossAS6/jboss-as/server/default_Audit/deploy

client:
 [wsimport] Consider using <depends>/<produces> so that wsimport won't do unnecessary compilation
 [wsimport] parsing WSDL...
 [wsimport] generating code...
 [wsimport] compiling code...
      [jar] Building jar: /home/userone/WebService_HttpRequest_HttpSession/clientStuff/Greeting-Client.jar

BUILD SUCCESSFUL
Total time: 11 seconds

Step8). Now as the webservice is deployed you will be able to run it like following:

[userone@localhost WebService_HttpRequest_HttpSession]echo $PATH
/home/userone/MyJdks/jdk1.6.0_21/bin:/home/userone/JBossAS6/jboss-as/bin:/home/userone/org.apache.ant_1.6.5/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/userone/bin:

[userone@localhost WebService_HttpRequest_HttpSession]$ ant run
Buildfile: build.xml

run:
    [javac] Compiling 1 source file to /home/jsenshar/Downloads/WebService_HttpRequest_HttpSession/clientStuff
      **********************************
      	port.hello("Jack") = Welcome Mr./Ms. Jack! Have a nice day...
      **********************************

      	port.getRequestHeaders() = HEADERS:
      content-type = text/xml;charset="utf-8"
      soapaction = ""
      accept = text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
      user-agent = JAX-WS RI 2.1.7-09/10/2010 09:17 PM(mockbuild)-
      host = 127.0.0.1:8080
      connection = keep-alive
      content-length = 179

BUILD SUCCESSFUL
Total time: 4 seconds

.
.
Thanks
Middleware Magic Team

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.