Tuesday 17 November 2015

Spring MVC: Session

Session management is one of the essential parts for each web application. Since Spring MVC is a powerful framework for web development, it has its own tools and API for the interaction with sessions. Today I intend to show you the basic ways of session processing within Spring MVC application. That is: how to process forms, add objects into a session, and display objects from the session on JSP. I will try my best, so let’s start.

This Spring MVC Session tutorial will be based on one of the previous posts on my blog, related to the form handling. I’m going to extend the application by adding some session logic to the existing student-form, and create a new page with a form and a single text field on it. The text from the field will be processed by a controller and added to the session.
In order to check the session functionality I will display the session objects on the pages using JSTL. You can download the source in the end of the tutorial.

Form with a single text field

Firstly I need to create a view and a controller. I will start from the view creation and after that I’ll demonstrate the corresponding controller with the session logic.
  1. ...  
  2. <h2>Adding of a String into the session</h2>  
  3.   
  4. <form action="remember.html" method="post">  
  5. <table>  
  6. <tbody><tr>  
  7. <td>To remember:</td>  
  8. <td><input name="thoughtParam" type="text"></td>  
  9. </tr>  
  10. <tr>  
  11. <td><input type="submit"></td>  
  12. <td></td>  
  13. </tr>  
  14. </tbody></table>  
  15. </form>  
  16. <a href="${pageContext.request.contextPath}/">Main page</a>   
  17. ...  
Now I need to develop the controller to handle the form. There will be two methods for the requests handling: the first one is responsible for navigation to the page, the second one is related to the session activity.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Controller
@SessionAttributes("thought")
public class SingleFieldController {
 
    @RequestMapping(value="/single-field")
    public ModelAndView singleFieldPage() {
        return new ModelAndView("single-field-page");
    }
     
    @RequestMapping(value="/remember"
    public ModelAndView rememberThought(@RequestParam String thoughtParam) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("thought", thoughtParam);
        modelAndView.setViewName("single-field-page");
        return modelAndView;
    }
     
}
This is a simple Spring MVC controller with the one extra @SessionAttributes annotation. It indicates that in the controller’s methods some values can be assigned to the arguments of the annotation. In this example I have declared just one session attribute with the name “thought“. That means I can put some object into modelAndView using the addObject() method, and it will be added to the session if the name of the object will be the same as the name of the argument in
@SessionAttributes.
The last thing I should to do is to add a link to the new page on the index.jsp:
  1. ...  
  2.     <h1>Home page</h1>  
  3.     <p>This is Home page.</p>  
  4.     <p>Don't forget: ${thought}</p>  
  5.     <p>  
  6.         <a href="person-form.html">Person page</a> <br>  
  7.         <a href="single-field.html">Single field page</a>  
  8.     </p>  
  9. ...  
In order, to check whether that session works properly, you need to add the following code to the existing views (single-field-page.jsp, …):
  1. <p>Don't forget: ${thought}</p>  
On the screenshots below you can see the result of the code execution:
Spring MVC session processing
And the results:
Spring MVC session result JSTL
And
Spring MVC session result JSTL 1

Adding a custom object into the session

In this section I’m going to show you how to add a custom object into the session, and how to display еру object’s properties on JSP. The role of the custom object will play the Person object. Firstly I’ll modify the existing person controller:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Controller
@SessionAttributes("personObj")
public class PersonController {
 
    @RequestMapping(value="/person-form")
    public ModelAndView personPage() {
        return new ModelAndView("person-page", "person-entity", new Person());
    }
     
    @RequestMapping(value="/process-person")
    public ModelAndView processPerson(@ModelAttribute Person person) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("person-result-page");
         
        modelAndView.addObject("pers", person);
        modelAndView.addObject("personObj", person);
         
        return modelAndView;
    }
     
}
Comparing with the latest version I have added two new strings:
1
2
3
4
5
...
@SessionAttributes("personObj")
...
modelAndView.addObject("personObj", person);
...
The result of the code execution is following:


Spring MVC session object
And
Spring MVC session object result

What does Class.forname method do?

