diff --git a/src/docbkx/server.xml b/src/docbkx/server.xml index 25a6a327..8fd2a4d7 100644 --- a/src/docbkx/server.xml +++ b/src/docbkx/server.xml @@ -586,13 +586,13 @@ Consider the following sample endpoint: - - - - + + + + - - + + @XmlRootElement). This means that the payload of the message is passed on to this method as a unmarshalled object. - The method is also annotated with @ResponseBody, + The SoapHeader type is also given as a parameter. + On invocation, this parameter will contain the SOAP header of the request message. + The method is also annotated with @ResponsePayload, indicating that the return value (the Order) is used as the payload of the response message. @@ -833,7 +837,7 @@ public void order(@RequestPayload Element orderElement) { and that is annotated with @XPathParam. - Enabled by default. + Enabled by default, see . Message context @@ -909,451 +913,170 @@ public void order(@RequestPayload Element orderElement) { Refer to the class-level Javadoc of DefaultMethodEndpointAdapter and MethodArgumentResolver to see how. - -
- Handling method return types - - To map the return value to the payload of the response message, you will need to annotate the - method with the @ResponsePayload annotation. - This annotation tells Spring-WS that the return value needs to be bound to the response payload. - -
- -
- <classname>AbstractDomPayloadEndpoint</classname> and other DOM endpoints - - One of the most basic ways to handle the incoming XML payload is by using a DOM (Document Object Model) - API. By extending from AbstractDomPayloadEndpoint, you can use the - org.w3c.dom.Element and related classes to handle the request and create the - response. When using the AbstractDomPayloadEndpoint as the baseclass for your - endpoints you only have to override the invokeInternal(Element, Document) - method, implement your logic, and return an Element if a response is - necessary. Here is a short example consisting of a class and a declaration in the application context. - - - - -]]> - - The above class and the declaration in the application context are all you need besides setting up an - endpoint mapping (see the section entitled ) to get this very - simple endpoint working. The SOAP message handled by this endpoint will look something like: - - - ]]> - Hello - ]]> -]]> - - Though it could also handle the following Plain Old XML (POX) message, since we are only working on - the payload of the message, and do not care whether it is SOAP or POX. - - - Hello -]]> - - The SOAP response looks like: - - - ]]> - Hello World! - ]]> -]]> - - Besides the AbstractDomPayloadEndpoint, which uses W3C DOM, there are other - base classes which use alternative DOM APIs. Spring Web Services supports most DOM APIs, so that you - can use the one you are familiar with. For instance, the - AbstractJDomPayloadEndpoint allows you to use JDOM, and the - AbstractXomPayloadEndpoint uses XOM to handle the XML. All of these endpoints - have an invokeInternal method similar to above. - Also, consider using Spring-WS's XPath support to extract the information you need out of the payload. - (See the section entitled for details.) - -
-
- <classname>AbstractMarshallingPayloadEndpoint</classname> - - Rather than handling XML directly using DOM, you can use marshalling to convert the payload of the XML - message into a Java Object. Spring Web Services offers the - AbstractMarshallingPayloadEndpoint for this purpose, which is built on the - Spring's OXM package. The - AbstractMarshallingPayloadEndpoint has two properties: - marshaller and unmarshaller, in which you can inject in the - constructor or by setters. - - - When extending from AbstractMarshallingPayloadEndpoint, you have to override - the invokeInternal(Object) method, where the passed - Object represents the unmarshalled request payload, and return an - Object that will be marshalled into the response payload. Here is an - example: - - - - - - - - - - - - samples.OrderRequest - samples.Order - - - - - - - ]]><!-- Other beans, such as the endpoint mapping -->]]> - - In this sample, we configure a - Jaxb2Marshaller - for the - OrderRequest and Order classes, and inject that - marshaller together with the - DefaultOrderService into our endpoint. This business service is not shown, but - it is a normal transactional service, probably using DAOs to obtain data from a database. - In the invokeInternal method, we cast the request object to an - OrderRequest object, which is the JAXB object representing the payload of the - request. Using the identifier of that request, we obtain an order from our business service and return - it. The returned object is marshalled into XML, and used as the payload of the response message. - The SOAP request handled by this endpoint will look like: - - - - - - -]]> - - The resulting response will be something like: - - - - - - 1 - 20.0 - - - 1 - 10.0 - - - -]]> - - Instead of JAXB 2, we could have used any Spring OXM marshallers. - The only thing that would change in the above example is the configuration of the - marshaller bean. - -
-
- Using Spring <interfacename>Validator</interfacename> with Marshalling Endpoints - - It is possible to use Validator - objects in conjunction with marshalling endpoints in order to validate the unmarshalled payloads. - Spring-WS provides 2 extensions of AbstractMarshallingPayloadEndpoint for that purpose: - AbstractValidatingMarshallingPayloadEndpoint and - AbstractFaultCreatingValidatingMarshallingPayloadEndpoint. The former is the most - general whereas the latter specializes in creating SOAP faults in response to validation errors. - - - Both classes support setting one or more Validator objects via the - validator and validators properties respectively. - Note that all of the injected validators - must support the request object (through the supports method) - or else an IllegalArgumentException will be thrown. - - - - The default request object name used in the validator is request. - The error codes are generated in consequence. For instance, assuming a POJO with a - "name" property of type java.lang.String, - calling errors.rejectValue("name","invalidValue") in the - validate method of a Validator - generates the following error codes: - invalidValue.request.name, invalidValue.name, - invalidValue.java.lang.String and invalidValue. - Similarly, calling errors.reject("invalidValue") - generates invalidValue.request and invalidValue as error codes. - - -
- <classname>AbstractValidatingMarshallingPayloadEndpoint</classname> - - Subclasses of AbstractValidatingMarshallingPayloadEndpoint - implement the validation error handling logic by overriding the onValidationErrors - method. This method is called when a validation error occurs and its return value - indicates whether the endpoint should continue processing the request or not. - - - In the following example, a custom error POJO is marshalled and sent as a response: - - -
-
- <classname>AbstractFaultCreatingValidatingMarshallingPayloadEndpoint</classname> - - Endpoints of this type generate a SOAP fault whenever a validation error occurs. - By default, a fault detail element is generated for each validation error. - The error codes are resolved using the application context message source. - - - The properties of AbstractFaultCreatingValidatingMarshallingPayloadEndpoint - have sensible defaults, which makes its subclasses quite simple to configure as in the following example: - - - - - - - - - - - - -]]> - - In case of validation error, here is how the response might look like: - - - - - - SOAP-ENV:Client - Validation error - - - invalid user id: Ernie - - - invalid order - - - - - -]]> - - It is possible though to customize various aspects of the generated SOAP faults, such as the fault string - and the soap detail. - Please refer to the Javadoc - for the full list of available options. - -
-
-
- <interfacename>@Endpoint</interfacename> - - The previous two programming models were based on inheritance, and handled individual XML messages. - Spring Web Services offer another endpoint with which you can aggregate multiple handling into one - controller, thus grouping functionality together. This model is based on annotations, so you can use - it only with Java 5 and higher. Here is an example that uses the same marshalled objects as above: - - - - By annotating the class with @Endpoint, you mark it as a Spring-WS - endpoint. Because the endpoint class can have multiple request handling methods, we need to instruct - Spring-WS which method to invoke for which request. This is done using the - @PayloadRoot annotation: the getOrder method - will be invoked for requests with a orderRequest local name and a - http://samples namespace URI; the order method for requests with - a order local name. For more information about these annotations, refer to - . - We also need to configure Spring-WS to support the JAXB objects OrderRequest and - Order by defining a Jaxb2Marshaller: - - - - - - - - - - - - - - - - - samples.OrderRequest - samples.Order - - - - - - -]]> - - The GenericMarshallingMethodEndpointAdapter converts the incoming - XML messages to marshalled objects used as parameters and return value; the - PayloadRootAnnotationMethodEndpointMapping is the mapping that detects and - handles the @PayloadRoot annotations. - -
- <interfacename>@XPathParam</interfacename> - - As an alternative to using marshalling, we could have used XPath to - extract the information out of the incoming XML request. Spring-WS offers another annotation for - this purpose: @XPathParam. You simply annotate one or more method - parameter with this annotation (each), and each such annotated parameter will be bound to the - evaluation of that annotation. Here is an example: - - + <interfacename>@XPathParam</interfacename> + + One parameter type needs some extra explanation: @XPathParam. + The idea here is that you simply annotate one or more method + parameter with an XPath expression, and that each such annotated parameter will be bound to the + evaluation of the expression. + Here is an example: + + package samples; import javax.xml.transform.Source; import org.springframework.ws.server.endpoint.annotation.Endpoint; +import org.springframework.ws.server.endpoint.annotation.Namespace; import org.springframework.ws.server.endpoint.annotation.PayloadRoot; import org.springframework.ws.server.endpoint.annotation.XPathParam; @Endpoint public class AnnotationOrderEndpoint { - private final OrderService orderService; + private final OrderService orderService; - public AnnotationOrderEndpoint(OrderService orderService) { - this.orderService = orderService; - } + public AnnotationOrderEndpoint(OrderService orderService) { + this.orderService = orderService; + } - @PayloadRoot(localPart = "orderRequest", namespace = "http://samples") - public Source getOrder(]]>// create Source from order and return it@Namespace(prefix = "s", uri="http://samples") + public Order getOrder(@XPathParam("/s:orderRequest/@id") int orderId) { + Order order = orderService.getOrder(orderId); + // create Source from order and return it +} -}]]> +} + + Since we use the prefix 's' in our XPath expression, we must bind it to the + http://samples namespace. + This is accomplished with the @Namespace annotation. + Alternatively, we could have placed this annotation on the type-level to use the same namespace + mapping for all handler methods, or even the package-level + (in package-info.java) to use it for multiple endpoints. + + + Using the @XPathParam, you can bind to all the data types + supported by XPath: + + boolean or Boolean + double or Double + String + Node + NodeList + + In addition to this list, you can use any type that can be converted from a + String by a Spring 3 + conversion service. + +
+ +
+
+ Handling method return types - Since we use the prefix 's' in our XPath expression, we must bind it to the - http://samples namespace: + To send a response message, the handling needs to specify a return type. + If no response message is required, the method can simply declare a void return + type. + Most commonly, the return type is used to create the payload of the response message, but it is + also possible to map to other parts of the response message. + This section will describe the return types you can use in your handling method signatures. - - - - - - - - - - - ]]> - - - http://samples - - - ]]>]]> - Using the @XPathParam, you can bind to all the data types supported by - XPath: - - boolean or Boolean - double or Double - String - Node - NodeList - + To map the return value to the payload of the response message, you will need to annotate the + method with the @ResponsePayload annotation. + This annotation tells Spring-WS that the return value needs to be bound to the response payload. + + + The following table describes the supported return types. + It shows the supported types, whether the parameter should be annotated with + @ResponsePayload, and any additional notes. + + + + + Name + Supported return types + @ResponsePayload required? + Additional notes + + + + + No response + + void + + + Enabled by default. + + + TrAX + + javax.xml.transform.Source and sub-interfaces + (DOMSource, SAXSource, + StreamSource, and StAXSource) + + + Enabled by default. + + + W3C DOM + org.w3c.dom.Element + + Enabled by default + + + dom4j + org.dom4j.Element + + Enabled when dom4j is on the classpath. + + + JDOM + org.jdom.Element + + Enabled when JDOM is on the classpath. + + + XOM + nu.xom.Element + + Enabled when XOM is on the classpath. + + + JAXB2 + + Any type that is annotated with + javax.xml.bind.annotation.XmlRootElement, + and javax.xml.bind.JAXBElement. + + + Enabled when JAXB2 is on the classpath. + + + OXM + + Any type supported by a Spring OXM + Marshaller. + + + + Enabled when the marshaller attribute of + <sws:annotation-driven/> is specified. + + + + + + + + As you can see, there are a lot of possibilities when it comes to defining handling method + signatures. + It is even possible to extend this mechanism, and to support your own parameter types. + Refer to the class-level Javadoc of DefaultMethodEndpointAdapter and + MethodReturnValueHandler to see how.
@@ -1361,8 +1084,8 @@ public class AnnotationOrderEndpoint {
Endpoint mappings - The endpoint mapping is responsible for mapping incoming messages to appropriate endpoints. There are some - endpoint mappings you can use out of the box, for example, the + The endpoint mapping is responsible for mapping incoming messages to appropriate endpoints. + There are some endpoint mappings you can use out of the box, for example, the PayloadRootQNameEndpointMapping or the SoapActionEndpointMapping, but let's first examine the general concept of an EndpointMapping.