# Provider

Web Service endpoints may choose to work at the XML message level by implementing the `Provider` interface. This is achieved by implementing either `Provider<Source>` or `Provider<SOAPMessage>` or `Provider<DataSource>`. The endpoint accesses the message or message payload using this low-level, generic API. All the Provider endpoints must have `@WebServiceProvider` annotation. The `@ServiceMode` annotation is used to convey whether the endpoint wants to access the message ( `Service.Mode.MESSAGE`) or payload ( `Service.Mode.PAYLOAD`). If there is no `@ServiceMode` annotation on the endpoint, payload is the default value. The endpoint communicates with handlers using `WebServiceContext resource like any other normal endpoint`. Provider endpoints can start from java or WSDL. When the provider endpoints start from a WSDL file, `<provider>` WSDL customization can be used to mark a port as a provider.

## `Provider<Source>` and `PAYLOAD`

An endpoint can access only the payload of a request using `Service.Mode.PAYLOAD` in the `@ServiceMode` annotation. This is the default behaviour, if the annotation is missing.

For example:

    @WebServiceProvider
    public class ProviderImpl implements Provider<Source> {
        public Source invoke(Source source) { // do request processing Source
            response = ...;
            return response;
        }
    }

## `Provider<SOAPMessage>` and `MESSAGE`

An endpoint can access an entire SOAP request as a `SOAPMessage`. `Service.Mode.MESSAGE` in the `@ServiceMode` annotation is used to convey the intent.

For example:

    @WebServiceProvider
    @ServiceMode(value = Service.Mode.MESSAGE)
    public class ProviderImpl implements Provider<SOAPMessage> {
        public SOAPMessage invoke(SOAPMessage msg) { // do request processing
            SOAPMessage response =...;
            return response;
        }
    }

## `Provider<Source>` and `MESSAGE`

An endpoint can access a request as a `Source`. If the request is a `SOAPMessage`, only the `SOAPPart` (no attachments) of the message is passed as `Source` to the `invoke` method. If the returned response is null, it is considered a one way MEP.

For example:

    @ServiceMode(value = Service.Mode.MESSAGE)
    public class ProviderImpl implements Provider<Source> {
        public Source invoke(Source source) { // do request processing
            using source // return null to indicate oneway return null;
        }
    }

## WSDL Customization

If the provider endpoint starts with a WSDL file, a port can be customized to a provider endpoint using the `<provider>` customization. `wsimport` won't generate any artifacts for that port.

For example:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <bindings
            ...
            wsdlLocaption="AddNumbers.wsdl"xmlns="http://java.sun.com/xml/ns/jaxws">
        <bindings node="wsdl:definitions">
            <package name="provider.server"/>
            <provider>true</provider>
        </bindings>
    </bindings>

## The `sun-jaxws.xml` file

The attributes of provider endpoint in sun-jaxws.xml: name, implementation, wsdl, service, port override the attributes provided through `@WebServiceProvider` annotation. For SOAP1.2 binding, one needs to specify binding attribute.

For example:

    <?xml version="1.0" encoding="UTF-8"?>
    <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
            version='2.0'>
        <endpoint name='AddNumbers'
                implementation='provider.server.AddNumbersImpl'
                wsdl='WEB-INF/wsdl/AddNumbers.wsdl'
                service='{http://duke.example.org}AddNumbersService'
                port='{http://duke.example.org}AddNumbersPort'
                url-pattern='/addnumbers'/>
    </endpoints>

If the wsdl, service, port are not specified in sun-jaxws.xml, then should be declared in the `@WebServiceProvider` annotation in implementation class.

## Provider and Binding

Provider endpoint can be configured for different bindings using binding ids. These binding ids are defined in JAX-WS API and endpoint can be configured by specifying `@BindingType` annotation or using binding attribute in sun-jaxws.xml. sun-jaxws.xml overwrites binding defined by `@BindingType` annotation. If the binding is not specified using `@BindingType` or in `sun-jaxws.xml`, the default binding is SOAP1.1/HTTP.

For example: To specify `XML/HTTP` binding using `@BindingType` annotation

    @ServiceMode(value = Service.Mode.MESSAGE)
    @BindingType(value = HTTPBinding.HTTP_BINDING)
    public class ProviderImpl implements Provider<Source> {
        public Source invoke(Source source) {
            // ...
        }
    }

For example: To specify `XML/HTTP` binding in `sun-jaxws.xml`

    <?xml version="1.0" encoding="UTF-8"?>
    <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
            version='2.0'>
        <endpoint
                ...
                binding="http://www.w3.org/2004/08/wsdl/http"/>
    </endpoints>

## RESTful Provider endpoints

RESTful Web Services can be built using `XML/HTTP` binding based `Provider` endpoints. In this case, even HTTP GET requests are passed to the endpoint. `Endpoint` can get necessary HTTP request query string and path information using standard `MessageContext.QUERY_STRING` and `MessageContext.PATH_INFO`. For more details on endpoint implementation, see the `samples/restful/src/restful/server/AddNumbersImpl.java` sample. If the endpoint expects GET requests to contain extra path after the endpoint address, then `url-pattern` should have "`/*`" at the end in both `sun-jaxws.xml` and `web.xml`.

For example: `sun-jaxws.xml`

    <?xml version="1.0" encoding="UTF-8"?>
    <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
            version='2.0'>
        <endpoint
                ...
                binding="http://www.w3.org/2004/08/wsdl/http"
                url-pattern="/addnumbers/*"/>
    </endpoints>

For example: `web.xml`

    <web-app>

        ...

        <servlet-mapping>
            <servlet-name>provider</servlet-name>
            <url-pattern>/addnumbers/*</url-pattern>
        </servlet-mapping>

        ...

    </web-app>

## Provider and Handlers

Handlers can be configured with Provider endpoints in `sun-jaxws.xml` descriptor or by putting `@HandlerChain` on the `Provider` implementation.

For example:

    <?xml version="1.0" encoding="UTF-8"?>
    <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
            xmlns:javaee="http://java.sun.com/xml/ns/javaee" version='2.0'>
        <endpoint name='AddNumbers'
                implementation='provider.server.AddNumbersImpl'
                wsdl='WEB-INF/wsdl/AddNumbers.wsdl'
                service='{http://duke.example.org}AddNumbersService'
                port='{http://duke.example.org}AddNumbersPort'
                url-pattern='/addnumbers'/>
        <javaee:handler-chain>
            <javaee:handler-chain-name>my handler</javaee:handler-chain-name>
            <javaee:handler>
                <javaee:handler-name>MyHandler</javaee:handler-name>
                <javaee:handler-class>provider.server.MyHandler
                </javaee:handler-class>
            </javaee:handler>
        </javaee:handler-chain>
    </endpoints>