A call to Class.forName("X") causes the class named X to be dynamically loaded (at runtime). A call to forName("X") causes the class named X to be initialized (i.e., JVM executes all its static block after class loading). Class.forName("X") returns the Class object associated with the "X" class. The returned Class object is not an instance of the "x" class itself.

Class.forName("X") loads the class if it not already loaded. The JVM keeps track of all the classes that have been previously loaded. This method uses the classloader of the class that invokes it. The "X" is the fully qualified name of the desired class.

For example,

package com.xyzws;
class AClass { 
    static { 
        System.out.println("static block in AClass");
    }
}

public class Program { 
    public static void main(String[] args) {
        try { 
            Class c   = Class.forName("com.xyzws.AClass"); 
        } catch (ClassNotFoundException e) {
        }
        
    }
}

The output is

static block in AClass

Here is one example that uses returned Class to create an instance of AClass:

package com.xyzws;
class AClass {
  public AClass() {
    System.out.println("AClass's Constructor");
  }
  static { 
    System.out.println("static block in AClass");
  }
}

public class Program { 
  public static void main(String[] args) {
    try { 
      System.out.println("The first time calls forName:");
      Class c   = Class.forName("com.xyzws.AClass"); 
      AClass a = (AClass)c.newInstance();

      System.out.println("The second time calls forName:");
      Class c1 = Class.forName("com.xyzws.AClass");

    } catch (ClassNotFoundException e) {
            ...
    } catch (InstantiationException e) {
            ...
    } catch (IllegalAccessException e) {
            ...
    }
        
  }
}

The output is

The first time calls forName:
static block in AClass
AClass's Constructor
The second time calls forName:  
//Calss has been loaded so there is not "static block in AClass" printing out

JDBC Driver Is a Good Example

You may have experience working with JDBC Drivers. For example, the classloader attempts to load and link the Driver class in the "org.gjt.mm.mysql" package. If successful, the static initializer is called.

Class.forName("org.gjt.mm.mysql.Driver");
Connection con = DriverManager.getConnection(url,?myLogin", "myPassword");

Let's see why you need Class.forName() to load a driver into memory.      All JDBC Drivers have a static block that registers itself with DriverManager and DriverManager has static an initializer only.

The MySQL JDBC Driver has a static initializer looks like this:

static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
        throw new RuntimeException("Can't register driver!");
    }
}

JVM executes the static block and the Driver registers itself with the DriverManager.
You need a database connection to manipulate the database. In order to create the connection to the database, the DriverManager class has to know which database driver you want to use. It does that by iterating over the array (internally a Vector) of drivers that have registered with it and calls the acceptsURL(url) method on each driver in the array, effectively asking the driver to tell it whether or not it can handle the JDBC URL.

AJAX call (JSON ) - XMLHttpRequest

<!DOCTYPE html>
<html>
<body>

<div id="id01"></div>

<script>
var xmlhttp = new XMLHttpRequest();
var url = "myTutorials.txt";

xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        var myArr = JSON.parse(xmlhttp.responseText);
        myFunction(myArr);
    }
};
xmlhttp.open("GET", url, true);
xmlhttp.send();

function myFunction(arr) {
    var out = "";
    var i;
    for(i = 0; i < arr.length; i++) {
        out += '<a href="' + arr[i].url + '">' +
        arr[i].display + '</a><br>';
    }
    document.getElementById("id01").innerHTML = out;
}
</script>

</body>
</html>

JSP - JSTL Custom Tag Library

JSP custom tags provide a standardized mechanism for separating the presentation and business logic in a dynamic web page, allowing page designers to focus on the presentation while application developers code the backend.

JSP Custom Tags

JSP custom tags provide a standardized mechanism for separating the presentation and business logic in a dynamic web page, allowing page designers to focus on the presentation while application developers code the backend. They are just Java classes that implement special interfaces. Once a custom tag is developed and deployed, its actions can be called from your HTML using an XML syntax. There is a start tag and an end tag. The tag may or may not have a body. A custom tag can be expressed as:
<tagLibrary:tagName attribute="value">
       body
</tagLibrary:tagName>

