|
10 | 10 | <classname>MessageDispatcher</classname> that dispatches incoming
|
11 | 11 | messages to endpoints, with configurable endpoint mappings, response
|
12 | 12 | generation, and endpoint interception.
|
13 |
| - The simplest endpoint is a <interfacename>PayloadEndpoint</interfacename>, which just offers the |
14 |
| - <literal>Source invoke(Source request)</literal> method. You are of course free to |
15 |
| - implement this interface directly, but you will probably prefer to extend one of |
16 |
| - the included abstract implementations such as |
17 |
| - <classname>AbstractDomPayloadEndpoint</classname>, <classname>AbstractSaxPayloadEndpoint</classname>, and |
18 |
| - <classname>AbstractMarshallingPayloadEndpoint</classname>. |
19 |
| - Alternatively, there is a endpoint development that uses Java 5 annotations, such as |
20 |
| - <interfacename>@Endpoint</interfacename> for marking a POJO as endpoint, and marking a method with |
21 |
| - <interfacename>@PayloadRoot</interfacename> or <interfacename>@SoapAction</interfacename>. |
| 13 | + Endpoints are typically annotated with the <interfacename>@Endpoint</interfacename> annotation, and have |
| 14 | + one or more handling methods. |
| 15 | + These methods handle incoming XML request messages by inspecting parts of the message (typically the |
| 16 | + payload), and create some sort of response. |
| 17 | + You annotate the method with another annotation, typically <interfacename>@PayloadRoot</interfacename>, |
| 18 | + to indicate what sort of messages it can handle. |
22 | 19 | </para>
|
23 | 20 | <para>
|
24 | 21 | Spring-WS's XML handling is extremely flexible. An endpoint can choose from
|
|
62 | 59 | <listitem>
|
63 | 60 | <para>
|
64 | 61 | An appropriate endpoint is searched for using the configured <literal>EndpointMapping(s)</literal>.
|
65 |
| - If an endpoint is found, the invocation chain associated with the endpoint (preprocessors, |
66 |
| - postprocessors, and endpoints) will be executed in order to create a response. |
| 62 | + If an endpoint is found, the invocation chain associated with the endpoint (pre-processors, |
| 63 | + post-processors, and endpoints) will be executed in order to create a response. |
67 | 64 | </para>
|
68 | 65 | </listitem>
|
69 | 66 | <listitem>
|
|
185 | 182 | </para>
|
186 | 183 | </note>
|
187 | 184 | <para>
|
188 |
| - Another cool feature of the <classname>MessageDispatcherServlet</classname> (or more correctly the |
| 185 | + Another nice feature of the <classname>MessageDispatcherServlet</classname> (or more correctly the |
189 | 186 | <classname>WsdlDefinitionHandlerAdapter</classname>) is that it is able to
|
190 | 187 | transform the value of the '<literal>location</literal>' of all the WSDL that it exposes to reflect
|
191 | 188 | the URL of the incoming request.
|
|
257 | 254 | </para>
|
258 | 255 | <programlisting><![CDATA[
|
259 | 256 | <bean id="schemaCollection" class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
|
260 |
| - <description> |
261 |
| - This bean wrap the messages.xsd (which imports types.xsd), and inlines them as a one. |
262 |
| - </description> |
263 | 257 | <property name="xsds">
|
264 | 258 | <list>
|
265 | 259 | <value>/WEB-INF/xsds/Orders.xsd</value>
|
|
281 | 275 | Refer to the class-level Javadoc of these classes to see how you can extend this mechanism,
|
282 | 276 | if necessary.
|
283 | 277 | </para>
|
284 |
| - <note> |
| 278 | + <caution> |
285 | 279 | <para>
|
286 | 280 | Even though it can be quite handy to create the WSDL at runtime from your XSDs, there
|
287 | 281 | are a couple of drawbacks to this approach. First off, though we try to keep the WSDL generation
|
|
296 | 290 | <classname>SimpleWsdl11Definition</classname>. This is the only way to be really sure that
|
297 | 291 | the WSDL does not change over time.
|
298 | 292 | </para>
|
299 |
| - </note> |
| 293 | + </caution> |
300 | 294 | </section>
|
301 | 295 | </section>
|
302 | 296 | <section>
|
|
591 | 585 | request message and uses that input to invoke a method on the business service (typically). The result of that service
|
592 | 586 | invocation is represented as a response message. Spring-WS has a wide variety of endpoints, using various
|
593 | 587 | ways to handle the XML message, and to create a response.
|
594 |
| - </para> |
| 588 | + </para> |
595 | 589 | <para>
|
596 |
| - The basis for most endpoints in Spring Web Services is the |
597 |
| - <interfacename>org.springframework.ws.server.endpoint.PayloadEndpoint</interfacename> interface, the source |
598 |
| - code of which is listed below. |
| 590 | + You create an endpoint by annotating a class with the <interfacename>@Endpoint</interfacename> annotation. |
| 591 | + In the class, you define one or more methods that handle the incoming XML request, by using a wide |
| 592 | + variety of parameter types (such as DOM elements, JAXB2 objects, etc). |
| 593 | + You indicate the sort of messages a method can handle by using another annotation (typically |
| 594 | + <interfacename>@PayloadRoot</interfacename>). |
599 | 595 | </para>
|
600 |
| - <programlisting><![CDATA[public interface PayloadEndpoint { |
| 596 | + <para> |
| 597 | + Consider the following sample endpoint: |
| 598 | + <programlistingco> |
| 599 | + <areaspec> |
| 600 | + <area coords="9" id="server-endpoint-atEndpoint"/> |
| 601 | + <area coords="14" id="server-endpoint-constructor"/> |
| 602 | + <area coords="20" id="server-endpoint-order"/> |
| 603 | + <area coords="27" id="server-endpoint-getOrder"/> |
| 604 | + <areaset coords="" id="server-endpoint-payloadRoot"> |
| 605 | + <area coords="19" id="server-endpoint-payloadRoot-1"/> |
| 606 | + <area coords="25" id="server-endpoint-payloadRoot-2"/> |
| 607 | + </areaset> |
| 608 | + </areaspec> |
| 609 | + <programlisting><![CDATA[package samples; |
| 610 | +
|
| 611 | +import org.w3c.dom.Element; |
| 612 | +
|
| 613 | +import org.springframework.beans.factory.annotation.Autowired; |
| 614 | +import org.springframework.ws.server.endpoint.annotation.Endpoint; |
| 615 | +import org.springframework.ws.server.endpoint.annotation.PayloadRoot; |
| 616 | +
|
| 617 | +@Endpoint |
| 618 | +public class AnnotationOrderEndpoint { |
| 619 | +
|
| 620 | + private final OrderService orderService; |
| 621 | +
|
| 622 | + @Autowired |
| 623 | + public AnnotationOrderEndpoint(OrderService orderService) { |
| 624 | + this.orderService = orderService; |
| 625 | + } |
| 626 | +
|
| 627 | + @PayloadRoot(localPart = "order", namespace = "http://samples") |
| 628 | + public void order(@RequestPayload Element orderElement) { |
| 629 | + Order order = createOrder(orderElement); |
| 630 | + orderService.createOrder(order); |
| 631 | + } |
| 632 | +
|
| 633 | + @PayloadRoot(localPart = "orderRequest", namespace = "http://samples") |
| 634 | + @ResponsePayload |
| 635 | + public Order getOrder(@RequestPayload OrderRequest orderRequest) { |
| 636 | + return orderService.getOrder(orderRequest.getId()); |
| 637 | + } |
| 638 | +
|
| 639 | + ... |
601 | 640 |
|
602 |
| - ]]><lineannotation>/** |
603 |
| - * Invokes an operation. |
604 |
| - */</lineannotation><![CDATA[ |
605 |
| - Source invoke(Source request) throws Exception; |
606 | 641 | }]]></programlisting>
|
607 |
| - <para> |
608 |
| - As you can see, the <interfacename>PayloadEndpoint</interfacename> interface defines a single method that |
609 |
| - is invoked with the XML payload of a request (typically the contents of the SOAP Body, see |
610 |
| - <xref linkend="soap-message"/>). The returned <interfacename>Source</interfacename>, if any, is stored in the |
611 |
| - response XML message. While the <interfacename>PayloadEndpoint</interfacename> interface is quite abstract, |
612 |
| - Spring-WS offers a lot of endpoint implementations out of the box that already contain a lot of the |
613 |
| - functionality you might need. The <interfacename>PayloadEndpoint</interfacename> interface just defines the |
614 |
| - most basic responsibility required of every endpoint; namely handling a request and returning a response. |
| 642 | + <calloutlist> |
| 643 | + <callout arearefs="server-endpoint-atEndpoint"> |
| 644 | + <para> |
| 645 | + The class is annotated with <interfacename>@Endpoint</interfacename>, marking it as a |
| 646 | + Spring-WS endpoint. |
| 647 | + </para> |
| 648 | + </callout> |
| 649 | + <callout arearefs="server-endpoint-constructor"> |
| 650 | + <para> |
| 651 | + The constructor is marked with <interfacename>@Autowired</interfacename>, so that the |
| 652 | + <classname>OrderService</classname> business service is injected into this endpoint. |
| 653 | + </para> |
| 654 | + </callout> |
| 655 | + <callout arearefs="server-endpoint-order"> |
| 656 | + <para> |
| 657 | + The <methodname>order</methodname> method takes a <interfacename>Element</interfacename> |
| 658 | + as a parameter, annotated with <interfacename>@RequestPayload</interfacename>. |
| 659 | + This means that the payload of the message is passed on this method as a DOM element. |
| 660 | + The method has a <literal>void</literal> return type, indicating that no response message |
| 661 | + is sent. |
| 662 | + </para> |
| 663 | + <para> |
| 664 | + For more information about endpoint methods, refer to |
| 665 | + <xref linkend="server-atEndpoint-methods"/>. |
| 666 | + </para> |
| 667 | + </callout> |
| 668 | + <callout arearefs="server-endpoint-getOrder"> |
| 669 | + <para> |
| 670 | + The <methodname>getOrder</methodname> method takes a <classname>OrderRequest</classname> |
| 671 | + as a parameter, annotated with <interfacename>@RequestPayload</interfacename> as well. |
| 672 | + This parameter is a JAXB2-supported object (it is annotated with |
| 673 | + <interfacename>@XmlRootElement</interfacename>). |
| 674 | + This means that the payload of the message is passed on to this method as a unmarshalled |
| 675 | + object. |
| 676 | + The method is also annotated with <interfacename>@ResponseBody</interfacename>, |
| 677 | + indicating that the return value (the <classname>Order</classname>) is used as the payload |
| 678 | + of the response message. |
| 679 | + </para> |
| 680 | + <para> |
| 681 | + For more information about endpoint methods, refer to |
| 682 | + <xref linkend="server-atEndpoint-methods"/>. |
| 683 | + </para> |
| 684 | + </callout> |
| 685 | + <callout arearefs="server-endpoint-payloadRoot"> |
| 686 | + <para> |
| 687 | + The two handling methods of this endpoint are marked with |
| 688 | + <interfacename>@PayloadRoot</interfacename>, indicating what sort of request messages |
| 689 | + can be handled by the method: the <methodname>getOrder</methodname> method |
| 690 | + will be invoked for requests with a <literal>orderRequest</literal> local name and a |
| 691 | + <uri>http://samples</uri> namespace URI; the <methodname>order</methodname> method |
| 692 | + for requests with a <literal>order</literal> local name. |
| 693 | + </para> |
| 694 | + <para> |
| 695 | + For more information about <interfacename>@PayloadRoot</interfacename>, refer to |
| 696 | + <xref linkend="server-endpoint-mapping"/>. |
| 697 | + </para> |
| 698 | + </callout> |
| 699 | + </calloutlist> |
| 700 | + </programlistingco> |
615 | 701 | </para>
|
616 | 702 | <para>
|
617 |
| - Alternatively, there is the <interfacename>MessageEndpoint</interfacename>, which operates on a |
618 |
| - whole <link linkend="message-context"><interfacename>MessageContext</interfacename></link> rather than just |
619 |
| - the payload. Typically, your code should not be dependent on messages, because the payload should |
620 |
| - contain the information of interest. Only when it is necessary to perform actions on the message as a whole, |
621 |
| - such as adding a SOAP header, get an attachment, and so forth, should you need to implement |
622 |
| - <interfacename>MessageEndpoint</interfacename>, though these actions are usually performed in an |
623 |
| - <link linkend="server-endpoint-interceptor">endpoint interceptor</link>. |
| 703 | + In the next couple of sections, a more elaborate description of the <interfacename>@Endpoint</interfacename> |
| 704 | + programming model is given. |
624 | 705 | </para>
|
625 | 706 | <note>
|
626 | 707 | <para>
|
|
631 | 712 | <ulink url="http://static.springframework.org/spring/docs/2.5.x/reference/beans.html#beans-factory-scopes">Spring Reference documentation</ulink>.
|
632 | 713 | </para>
|
633 | 714 | <para>
|
634 |
| - Note that all abstract base classes provided in Spring-WS (like AbstractDomPayloadEndpoint etc) are |
635 |
| - thread safe. |
| 715 | + Note that all abstract base classes provided in Spring-WS are thread safe, unless otherwise indicated |
| 716 | + in the class-level Javadoc. |
636 | 717 | </para>
|
637 | 718 | </note>
|
| 719 | + <section id="server-atEndpoint-methods"> |
| 720 | + <title><interfacename>@Endpoint</interfacename> handling methods</title> |
| 721 | + <para> |
| 722 | + In order for an endpoint to actually handle incoming XML messages, it needs to have one or more handling |
| 723 | + methods. |
| 724 | + Handling methods can take wide range of parameters and return types, but typically they have one |
| 725 | + parameter that will contain the message payload, and they return the payload of the response message |
| 726 | + (if any). |
| 727 | + You will learn which parameter and return types are supported in this section. |
| 728 | + </para> |
| 729 | + <para> |
| 730 | + To indicate what sort of messages a method can handle, the method is typically annotated with either the |
| 731 | + <interfacename>@PayloadRoot</interfacename> or <interfacename>@SoapAction</interfacename> annotation. |
| 732 | + You will learn more about these annotations in <xref linkend="server-endpoint-mapping"/>. |
| 733 | + </para> |
| 734 | + <para> |
| 735 | + Here is an example of a handling method: |
| 736 | + <programlisting>@PayloadRoot(localPart = "order", namespace = "http://samples") |
| 737 | +public void order(@RequestPayload Element orderElement) { |
| 738 | + Order order = createOrder(orderElement); |
| 739 | + orderService.createOrder(order); |
| 740 | +}</programlisting> |
| 741 | + The <methodname>order</methodname> method takes a <interfacename>Element</interfacename> |
| 742 | + as a parameter, annotated with <interfacename>@RequestPayload</interfacename>. |
| 743 | + This means that the payload of the message is passed on this method as a DOM element. |
| 744 | + The method has a <literal>void</literal> return type, indicating that no response message |
| 745 | + is sent. |
| 746 | + </para> |
| 747 | + <section> |
| 748 | + <title>Handling method parameters</title> |
| 749 | + <para> |
| 750 | + The handling method typically has one or more parameters that refer to various parts of the |
| 751 | + incoming XML message. |
| 752 | + Most commonly, the handling method will have a single parameter that will map to the payload of |
| 753 | + the message, but it is also possible to map to other parts of the message, such as a SOAP header. |
| 754 | + This section will describe the parameters you can use in your handling method signatures. |
| 755 | + </para> |
| 756 | + <para> |
| 757 | + One |
| 758 | + </para> |
| 759 | + </section> |
| 760 | + <section> |
| 761 | + <title>Handling method return types</title> |
| 762 | + <para> |
| 763 | + |
| 764 | + </para> |
| 765 | + </section> |
| 766 | + </section> |
638 | 767 | <section>
|
639 | 768 | <title><classname>AbstractDomPayloadEndpoint</classname> and other DOM endpoints</title>
|
640 | 769 | <para>
|
|
0 commit comments