Application Overview
The sample application referred in this article is a simple calculator which performs addition of two integers. The client application referred here is not a J2EE application. It is a regular Java client which will call a web service to carry out the application functionality. Web service is exposed as a Servlet in the Geronimo application server.
Two clients are provided: a jsp page and a non-javaee client.
Service implementation
The Calculator interface defines the Service Endpoint Interface (SEI) for the Web Service.
Code Block |
---|
| java |
---|
| java |
---|
borderStyle | solid |
---|
title | Calculator.java |
---|
|
package org.apache.geronimo.samples.jws;
import javax.jws.WebServiceWebMethod;
import javax.jws.WebMethodWebParam;
import javax.jws.WebParamWebResult;
@WebService(name="CalculatorPortType",
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
@WebService(name = "CalculatorPortType",
targetNamespace = "http://jws.samples.geronimo.apache.org")
public interface Calculator {
@WebMethod/**
public int add(@WebParam(name = "value1") int value1,
* @param value1
* @param value2
* @return returns int
*/
@WebParam(name @WebMethod(operationName = "value2add") int value2);
}
|
The CalculatorService class implements the Web Service business logic. It implements all the methods defined in the SEI. The class does not need to implement the Calculator interface but must reference it through the @WebService.endpointInterface annotation. This class will be exposed as a Servlet through web.xml file even though it does not extend the javax.servlet.Servlet class.
The context variable marked with the @Resource annotation will be injected at runtime. The WebServiceContext can be used to obtain the message context and security information relative to the call.
Code Block |
---|
java | java |
borderStyle | solid |
---|
title | CalculatorService.java |
---|
package
@WebResult(name = "return", targetNamespace = "http://jws.samples.geronimo.apache.org")
@RequestWrapper(localName = "add", targetNamespace = "http://jws.samples.geronimo.apache.org", className = "org.apache.geronimo.samples.jws;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
@WebService(serviceName.Add")
@ResponseWrapper(localName = "CalculatoraddResponse",
targetNamespace portName="CalculatorPort",
endpointInterface = "= "http://jws.samples.geronimo.apache.org", className = "org.apache.geronimo.samples.jws.CalculatorAddResponse",)
public int add(@WebParam(name = "value1", targetNamespace = "http://jws.samples.geronimo.apache.org")int value1,
wsdlLocation = "WEB-INF/wsdl/CalculatorService.wsdl")
public class CalculatorService implements Calculator {
@Resource
private WebServiceContext context;
public int add(int value1, int value2) {
System.out.println("User Principal: " + context.getUserPrincipal());
return value1 + value2;
}
}
|
The web.xml descriptor is used to deploy the Web Service.
@WebParam(name = "value2", targetNamespace = "http://jws.samples.geronimo.apache.org")int value2);
}
|
The CalculatorService class implements the Web Service business logic. It implements all the methods defined in the SEI. The class does not need to implement the Calculator interface but must reference it through the @WebService.endpointInterface annotation. This class will be exposed as a Servlet through web.xml file even though it does not extend the javax.servlet.Servlet class.
The context variable marked with the @Resource annotation will be injected at runtime. The WebServiceContext can be used to obtain the message context and security information relative to the call.
Code Block |
---|
| java |
---|
| java |
---|
borderStyle | solid |
---|
title | CalculatorService.java |
---|
|
package org. |
Code Block |
---|
xml | xml |
borderStyle | solid |
---|
title | web.xml |
---|
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<display-name>CalculatorService</display-name>
<servlet-name>CalculatorService</servlet-name>
<servlet-class>
org.apache.geronimo.samples.jws.CalculatorService
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CalculatorService</servlet-name>
<url-pattern>/calculator</url-pattern>
</servlet-mapping>
.....
</web-app>
|
Info |
---|
|
The web.xml descriptor is not necessary for simple JAX-WS web service deployments. If the web.xml descriptor is not provided, it will be automatically generated during deployment. |
The geronimo-web.xml descriptor is optional but it is used in this sample to specify the module name. Information about the project (e.g. module's unique identification, any dependencies) is described inside the <environment> tag. In this case, there are no dependencies so they do not need to be listed. However, it is a good idea to give this module some sort of unique identification, so that it can later be referenced by some other deployable application.
...
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">
<dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1">
<dep:moduleId>
<dep:groupId>${pom.groupId}</dep:groupId>
<dep:artifactId>${pom.artifactId}</dep:artifactId>
<dep:version>${version}</dep:version>
<dep:type>war</dep:type>
</dep:moduleId>
</dep:environment>
<context-root>/jaxws-calculator</context-root>
<service-ref>
<service-ref-name>services/Calculator</service-ref-name>
<port>
<port-name>CalculatorPort</port-name>
<protocol>http</protocol>
<host>localhost</host>
<port>8080</port>
<uri>/jaxws-calculator/calculator</uri>
</port>
</service-ref>
</web-app>
;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
@WebService(serviceName = "Calculator",
portName = "CalculatorPort",
endpointInterface = "org.apache.geronimo.samples.jws.Calculator",
targetNamespace = "http://jws.samples.geronimo.apache.org",
wsdlLocation = "WEB-INF/wsdl/CalculatorService.wsdl")
public class CalculatorService implements Calculator {
@Resource
private WebServiceContext context;
/**
* @return returns javax.xml.ws.WebServiceContext
*/
public WebServiceContext getContext() {
return context;
}
/**
* @param value1
* @param value2
* @return returns int
*/
public int add(int value1, int value2) {
System.out.println("User Principal: " + context.getUserPrincipal());
System.out.println("value1: " + value1 + " value2: " + value2);
return value1 + value2;
}
}
|
The web.xml descriptor is used to deploy the Web Service. The following WSDL file describes the Web Service:
Code Block |
---|
| xml |
---|
| xml |
---|
borderStyle | solid |
---|
title | CalculatorServiceweb.wsdlxml |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="Calculator"
<web-app xmlns="http://schemasjava.xmlsoapsun.orgcom/xml/wsdlns/javaee" version="2.5">
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://jws.samples.geronimo.apache.org"
xmlns:tns="http://jws.samples.geronimo.apache.org">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" <servlet>
<display-name>CalculatorService</display-name>
<servlet-name>CalculatorService</servlet-name>
<servlet-class>
org.apache.geronimo.samples.jws.CalculatorService
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CalculatorService</servlet-name>
<url-pattern>/calculator</url-pattern>
</servlet-mapping>
.....
<service-ref>
<service-ref-name>services/Calculator</service-ref-name>
<service-interface>javax.xml.ws.Service</service-interface>
xmlns="http://jws.samples.geronimo.apache.org" <wsdl-file>WEB-INF/wsdl/CalculatorService.wsdl</wsdl-file>
</service-ref>
</web-app>
|
Info |
---|
|
The web.xml descriptor is not necessary for simple JAX-WS web service deployments. If the web.xml descriptor is not provided, it will be automatically generated during deployment. In this sample, while not required to implement the web service, it is required to provide the service-ref used by the jsp client. |
The geronimo plan has no information for the web service but does specify more information for the service-ref for the jsp client. For tomcat, the plan can be located after building the project in jaxws-calculator/jaxws-calculator-tomcat/target/resources/META-INF/plan.xml. For Jetty, the plan can be located after building the project in jaxws-calculator/jaxws-calculator-jetty/target/resources/META-INF/plan.xml.
Code Block |
---|
| xml |
---|
| xml |
---|
borderStyle | solid |
---|
title | geronimo-web.xml for tomcat |
---|
|
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">
<dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2">
<dep:moduleId>
<dep:groupId>org.apache.geronimo.samples</dep:groupId>
<dep:artifactId>jaxws-calculator-tomcat</dep:artifactId>
<dep:version>2.1.2-SNAPSHOT</dep:version>
<dep:type>car</dep:type>
</dep:moduleId>
<dep:dependencies>
<dep:dependency>
<dep:groupId>org.apache.geronimo.configs</dep:groupId>
<dep:artifactId>jasper</dep:artifactId>
<dep:version>2.1.2-SNAPSHOT</dep:version>
<dep:type>car</dep:type>
</dep:dependency>
<dep:dependency>
<dep:groupId>org.apache.geronimo.configs</dep:groupId>
<dep:artifactId>tomcat6</dep:artifactId>
<dep:version>2.1.2-SNAPSHOT</dep:version>
<dep:type>car</dep:type>
</dep:dependency>
<dep:dependency>
<dep:groupId>org.apache.geronimo.configs</dep:groupId>
<dep:artifactId>axis2</dep:artifactId>
<dep:version>2.1.2-SNAPSHOT</dep:version>
<dep:type>car</dep:type>
</dep:dependency>
</dep:dependencies>
<dep:hidden-classes/>
<dep:non-overridable-classes/>
</dep:environment>
<context-root>/jaxws-calculator</context-root>
<service-ref>
<service-ref-name>services/Calculator</service-ref-name>
<port>
<port-name>CalculatorPort</port-name>
<protocol>http</protocol>
<host>localhost</host>
<port>8080</port>
<uri>/jaxws-calculator/calculator</uri>
</port>
</service-ref>
</web-app>
|
Info |
---|
title | Optional geronimo-web.xml |
---|
|
You could also deploy the jaxws-calculator-war\target\jaxws-calculator-war-version.war file without a plan, use the steps below: Update the "soap:address location" value in the CalculatorService.wsdl to refect the correct version of the jaxws-calculator-war module, for example <soap:address location="http://localhost:8080/jaxws-calculator-war-version/calculator"/> Rebuild the sample and deploy the war. |
The following WSDL file describes the Web Service:
Code Block |
---|
| xml |
---|
| xml |
---|
borderStyle | solid |
---|
title | CalculatorService.wsdl |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="Calculator"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://jws.samples.geronimo.apache.org"
xmlns:tns="http://jws.samples.geronimo.apache.org">
<wsdl:types>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://jws.samples.geronimo.apache.org"
targetNamespace="http://jws.samples.geronimo.apache.org"
targetNamespace="http://jws.samples.geronimo.apache.org"
attributeFormDefault="unqualified" elementFormDefault="qualified">
<xsd:element name="add">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value1" type="xsd:int"/>
<xsd:element name="value2" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="addResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="return" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
<wsdl:message name="add">
<wsdl:part name="add" element="tns:add"/>
</wsdl:message>
<wsdl:message name="addResponse">
<wsdl:part name="addResponse" element="tns:addResponse"/>
</wsdl:message>
<wsdl:portType name="CalculatorPortType">
<wsdl:operation name="add">
<wsdl:input name="add" message="tns:add"/>
<wsdl:output name="addResponse" message="tns:addResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="CalculatorSoapBinding" type="tns:CalculatorPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="add">
<soap:operation soapAction="add" style="document"/>
<wsdl:input name="add">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="addResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Calculator">
<wsdl:port name="CalculatorPort" binding="tns:CalculatorSoapBinding">
<soap:address location="http://localhost:8080/jaxws-calculator-1.0/calculator"/="tns:CalculatorSoapBinding">
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
|
Info |
---|
|
In J2EE version 1.4, the webservices.xml file was also necessary to describe the Web Service. In Java EE 5 that file is optional and is not required in this example. |
JSP-based JAX-WS client
The add.jsp is a basic client for the CalculatorService Web Service.
<soap:address location="http://localhost:8080/jaxws-calculator/calculator"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
|
Info |
---|
title | CalculatorService.wsdl |
---|
|
In J2EE version 1.4, wsdl file was required to describe the Web Service. In Java EE 5 wsdl file is optional. It can be generated at deployment time by the Geronimo server if CalculatorService.wsdl is not provided with the sample. |
Info |
---|
|
In J2EE version 1.4, the webservices.xml file was also necessary to describe the Web Service. In Java EE 5 that file is optional and is not required in this example. |
JSP-based JAX-WS client
The add.jsp is a basic client for the CalculatorService Web Service.
Code Block |
---|
| java |
---|
| java |
---|
borderStyle | solid |
---|
title | add.jsp |
---|
|
<%@ page language="java" contentType |
Code Block |
---|
java | java |
borderStyle | solid |
---|
title | add.jsp |
---|
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ page import="javax.naming.InitialContext,javax.xml.ws.Service,org.apache.geronimo.samples.jws.Calculator"%>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Apache Geronimo Sample Application - JAX-WS Calculator</title>
<meta content="text/html; CHARSETcharset=isoISO-8859-1" http-equivpageEncoding="ContentISO-8859-Type">
</head>
<BODY>
<font face="Verdana, Helvetica, Arial">
<h3>This is a JAX-WS web service sample application. Please type the value 1 and value 2 below to see the add result.</h3>
<form action="add.jsp">
Value 1: <input type="text" name="value1"> Value 2: <input type="text" name="value2"> <input type="submit" value="Add">
</form>
<br>
<%
String value1 = request.getParameter( "value1" );
String value2 = request.getParameter( "value2" );
if (value1 != null && value1.trim().length() > 0 &&
value2 != null && value2.trim().length() > 0) {
out.println("<h4>");
try {
int v1 = Integer.parseInt(value11"%>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.xml.ws.Service" %>
<%@ page import="org.apache.geronimo.samples.jws.Calculator" %>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Apache Geronimo Sample Application - JAX-WS Calculator</title>
<meta content="text/html; CHARSET=iso-8859-1" http-equiv="Content-Type">
</head>
<BODY>
<font face="Verdana, Helvetica, Arial">
<h3>This is a JAX-WS web service sample application. Please type the value 1 and value 2 below to see the add result.</h3>
<form action="add.jsp">
Value 1: <input type="text" name="value1"> Value 2: <input type="text" name="value2"> <input type="submit" value="Add">
</form>
<br>
<%
String value1 = request.getParameter( "value1" );
String int v2 value2 = Integerrequest.parseIntgetParameter( "value2" );
if (value1 InitialContext!= ctxnull = new InitialContext();
&& value1.trim().length() > 0 &&
value2 Service!= servicenull =&& value2.trim(Service)ctx.lookup("java:comp/env/services/Calculator");
length() > 0) {
Calculator calc = serviceout.getPort(Calculator.classprintln("<h4>");
try {
int sumv1 = calcInteger.add(v1, v2parseInt(value1);
out.println("Result: " + v1 + " + " + v2 + " = " + sum);
int }v2 catch= Integer.parseInt(value2);
Exception e ) {
out.println("Error: " + e.getMessage()InitialContext ctx = new InitialContext();
}
out.println("</h4>");
}
%>
</FONT>
</body>
</html>
|
The add.jsp looks up a Web Service reference in the JNDI tree. The Web Service reference must first be added the web.xml file.
Code Block |
---|
xml | xml |
borderStyle | solid |
---|
title | web.xml |
---|
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
Service service = (Service)ctx.lookup("java:comp/env/services/Calculator");
Calculator calc = service.getPort(Calculator.class);
int sum = calc.add(v1, v2);
.....
<service-ref>
out.println("Result: " + v1 + " + " + v2 + " = " + sum);
<service-ref-name>services/Calculator</service-ref-name>
} catch ( Exception e ) {
<service-interface>javax.xml.ws.Service</service-interface>
out.println("Error: " <wsdl-file>WEB-INF/wsdl/CalculatorService.wsdl</wsdl-file>+ e.getMessage());
}
out.println("</service-ref>
h4>");
.....}
%>
</FONT>
</body>
</web-app>
| Note |
---|
title | Resource injection in JSP |
---|
|
Since the resource injection is not supported in JSPs the service-ref must be added explicitly to html>
|
The add.jsp looks up a Web Service reference in the JNDI tree. The Web Service reference must first be added the web.xml file.
...
Code Block |
---|
| xml |
---|
| xml |
---|
borderStyle | solid |
---|
title | web.xml |
---|
|
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns=" |
...
Checkout the sample source code from SVN:
...
...
...
...
...
...
The source code will be checked out into the calculator/ directory. This sample code code lives in calculator/jaxws-calculator-war/ directory.
Required Tools
The tools used for developing and building the Calculator sample application are:
Apache Maven 2.0.x
Apache Maven is used for building the Calculator application.
Building
Compile Source Code
From command prompt execute the following command in the calculator/jaxws-calculator-war/ folder:
mvn install
After the code is successfully compiled a jaxws-calculator-war-2.0-SNAPSHOT.war file will be created in the target/ subfolder.
Deploying
Deploy the jaxws-calculator-war-2.0-SNAPSHOT.war using the Geronimo Console (http://localhost:8080/console):
...
ns/javaee" version="2.5">
.....
<service-ref>
<service-ref-name>services/Calculator</service-ref-name>
<service-interface>javax.xml.ws.Service</service-interface>
<wsdl-file>WEB-INF/wsdl/CalculatorService.wsdl</wsdl-file>
</service-ref>
.....
</web-app>
|
Note |
---|
title | Resource injection in JSP |
---|
|
Since the resource injection is not supported in JSPs the service-ref must be added explicitly to the web.xml file |
...
Testing of the Sample
To test this sample service use using the add.jsp (http://localhost:8080/jaxws-calculator/add.jsp) to invoke the Web Service. Once the JSP page loads type in two values to add and press the Add button. The result of the addition should show up below. For example:
Note |
---|
Command line client CalculatorClient.java is not currently working yet. |