Benefits of Custom Tags

A very important thing to note about JSP custom tags is that they does not offer more functionality than scriptlets. They simply provide better packaging, by helping us improve the separation of the business logic and the presentation logic. Some of the benefits of a custom tag are:
  • It can reduce or eliminate scriptlets in our JSP applications. Any necessary parameters to the tag can be passed as attributes or as body content, and therefore no Java code is needed to initialize or set component properties.
  • It has a simpler syntax. A scriptlet is written in Java, but a custom tag can be used in an HTML-like syntax.
  • It can improve the productivity of nonprogrammer content developers, by allowing them to perform tasks that cannot be done with HTML.
  • It is reusable. It saves development and testing time. A scritplet is not reusable, unless we do cut-and-paste reuse.

Implementing JSP Custom Tags

There are a few steps involved in developing a custom tag. These steps can be summarized as follows:
  1. Write the tag handler class.
  2. Create the tag library descriptor (TLD).
  3. Make the TLD file and handler classes accessible.
  4. Reference the tag library.
  5. Use the tag in a JSP page.

Step 1. Write the tag handler class

The first thing we need to do is write the tag handler class. A tag handler is an object invoked by the JSP runtime to evaluate a custom tag during the execution of a JSP page that references the tag. The methods of the tag handler are called by the implementation class at various points during the evaluation of the tag. All tags must implement the Tag interface. We do not need to include the body content in our example TodayTag, because it only displays the current date in the user defined format. As such, our handler class will implement the Tag interface (typically by extending the TagSupport class). If we were to create a tag capable of processing body content, we would need to implement the BodyTag interface (typically by extending the BodyTagSupport class).
package jstl;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

/**
 * @author Bikash Shaw
 */
public class TodayTag extends TagSupport{
    private String mFormat;
    
    public void setFormat(String pFormat) {
        mFormat = pFormat;
    }
    
    
    public int doStartTag() throws JspException {
        try {
            JspWriter out = pageContext.getOut();
            Date today = new Date();
            SimpleDateFormat dateFormatter = new SimpleDateFormat(mFormat);
            out.print(dateFormatter.format(today));
            
        } catch(IOException ioe) {
            throw new JspException("Error: " + ioe.getMessage());
        }       
        return SKIP_BODY;
    }
    
    
    public int doEndTag() throws JspException {
        return SKIP_PAGE;
    }
}

Step 2. Create the tag library descriptor (TLD)

Our next step is to define the library that will contain the mappings between our custom tag and the Java class (or classes) that will handle it. This library is defined within an XML document called a tag library descriptor (TLD). We'll call the TLD for our custom tag examples, customTag.tld.
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
  <tlib-version>1.0</tlib-version>
    <short-name>ct</short-name>
    <uri>/WEB-INF/customTag</uri>
    <tag>
        <name>today</name>
        <tag-class>jstl.TodayTag</tag-class>
        <body-content>empty</body-content>
        <info>This Tag Displayes current server date in usser defined format</info>
        <attribute>
            <name>format</name>
            <required>true</required>
            <description>Provide a display format</description>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
    </tag>
</taglib>
 
All key information is contained within the Tag tag where the tag name and the handler class are mapped. In more complex cases, we could use additional XML tags to provide more information about the library and about the tags. It is also typical to define multiple tags within a single library.

Step 3. Make the TLD file and handler classes accessible

The third step is to make the class or classes and TLD accessible to the web application. There are two ways of doing this. We can either package the classes and the TLD together into a JAR file and then store the JAR file in the web application's lib directory, or we can place the class files loosely in the classes subdirectory and place the TLD file somewhere beneath the web application's WEB-INF directory.

Step 4. Reference the tag library

