You can use the @WebService
and @WebMethod
annotations on a service endpoint implementation
to specify Java methods that you want to expose as Java API for XML-Based Web Services (JAX-WS) web services.
JAX-WS technology enables the implementation of web services based on both the standard service endpoint interface and
a Provider
interface. When developing a JAX-WS Web service starting from existing Java classes, known
as the bottom-up approach, you must annotate the class with either the @WebService
or
@WebServiceProvider
annotation to initially define the class as a web service.
Using the Provider
interface is the dynamic approach to defining your JAX-WS services. To use the
Provider
interface, your class must implement the javax.xml.ws.Provider
interface, and
contain the @WebServiceProvider
annotation. The Provider
interface has one method, the
invoke
method, which uses generics in the Java programming language to control both the input and
output types when working with various messages or message payloads.
To describe your web services using the service endpoint interface (SEI) approach, initially define a web service,
annotate the Java class with the @WebService
annotation. However, you can also selectively annotate
the individual methods with @WebMethod
annotation to control how these methods are exposed as web
services operations.
@javax.jws.WebService
marks a Java class as implementing a web service, or a Java interface as
defining a web service interface:
@Retention(value=RetentionPolicy.RUNTIME) @Target({TYPE}) public @interface WebService { String name() default ""; String targetNamespace() default ""; String serviceName() default ""; String wsdlLocation() default ""; String endpointInterface() default ""; String portName() default ""; };
Table 1.1.
@javax.jws.WebService
Member-Value | Meaning | Default |
---|---|---|
|
The name of the web service. Used as the name of the |
The simple name of the Java class or interface. |
|
The XML namespace used for the WSDL and XML elements generated from this web service. |
Implementation-defined, as described in JAX-RPC 1.1. Typically derived from the package containing the web service. |
|
The service name of the web service. Used as the name of the Not allowed on interfaces. |
The simple name of the Java class + " |
|
The location of a pre-defined WSDL describing the service. The |
None. |
|
The complete name of the service endpoint interface defining the service's abstract web
service contract. This annotation allows the developer to separate the interface contract
from the implementation. If this annotation is present, the service endpoint interface is used
to determine the abstract WSDL contract ( Not allowed on interfaces. |
None -– the web service contract is generated from annotations on the service implementation bean. If a service endpoint interface is required by the target environment, it will be generated into an implementation-defined package with an implementation-defined name. |
|
The port name of the Web Service.
Used as the name of the Not allowed on interfaces. |
|
Example:
/** * Annotated Implementation Object */ @WebService( name = "EchoService", targetNamespace = "http://www.openuri.org/2004/04/HelloWorld" ) public class EchoServiceImpl { @WebMethod public String echo(String input) { return input; } }
Use the following best practices for defining web services:
To define a basic web service, annotate the Java class with the @WebService
annotation.
To define your web services using an explicit SEI, add the @WebService
annotation to
a Java implementation class and explicitly reference a Java interface using the
@WebService.endpointInterface
attribute.
To define your web services using an implicit SEI, add the @WebService
annotation to a
Java implementation class and do not define the @WebService.endpointInterface
attribute.
Provide a reference to a WSDL file in the @WebService.wsdlLocation
attribute. By specifying
a pre-defined WSDL file, performance is improved. Additionally, any discrepancies between the WSDL file
and the annotations are reported to you by the runtime environment.
When you use an explicit SEI, all public methods in the SEI and inherited classes are always exposed.
You only need to add @WebMethod
annotations if you want to further customize the methods
that are already exposed.
If you define an implicit SEI, follow these rules to ensure that your methods are exposed consistently:
Add an @WebService
annotation to your implementation class and all its superclasses
that contain methods that you want to expose. Adding an @WebService
annotation to
a class exposes all public methods in that class.
If you want more granular control and expose only certain methods from a class that is
annotated with the @WebService
annotation, you can use the @WebMethod
annotation on selected individual methods. The @WebMethod.exclude
attribute
is one of the criteria that is used to determine whether a method is exposed as an
operation. The default value for this attribute is false
. To ensure that
a method is exposed, annotate it with the @WebMethod
annotation. If you want
to make sure that a method is NOT exposed, annotate it with the
@WebService(exclude=true)
annotation.
@javax.jws.WebMethod
customizes a method that is exposed as a web wervice operation.
@Retention(value=RetentionPolicy.RUNTIME) @Target({METHOD}) public @interface WebMethod { String operationName() default ""; String action() default "" ; };
The @WebMethod
annotation includes the following member-value pairs:
Table 1.2.
@javax.jws.WebMethod
Member-Value | Meaning | Default |
---|---|---|
|
Name of the |
The name of the Java method. |
|
The action for this operation. For SOAP bindings, this determines the value of the
|
"" |
|
Marks a method to NOT be exposed as a web method.
Used to stop an inherited method from being exposed as part of this web service. If this
element is specified, other elements MUST NOT be specified for the This member-value is not allowed on endpoint interfaces. |
|
Java source:
@WebService public class MyWebService { @WebMethod(operationName = "echoString", action="urn:EchoString") public String echo(String input) { return input; } }
Resulting WSDL:
<definitions> <portType name="MyWebService"> <operation name="echoString"/> <input message="echoString"/> <output message="echoStringResponse"/> </operation> </portType> <binding name="PingServiceHttpSoap"> <operation name="echoString"> <soap:operation soapAction="urn:EchoString"/> </operation> </binding> </definitions>
NOTE: Beginning with Sun and HP JDK Version 1.6 containing JAX-WS tooling Version 2.1.6, the behavior of the JAX-WS runtime environment and tooling has changed how it interprets the JAX-WS specification regarding exposing methods as web services operations. When the web service does not specify a pre-existing WSDL file, the JAX-WS tooling behavior that generates a WSDL file has changed. This change does not affect web services that reference a WSDL file. The change in semantics might affect web services that do not reference a WSDL file or a SEI, and they rely on the JAX-WS runtime environment to create a WSDL file.
Using the NEW interpretation, a method in an implicit SEI and its superclasses are only exposed under the following conditions:
The method has an @WebMethod
or @WebMethod(exclude=false)
annotation.
The method has no @WebMethod
annotations, but the containing class has an
@WebService
annotation.
Using the LEGACY interpretation, a method in an implicit SEI and its superclasses are only exposed under the following conditions:
The method has an @WebMethod
or @WebMethod(exclude=false)
annotation and the
containing class has an @WebService
annotation.
The method has no @WebMethod
annotations, but the containing class has a
@WebService
annotation and no other methods have @WebMethod
or
@WebMethod(exclude=false)
annotations on it.
Example:
public class Base { @WebMethod(exclude=false) public void superMethod1(String s) {...} public String superMethod2(String s) {...} }
@WebService(targetNamespace="foo") public class BeanImpl extends Base { @WebMethod(exclude=false) public void method1(String s) {...} public String method2(String s) {...} }
Before JAX-WS 2.1.6, the only exposed method would be:
public void method1(String s) {...}
In JAX-WS 2.1.6 and later the following methods will be exposed:
public void superMethod1(String s) {...} public void method1(String s) {...} public String method2(String s) {...}
@javax.jws.soap.SOAPBinding
specifies the mapping of the web service onto the SOAP message protocol.
The SOAPBinding
annotation has a target of TYPE
and METHOD
. The annotation
may be placed on a method if and only if the SOAPBinding.style
is DOCUMENT
.
Implementations MUST report an error if the SOAPBinding
annotation is placed on a method with a
SOAPBinding.style
of RPC
. Methods that do not have a SOAPBinding
annotation
accept the SOAPBinding
behavior defined on the type.
The @SOAPBinding
annotation includes the following member-value pairs:
Table 1.3.
@javax.jws.soap.SOAPBinding
Member-Value | Meaning | Default |
---|---|---|
|
Defines the encoding style for messages send to and from the web service. One of
|
|
|
Defines the formatting style for messages sent to and from the web service. One of
|
|
|
Determines whether method parameters represent the entire message body, or whether the parameters are elements wrapped inside a top-level element named after the operation. |
|
@Retention(value=RetentionPolicy.RUNTIME) @Target({TYPE, METHOD}) public @interface SOAPBinding { public enum Style { DOCUMENT, RPC }; public enum Use { LITERAL, ENCODED }; public enum ParameterStyle { BARE, WRAPPED } Style style() default Style.DOCUMENT; Use use() default Use.LITERAL; ParameterStyle parameterStyle() default ParameterStyle.WRAPPED; }
RPC/LITERAL
Java source:
@WebService(targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample1") @SOAPBinding( style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL) public class ExampleService { @WebMethod public String concat(String first, String second, String third) { return first + second + third; } }
Resulting WSDL:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.openuri.org/jsr181/SoapBindingExample1" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample1"> <message name="concat"> <part name="first" type="xs:string"/> <part name="second" type="xs:string"/> <part name="third" type="xs:string"/> </message> <message name="concatResponse"> <part name="return" type="xs:string"/> </message> <portType name="ExampleService"> <operation name="concat"> <input message="tns:concat"/> <output message="tns:concatResponse"/> </operation </portType> <binding name="ExampleServiceHttpSoap" type="ExampleService"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="concat"> <soap:operation soapAction="http://www.openuri.org/jsr181/SoapBindingExample1/concat" /> <input> <soap:body parts="first second third" use="literal"/> </input> <output> <soap:body parts="return" use="literal"/> </output> </operation> </binding> </definitions>
DOCUMENT/LITERAL/BARE
Java source:
@WebService(targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample2") @SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE) public class DocBareService { @WebMethod( operationName="SubmitPO" ) public SubmitPOResponse submitPO(SubmitPORequest submitPORequest) { ... } }
Resulting WSDL:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.openuri.org/jsr181/SoapBindingExample2" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample2"> <types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample2"> <s:element name="SubmitPORequest"> . . . </s:element> <s:element name="SubmitPOResponse"> . . . </s:element> </s:schema> </types> <message name="SubmitPO"> <part name="parameters" element="tns:SubmitPORequest"/> </message> <message name="SubmitPOResponse"> <part name="parameters" element="tns:SubmitPOResponse"/> </message> <portType name="DocBareService"> <operation name="SubmitPO"> <input message="tns:SubmitPO"/> <output message="tns:SubmitPOResponse"/> </operation </portType> <binding name="DocBareServiceHttpSoap" type="ExampleService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="SubmitPO"> <soap:operation soapAction="http://www.openuri.org/jsr181/SoapBindingExample2/SubmitPO" /> <input> <soap:body parts="parameters" use="literal"/> </input> <output> <soap:body parts="parameters" use="literal"/> </output> </operation> </binding> </definitions>
DOCUMENT/LITERAL/WRAPPED
Java source:
@WebService(targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample3") @SOAPBinding( style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED) public class DocWrappedService { @WebMethod(operationName = "SubmitPO") @WebResult(name="PurchaseOrderAck") public PurchaseOrderAck submitPO( @WebParam(name="PurchaseOrder") PurchaseOrder purchaseOrder) { ... } }
Resulting WSDL:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.openuri.org/jsr181/SoapBindingExample3" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample3"> <types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample3"> <s:element name="SubmitPO"> <complexType> <sequence> <element name="PurchaseOrder" type="tns:PurchaseOrder"/> . . . </sequence> </complexType> </s:element> <s:element name="SubmitPOResponse"> . . . </s:element> </s:schema> </types> <message name="SubmitPO"> <part name="parameters" element="tns:SubmitPO"/> </message> <message name="SubmitPOResponse"> <part name="parameters" element="tns:SubmitPOResponse"/> </message> <portType name="DocWrappedService"> <operation name="SubmitPO"> <input message="tns:SubmitPO"/> <output message="tns:SubmitPOResponse"/> </operation </portType> <binding name="ExampleServiceHttpSoap" type="ExampleService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="SubmitPO"> <soap:operation soapAction="http://www.openuri.org/jsr181/SoapBindingExample3/SubmitPO" /> <input> <soap:body parts="parameters" use="literal"/> </input> <output> <soap:body parts="parameters" use="literal"/> </output> </operation> </binding> </definitions>
The @javax.jws.Oneway
annotation indicates that the given web method has only an input message and no
output. Typically, a oneway method returns the thread of control to the calling application prior to executing
the actual business method. A JSR-181 processor is REQUIRED to report an error if an operation marked
@Oneway
has a return value, declares any checked exceptions or has any INOUT or OUT parameters.
@Retention(value=RetentionPolicy.RUNTIME) @Target({METHOD}) public @interface Oneway { };
Java source:
@WebService public class PingService { @WebMethod @Oneway public void ping() { ... } }
Resulting WSDL:
<definitions> <message name="ping"/> ... <portType name="PingService"> <operation name="ping"> <input message="ping"/> </operation> </portType> </definitions>
WebParam
The @javax.jws.WebParam
annotation customizes the mapping of an individual parameter to a web service
message part and XML element.
Table 1.4.
@javax.jws.WebParam
Member-Value | Meaning | Default |
---|---|---|
|
Name of the parameter.
If the operation is rpc style and If the operation is document style or the parameter maps to a header, this is the local name of the XML element representing the parameter.
A name MUST be specified if the operation is document style, the parameter style is
|
Otherwise, the default is |
|
The name of the |
|
|
The XML namespace for the parameter. Only used if the operation is document style or the paramater maps to a header. If the target namespace is set to "", this represents the empty namespace. |
The empty namespace, if the operation is document style, the parameter style is WRAPPED, and the parameter does not map to a header.
Otherwise, the default is the |
|
The direction in which the parameter is flowing. One of |
|
|
If |
|
Java Source:
@WebService(targetNamespace="http://www.openuri.org/jsr181/WebParamExample") @SOAPBinding(style=SOAPBinding.Style.RPC) public class PingService { @WebMethod(operationName = "PingOneWay") @Oneway public void ping(PingDocument ping) { ... } @WebMethod(operationName = "PingTwoWay") public void ping( @WebParam(mode=WebParam.Mode.INOUT) PingDocumentHolder ping) { ... } @WebMethod(operationName = "SecurePing") @Oneway public void ping( PingDocument ping, @WebParam(header=true) SecurityHeader secHeader) { ... } }
Resulting WSDL:
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.openuri.org/jsr181/WebParamExample" xmlns:wsdl="http://www.openuri.org/jsr181/WebParamExample" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.openuri.org/jsr181/WebParamExample"> <types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.openuri.org/jsr181/WebParamExample"> <s:complexType name="PingDocument"> . . . </s:complexType> <s:complexType name="SecurityHeader"> . . . </s:complexType> <s:element name="SecurityHeader" type="SecurityHeader"/> </s:schema> </ types> <message name="PingOneWay"> <part name="arg0" type="tns:PingDocument"/> </message> <message name="PingTwoWay"> <part name="arg0" type="tns:PingDocument"/> </message> <message name="PingTwoWayResponse"> <part name="arg0" type="tns:PingDocument"/> </message> <message name="SecurePing"> <part name="arg0" type="tns:PingDocument"/> <part name="arg1" element="tns:SecurityHeader"/> </message> <portType name="PingService"> <operation name="PingOneWay"> <input message="tns:PingOneWay"/> </operation> <operation name="PingTwoWay"> <input message="tns:PingTwoWay"/> <output message="tns:PingTwoWayResponse"/> </operation> <operation name="SecurePing"> <input message="tns:SecurePing"/> </operation> </portType> <binding name="PingServiceHttpSoap" type="tns:PingService"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="PingOneWay"> <soap:operation soapAction="http://openuri.org/PingOneWay" /> <input> <soap:body parts="arg0" use="literal"/> </input> </operation> <operation name="PingTwoWay"> <soap:operation soapAction="http://openuri.org/PingTwoWay"/> <input> <soap:body parts="arg0" use="literal"/> </input> <output> <soap:body parts="arg0" use="literal"/> </output> </operation> <operation name="SecurePing"> <soap:operation soapAction="http://openuri.org/SecurePing"/> <input> <soap:body parts="arg0" use="literal"/> <soap:header message="SecurePing" part="arg1" use="literal"/> </input> </operation> </binding> </definitions>
WebResult
Use the @javax.jws.WebResult
annotation to map to an existing wsdl:output
or to customize how
it's generated.
Table 1.5.
@javax.jws.WebResult
Member-Value | Meaning | Default |
---|---|---|
|
Name of return value.
If the operation is rpc style and If the operation is document style or the return value maps to a header, this is the local name of the XML element representing the return value. |
Otherwise, the default is " |
|
The name of the |
|
|
The XML namespace for the return value. Only used if the operation is document style or the return value maps to a header. If the target namespace is set to "", this represents the empty namespace. |
The empty namespace, if the operation is document style, the parameter style is
Otherwise, the default is the |
|
If |
|
Java Source:
@WebService public class CustomerService { @WebMethod @WebResult(name="CustomerRecord") public CustomerRecord locateCustomer( @WebParam(name="FirstName") String firstName, @WebParam(name="LastName") String lastName, @WebParam(name="Address") USAddress addr) { ... } }
Resulting WSDL:
<definitions> <types> <complexType name="CustomerRecord"> ... </complexType> <complexType name="USAddress"> ... </complexType> <element name="locateCustomer"> <complexType> <sequence> <element name="FirstName" type="xs:string" /> <element name="LastName" type="xs:string" /> <element name="Address" type="USAddress"/> </sequence> </complexType> </element> <element name="locateCustomerResponse"> <complexType> <sequence> <element name="CustomerRecord" type="CustomerRecord"/> </sequence> </complexType> </element> </types> <message name="locateCustomer"> <part name="parameters" element="tns:locateCustomer"/> </message> <message name="locateCustomerResponse"> <part name="parameters" element="tns:locateCustomerResponse"/> </message> <portType name="CustomerService"> <operation name="locateCustomer"> <input message="tns:locateCustomer"/> <output message="tns:locateCustomerResponse"/> </operation> </portType> </definitions>
blah-blah
blah-blah
![]() |
![]() ![]() |