The fourth step is to make the class or classes and TLD accessible to the web application. In order to use the tag, we have to reference it, and this can be done in three ways:
  1. Reference the tag library descriptor of an unpacked tag library. For example:
  2. <%@ taglib uri="/WEB-INF/customTag.tld" prefix="ct" %>
     
  3. Reference a JAR file containing a tag library. For example:
  4. <%@ taglib uri="/WEB-INF/lib/customTag.jar" prefix="ct" %>
     
  5. Define a reference to the tag library descriptor from the web-application descriptor (web.xml), and define a short name to reference the tag library from JSP.
  6. <taglib>
        <taglib-uri>customTag</taglib-uri>   
        <taglib-location>/WEB-INF/customTag.tld</taglib-location>      
    </taglib>
    Next, we add a JSP declaration to any page that will need to use the custom tag library:
    <%@ taglib uri="customTag" prefix="ct" %>

Step 5. Use the tag in a JSP page

Now, we're ready to use our custom tag within a JSP page.
<%@ taglib uri="/WEB-INF/customTag.tld" prefix="ct" %>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">

<html>
  <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSTL Custom Tag Today</title>
  </head>
  <body>
        <h2 align="center"><ct:today format="MMMM dd, yyyy"/></h2>
  </body>
</html>
The results should look similar to the figure shown below:
JSTL-TodayTag.png

Parameterized Tags

There are two things that need to be mentioned to handle attributes to develop parameterized tags:
  1. Add a set method in the tag handler
  2. Add a new tag to customTag.tld
We can refer to the highlighted section of our previous example.

Tags with a body

A tag handler for a tag with a body is implemented differently depending on whether the body needs to be evaluated once or multiple times.
  • Single Evaluation: If the body needs to be evaluated once, the tag handler should implement the Tag interface, or extend the TagSupport abstract class; the doStartTag method needs to return EVAL_BODY_INCLUDE, and if it does not need to be evaluated at all, then it should return BODY_SKIP.
  • Multiple Evaluation: If the body needs to be evaluated multiple times, the BodyTag interface should be implemented. The BodyTag interface extends the Tag interface, and defines additional methods (setBodyContent, doInitBody, and doAfterBody) that enable a tag handler to inspect and possibly change its body. Alternatively, and similar to the TagSupport class, we can extend the BodyTagSupport class, which provides default implementations for the methods in the BodyTag interface. Typically, we need to implement doInitBody and doAfterBody methods. The doInitBody is called after the body content is set but before it is evaluated, and the doAfterBody is called after the body content is evaluated.

Single Evaluation

Here is an example of a single evaluation where we extend the BodyTagSupport class. This example reads the body content, and converts it to uppercase or lowercase depending on the attribute provided by us.
At first, we need to create the tag handler class:
package jstl;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

/**
 *
 * @author Bikash Shaw
 */
public class ChangeCaseTag extends BodyTagSupport {

    private String mCase;

    public void setCase(String pCase) {
        mCase = pCase;
    }

    
    public int doAfterBody() throws JspException {
        try {
            BodyContent bc = getBodyContent();
            String body = bc.getString();
            JspWriter out = bc.getEnclosingWriter();
            if (body != null) {
                if ("upper".equalsIgnoreCase(mCase)) {
                    out.print(body.toUpperCase());
                } else {
                    out.print(body.toLowerCase());
                }
            }
        } catch (IOException ioe) {
            throw new JspException("Error: " + ioe.getMessage());
        }
        return SKIP_BODY;
    }
}
The next step is to add a tag to the tag library descriptor file, customTag.tld:
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>ct</short-name>
<uri>/WEB-INF/customTag</uri>
    <tag>
        <name>changeCase</name>
        <tag-class>jstl.ChangeCaseTag</tag-class>
        <body-content>JSP</body-content>
        <info>This Tag Displayes current server date in user defined format</info>
        <attribute>
            <name>case</name>
            <required>true</required>
            <description>Provide the case upper or lower</description>
            <rtexprvalue>false</rtexprvalue>
        </attribute>
    </tag>
</taglib>
 
Note that when you write a tag with a body, the <body-content> tag's value must be either JSP or jspcontent.
Now, a test driver for this example is shown below:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
  <%@ taglib uri="/WEB-INF/customTag.tld" prefix="ct" %>
  <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Upper or Lower Case</title>
      </head>
      <body>
        <h2>
            Upper Case : 
              <ct:changeCase case="upper">
            Hello World
              </ct:changeCase>
        </h2>
        <h2>
            Lower Case : 
            <ct:changeCase case="lower">
                Hello World
            </ct:changeCase>
        </h2>
      </body>
  </html>
The results should look similar to the figure shown below:
JSTL-UpperLowerCase.png

Multiple Evaluation

Let's now see an example of a body tag evaluated multiple times. The example tag accepts an integer as its attribute, and prints its body HTML as many times as indicated in the JSP code.
Once again, create a tag handler class first:
package jstl;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

/**
 *
 * @author Bikash Shaw
 */
public class LoopTextTag extends BodyTagSupport {

    private int mTimes = 0;
    private BodyContent mBodyContent;

    public void setTimes(int pTimes) {
        mTimes = pTimes;
    }

    
    public void setBodyContent(BodyContent pBodyContent) {
        mBodyContent = pBodyContent;
    }

    
    public int doStartTag() throws JspException {
        if (mTimes > 1) {
            return EVAL_BODY_TAG;
        } else {
            return SKIP_BODY;
        }
    }

    
    public int doAfterBody() throws JspException {
        if (mTimes > 1) {
            mTimes--;
            return EVAL_BODY_TAG;
        } else {
            return SKIP_BODY;
        }
    }

    
    public int doEndTag() throws JspException {
        try {
            if (mBodyContent != null) {
                mBodyContent.writeOut(mBodyContent.getEnclosingWriter());
            }
        } catch (IOException pIOEx) {
            throw new JspException("Error: " + pIOEx.getMessage());
        }
        return EVAL_PAGE;
    }
}
The methods of this tag perform the following roles:
  • The doStartTag method gets called at the start of the tag. It checks if the loop needs to be performed.
  • The setBodyContent is called by the JSP container to check for more than one loop.
  • The doAfterBody method is called after each evaluation; the number of times the loop needs to be performed is decreased by one, then it returns SKIP_BODY when the number of times is not greater than one.
  • The doEndTag method is called at the end of the tag, and the content (if any) is written to the enclosing writer.
Similar to the previous examples, the next step is to add a new tag descriptor to customTag.tld:
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>ct</short-name>
<uri>/WEB-INF/customTag</uri>
    <tag>
        <name>loopText</name>
        <tag-class>jstl.LoopTextTag</tag-class>
        <body-content>JSP</body-content>
        <info>This Tag Displayes given text multiple times</info>
        <attribute>
            <name>times</name>
            <required>true</required>
            <description>Provide number of times the text will be repeated</description>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>
Note that the <rtexprvalue> tag is true, which specifies that evaluations will be performed at runtime.
Finally, we write a sample JSP page to test the <loopText> tag.
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib uri="/WEB-INF/customTag.tld" prefix="ct" %>
<html>
    <head>
        <meta http-equiv="Content-Type" 
           content="text/html; charset=UTF-8">
        <title>JSTL Custom Tag Loop Text</title>
    </head>
    <body>
        <center>

            <ct:loopText times="5">
                <h3>Loop Text!</h3>
            </ct:loopText>

        </center>
    </body>
</html>
The output should look similar to the figure shown below:
JSTL-LoopText.png

SOAP Binding: Difference between Document and RPC Style Web Services


Document Style Vs RPC Style

The Document style indicates that the SOAP body contains a XML document which can be validated against pre-defined XML schema document.
RPC indicates that the SOAP message body contains an XML representation of a method call and uses the names of the method and its parameters to generate XML structures that represent a method’s call stack. The document/literal approach is easier because it simply relies on XML Schema to describe exactly what the SOAP message looks like while transmission.


RPC /LITERAL SOAP Binding Example Web Service

First let us see how the RPC/LITERAL/WRAPPED style web service request and response structure.
The following is a sample Java SEI (Service Endpoint Interface) to create a RPC web service.
/**
 * @author Binu George
 * Globinch.com
 * Visit  http://www.globinch.com. All rights reserved.
 */
package com.my.ws;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.ParameterStyle;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;

@WebService(name = "MyJaxWSHello", 
  targetNamespace = "http://globinch.com", 
  wsdlLocation = "http://globinch.com/ws/MyJaxWS?wsdl")
@SOAPBinding(style=Style.RPC, use=Use.LITERAL, parameterStyle=ParameterStyle.WRAPPED)  
public interface MyJaxWSSEI {

   @WebMethod(operationName="getGreetingRequest")
   @WebResult(targetNamespace="http://globinch.com/ws/types",
      name="GreetingResponse")
   public JXRes getJXWsRes(
      @WebParam(targetNamespace="http://globinch.com/ws/types",
                name="name",
                mode=Mode.IN)
                String name
   );

}
The corresponding WSDL and XML schema definition is given below. You can the operation name still appears in the SOAP message. The type encoding info is not present since this is defined as LITERAL.

Schema Defintion

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://globinch.com" xmlns:tns="http://globinch.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="jxRes" type="tns:jxRes"/>
  <xs:complexType name="jxRes">
    <xs:sequence>
      <xs:element name="message" type="xs:string" minOccurs="0"/>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

WSDL Document

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.1 in JDK 6. -->
<definitions targetNamespace="http://globinch.com" name="MyJaxWSHelloService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://globinch.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <types>
    <xsd:schema>
      <xsd:import namespace="http://globinch.com" schemaLocation="MyJaxWSHelloService_schema1.xsd"/>
    </xsd:schema>
  </types>
  <message name="getGreetingRequest">
    <part name="name" type="xsd:string"/>
  </message>
  <message name="getGreetingRequestResponse">
    <part name="GreetingResponse" type="tns:jxRes"/>
  </message>
  <portType name="MyJaxWSHello">
    <operation name="getGreetingRequest" parameterOrder="name">
      <input message="tns:getGreetingRequest"/>
      <output message="tns:getGreetingRequestResponse"/>
    </operation>
  </portType>
  <binding name="MyJaxWSSEIPortBinding" type="tns:MyJaxWSHello">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
    <operation name="getGreetingRequest">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal" namespace="http://globinch.com"/>
      </input>
      <output>
        <soap:body use="literal" namespace="http://globinch.com"/>
      </output>
    </operation>
  </binding>
  <service name="MyJaxWSHelloService">
    <port name="MyJaxWSSEIPort" binding="tns:MyJaxWSSEIPortBinding">
      <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
    </port>
  </service>
</definitions>

SOAP Request Message

  
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:glob="http://globinch.com">
   <soapenv:Header/>
   <soapenv:Body>
      <glob:getGreetingRequest>
         <name>Binu George</name>
      </glob:getGreetingRequest>
   </soapenv:Body>
</soapenv:Envelope>

SOAP Response Message

 
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <ns2:getGreetingRequestResponse xmlns:ns2="http://globinch.com">
         <GreetingResponse>
            <message>Hello</message>
            <name>Binu George</name>
         </GreetingResponse>
      </ns2:getGreetingRequestResponse>
   </S:Body>
</S:Envelope>
From the above you can see that the WSDL is not so complex. It is not very easy to validate the messages since there is no complete schema defined for it. This means the schema alone does not tell you what the message body Info set contains because some of the soap:body contents comes from WSDL definitions. Because of this , schema describing an RPC/literal message is not sufficient to validate that message.
From the above request and response you can see that the Soap:Body contains one element which has the name of the WSDL operation and the namespace specified on the soap:body element in the WSDL binding. Inside this element, there’s an element for each part of the message and its name is name of the part. Inside each part element are the contents of that part, as defined by the schema type that the part references in WSDL.
For example see the above response. The
<ns2:getGreetingRequestResponse xmlns:ns2="http://globinch.com">
has the name of the WSDL operation and the namespace specified on the soap:body element in the WSDL binding. Inside this you can see the part element “GreetingResponse” and its content is as per the defined schema.


Document/Literal SOAP Binding Web service




Let us now change the style to Document and see the generated schema files and WSDL files. There are two schema files generated and are included in the WSDLfile.
 
/**
 * @author Binu George
 * Globinch.com
 * Visit  http://www.globinch.com. All rights reserved.
 */
package com.my.ws;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.ParameterStyle;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

@WebService(name = "MyJaxWSHello", 
  targetNamespace = "http://globinch.com", 
  wsdlLocation = "http://globinch.com/ws/MyJaxWS?wsdl")
@SOAPBinding(style=Style.DOCUMENT, use=Use.LITERAL, parameterStyle=ParameterStyle.BARE)  
public interface MyJaxWSSEI {

   @WebMethod(operationName="getGreetingRequest")
   /*@RequestWrapper(targetNamespace="http://globinch.com/ws/types",
      className="java.lang.String")
   @ResponseWrapper(targetNamespace="http://globinch.com/ws/types",
      className="com.my.ws.JXRes")
   @WebResult(targetNamespace="http://globinch.com/ws/types",
      name="JXWsRes")*/
     @WebResult(targetNamespace="http://globinch.com/ws/types",
      name="GreetingResponse")
   public JXRes getJXWsRes(
      @WebParam(targetNamespace="http://globinch.com/ws/types",
                name="name",
                mode=Mode.IN)
                String name
   );

}

Schema defintion document1

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://globinch.com/ws/types" xmlns:ns1="http://globinch.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:import namespace="http://globinch.com" schemaLocation="MyJaxWSHelloService_schema2.xsd"/>
  <xs:element name="GreetingResponse" nillable="true" type="ns1:jxRes"/>
  <xs:element name="name" nillable="true" type="xs:string"/>
</xs:schema>

Schema defintion document 2

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://globinch.com" xmlns:tns="http://globinch.com" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="jxRes" type="tns:jxRes"/>
  <xs:complexType name="jxRes">
    <xs:sequence>
      <xs:element name="message" type="xs:string" minOccurs="0"/>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

The WSDL Document

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.1 in JDK 6. -->
<definitions targetNamespace="http://globinch.com" name="MyJaxWSHelloService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://globinch.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
  <types>
    <xsd:schema>
      <xsd:import namespace="http://globinch.com/ws/types" schemaLocation="MyJaxWSHelloService_schema1.xsd"/>
    </xsd:schema>
    <xsd:schema>
      <xsd:import namespace="http://globinch.com" schemaLocation="MyJaxWSHelloService_schema2.xsd"/>
    </xsd:schema>
  </types>
  <message name="getGreetingRequest">
    <part name="name" element="ns1:name" xmlns:ns1="http://globinch.com/ws/types"/>
  </message>
  <message name="getGreetingRequestResponse">
    <part name="GreetingResponse" element="ns2:GreetingResponse" xmlns:ns2="http://globinch.com/ws/types"/>
  </message>
  <portType name="MyJaxWSHello">
    <operation name="getGreetingRequest">
      <input message="tns:getGreetingRequest"/>
      <output message="tns:getGreetingRequestResponse"/>
    </operation>
  </portType>
  <binding name="MyJaxWSSEIPortBinding" type="tns:MyJaxWSHello">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="getGreetingRequest">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="MyJaxWSHelloService">
    <port name="MyJaxWSSEIPort" binding="tns:MyJaxWSSEIPortBinding">
      <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
    </port>
  </service>
</definitions>
You can see from the schema and wsdl files that all the elements are defined. The following request and response SOAP messages are following the schema definitions.

Sample SOAP Request

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://globinch.com/ws/types">
   <soapenv:Header/>
   <soapenv:Body>
      <typ:name>Binu George</typ:name>
   </soapenv:Body>
</soapenv:Envelope>

Sample SOAP Response

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <ns3:GreetingResponse xmlns:ns2="http://globinch.com" xmlns:ns3="http://globinch.com/ws/types">
         <message>Hello</message>
         <name>Binu George</name>
      </ns3:GreetingResponse>
   </S:Body>
</S:Envelope>
In the above SOAP request and response messages, all the elements are defined in the XML schema definition files. But if you use the parameter style as WRAPPED you will see the operation name element in SOAP messages. Still the definition will be complaint to the XSD. Document style requires extra classes to run the application. You can use “wsgen” to generate all required Java artifacts including mapping classes, wsdl or xsd schema. Read more below