Skip to content

Commit

Permalink
Review reference guide
Browse files Browse the repository at this point in the history
Closes gh-1475
  • Loading branch information
snicoll committed Mar 5, 2025
1 parent ae1029e commit 10f4a3b
Show file tree
Hide file tree
Showing 16 changed files with 275 additions and 308 deletions.
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ version=4.0.12-SNAPSHOT

org.gradle.caching=true
org.gradle.parallel=true

springFrameworkVersion=6.0.23
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
import org.springframework.ws.mime.MimeMessage;

/**
* Represents an abstraction for SOAP messages, providing access to a SOAP Envelope. The
* contents of the SOAP body can be retrieved by {@code getPayloadSource()} and
* {@code getPayloadResult()} on {@code WebServiceMessage}, the super-interface of this
* interface.
* Represents an abstraction for SOAP messages, providing access to a
* {@linkplain #getEnvelope() SOAP Envelope}. The contents of the SOAP body can be
* retrieved by {@link #getPayloadSource()} and {@link #getPayloadResult()} on
* {@code WebServiceMessage}, the super-interface of this interface.
*
* @author Arjen Poutsma
* @see #getPayloadSource()
Expand All @@ -35,7 +35,9 @@
*/
public interface SoapMessage extends MimeMessage, FaultAwareWebServiceMessage {

/** Returns the {@code SoapEnvelope} associated with this {@code SoapMessage}. */
/**
* Returns the {@link SoapEnvelope} associated with this message.
*/
SoapEnvelope getEnvelope() throws SoapEnvelopeException;

/**
Expand All @@ -51,15 +53,15 @@ public interface SoapMessage extends MimeMessage, FaultAwareWebServiceMessage {
void setSoapAction(String soapAction);

/**
* Returns the {@code SoapBody} associated with this {@code SoapMessage}. This is a
* convenience method for {@code getEnvelope().getBody()}.
* Returns the {@link SoapBody} associated with this message. This is a convenience
* method for {@code getEnvelope().getBody()}.
* @see SoapEnvelope#getBody()
*/
SoapBody getSoapBody() throws SoapBodyException;

/**
* Returns the {@code SoapHeader} associated with this {@code SoapMessage}. This is a
* convenience method for {@code getEnvelope().getHeader()}.
* Returns the {@link SoapHeader} associated with this message. This is a convenience
* method for {@code getEnvelope().getHeader()}.
* @see SoapEnvelope#getHeader()
*/
SoapHeader getSoapHeader() throws SoapHeaderException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
* @see HttpClient
* @see #setCredentials(Credentials)
* @since 1.0.0
* @deprecated In favor of {@link HttpComponentsMessageSender}
* @deprecated In favor of {@link HttpComponents5MessageSender}
*/
@Deprecated
public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSender
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* execute POST requests, without support for HTTP authentication or advanced
* configuration options.
* <p>
* Consider {@link HttpComponentsMessageSender} for more sophisticated needs: this class
* Consider {@link HttpComponents5MessageSender} for more sophisticated needs: this class
* is rather limited in its capabilities.
*
* @author Arjen Poutsma
Expand Down
2 changes: 2 additions & 0 deletions spring-ws-docs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ asciidoctorj {
attributes = [
"allow-uri-read": true,
"numbered": true,
"spring-framework-version": springFrameworkVersion,
"spring-ws-version": project.version,
"toclevels": 4
]
options = [
Expand Down
151 changes: 76 additions & 75 deletions spring-ws-docs/src/docs/asciidoc/client.adoc

Large diffs are not rendered by default.

64 changes: 20 additions & 44 deletions spring-ws-docs/src/docs/asciidoc/common.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This section describes the messages and message factories that Spring-WS uses.
[[web-service-message]]
=== `WebServiceMessage`

One of the core interfaces of Spring Web Services is the `WebServiceMessage`. This interface represents a protocol-agnostic XML message. The interface contains methods that provide access to the payload of the message, in the form of a `javax.xml.transform.Source` or a `javax.xml.transform.Result`. `Source` and `Result` are tagging interfaces that represent an abstraction over XML input and output. Concrete implementations wrap various XML representations, as indicated in the following table:
One of the core interfaces of Spring-WS is the `WebServiceMessage`. This interface represents a protocol-agnostic XML message. The interface contains methods that provide access to the payload of the message, in the form of a `javax.xml.transform.Source` or a `javax.xml.transform.Result`. `Source` and `Result` are tagging interfaces that represent an abstraction over XML input and output. Concrete implementations wrap various XML representations, as indicated in the following table:

[cols="2", options="header"]
|===
Expand Down Expand Up @@ -49,7 +49,7 @@ In addition to reading from and writing to the payload, a web service message ca
[[message-factories]]
=== Message Factories

Concrete message implementations are created by a `WebServiceMessageFactory`. This factory can create an empty message or read a message from an input stream. There are two concrete implementations of `WebServiceMessageFactory`. One is based on SAAJ, the SOAP with Attachments API for Java. The other is based on Axis 2's AXIOM (AXis Object Model).
Concrete message implementations are created by a `WebServiceMessageFactory`. This factory can create an empty message or read a message from an input stream. One concrete implementations of `WebServiceMessageFactory` is provided based on SAAJ, the SOAP with Attachments API for Java.

==== `SaajSoapMessageFactory`

Expand All @@ -72,7 +72,7 @@ The `SaajSoapMessageFactory` uses the SOAP with Attachments API for Java (SAAJ)
| SUN Glassfish 1
| 1.3

2+|^1^Weblogic 9 has a known bug in the SAAJ 1.2 implementation: it implements all the 1.2 interfaces but throws an `UnsupportedOperationException` when called. Spring Web Services has a workaround: It uses SAAJ 1.1 when operating on WebLogic 9.
2+|^1^Weblogic 9 has a known bug in the SAAJ 1.2 implementation: it implements all the 1.2 interfaces but throws an `UnsupportedOperationException` when called. Spring-WS has a workaround: It uses SAAJ 1.1 when operating on WebLogic 9.
|===

Additionally, Java SE 6 includes SAAJ 1.3. You can wire up a `SaajSoapMessageFactory` as follows:
Expand All @@ -84,35 +84,12 @@ Additionally, Java SE 6 includes SAAJ 1.3. You can wire up a `SaajSoapMessageFac
----
====

NOTE: SAAJ is based on DOM, the Document Object Model. This means that all SOAP messages are stored in memory. For larger SOAP messages, this may not be performant. In that case, the `AxiomSoapMessageFactory` might be more applicable.

==== `AxiomSoapMessageFactory`

The `AxiomSoapMessageFactory` uses the AXis 2 Object Model (AXIOM) to create `SoapMessage` implementations. AXIOM is based on StAX, the Streaming API for XML. StAX provides a pull-based mechanism for reading XML messages, which can be more efficient for larger messages.

To increase reading performance on the `AxiomSoapMessageFactory`, you can set the `payloadCaching` property to false (default is true). Doing so causesthe contents of the SOAP body to be read directly from the socket stream. When this setting is enabled, the payload can be read only once. This means that you have to make sure that any pre-processing (logging or other work) of the message does not consume it.

You can use the `AxiomSoapMessageFactory` as follows:

====
[source,xml]
----
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
</bean>
----
====

In addition to payload caching, AXIOM supports full streaming messages, as defined in the `StreamingWebServiceMessage`. This means that you can directly set the payload on the response message, rather than writing it to a DOM tree or buffer.

Full streaming for AXIOM is used when a handler method returns a JAXB2-supported object. It automatically sets this marshalled object into the response message and writes it out to the outgoing socket stream when the response is going out.

For more information about full streaming, see the class-level Javadoc for `StreamingWebServiceMessage` and `StreamingPayload`.
NOTE: SAAJ is based on DOM, the Document Object Model. This means that all SOAP messages are stored in memory. For larger SOAP messages, this may not be performant.

[[soap_11_or_12]]
==== SOAP 1.1 or 1.2

Both the `SaajSoapMessageFactory` and the `AxiomSoapMessageFactory` have a `soapVersion` property, where you can inject a `SoapVersion` constant. By default, the version is 1.1, but you can set it to 1.2:
`SaajSoapMessageFactory` has a `soapVersion` property, where you can inject a `SoapVersion` constant. By default, the version is 1.1, but you can set it to 1.2:

====
[source,xml]
Expand Down Expand Up @@ -149,14 +126,14 @@ One important thing to note with SOAP version numbers (or WS-* specification ver

Typically, messages come in pairs: a request and a response. A request is created on the client-side, which is sent over some transport to the server-side, where a response is generated. This response gets sent back to the client, where it is read.

In Spring Web Services, such a conversation is contained in a `MessageContext`, which has properties to get request and response messages. On the client-side, the message context is created by the <<client-web-service-template,`WebServiceTemplate`>>. On the server-side, the message context is read from the transport-specific input stream. For example, in HTTP, it is read from the `HttpServletRequest`, and the response is written back to the `HttpServletResponse`.
In Spring-WS, such a conversation is contained in a `MessageContext`, which has properties to get request and response messages. On the client-side, the message context is created by the <<client-web-service-template,`WebServiceTemplate`>>. On the server-side, the message context is read from the transport-specific input stream. For example, in HTTP, it is read from the `HttpServletRequest`, and the response is written back to the `HttpServletResponse`.

[[transport-context]]
== `TransportContext`

One of the key properties of the SOAP protocol is that it tries to be transport-agnostic. This is why, for instance, Spring-WS does not support mapping messages to endpoints by HTTP request URL but rather by message content.

However, it is sometimes necessary to get access to the underlying transport, either on the client or the server side. For this, Spring Web Services has the `TransportContext`. The transport context allows access to the underlying `WebServiceConnection`, which typically is a `HttpServletConnection` on the server side or a `HttpUrlConnection` or `CommonsHttpConnection` on the client side. For example, you can obtain the IP address of the current request in a server-side endpoint or interceptor:
However, it is sometimes necessary to get access to the underlying transport, either on the client or the server side. For this, Spring-WS has the `TransportContext`. The transport context allows access to the underlying `WebServiceConnection`, which typically is a `HttpServletConnection` on the server side or a `HttpUrlConnection` or `CommonsHttpConnection` on the client side. For example, you can obtain the IP address of the current request in a server-side endpoint or interceptor:

====
[source,java]
Expand All @@ -176,7 +153,7 @@ One of the best ways to handle XML is to use XPath. Quoting <<effective-xml>>, i
[quote, Elliotte Rusty Harold]
XPath is a fourth generation declarative language that allows you to specify which nodes you want to process without specifying exactly how the processor is supposed to navigate to those nodes. XPath's data model is very well designed to support exactly what almost all developers want from XML. For instance, it merges all adjacent text including that in CDATA sections, allows values to be calculated that skip over comments and processing instructions` and include text from child and descendant elements, and requires all external entity references to be resolved. In practice, XPath expressions tend to be much more robust against unexpected but perhaps insignificant changes in the input document.

Spring Web Services has two ways to use XPath within your application: the faster `XPathExpression` or the more flexible `XPathTemplate`.
Spring-WS has two ways to use XPath within your application: the faster `XPathExpression` or the more flexible `XPathOperations`.

[[xpath-expression]]
=== `XPathExpression`
Expand Down Expand Up @@ -261,9 +238,9 @@ public class MyXPathClass {
Similar to mapping rows in Spring JDBC's `RowMapper`, each result node is mapped by using an anonymous inner class. In this case, we create a `Contact` object, which we use later on.

[[xpath-template]]
=== `XPathTemplate`
=== `XPathOperations`

The `XPathExpression` lets you evaluate only a single, pre-compiled expression. A more flexible, though slower, alternative is the `XpathTemplate`. This class follows the common template pattern used throughout Spring (`JdbcTemplate`, `JmsTemplate`, and others). The following listing shows an example:
The `XPathExpression` lets you evaluate only a single, pre-compiled expression. A more flexible, though slower, alternative is the `XPathOperations`. This class follows the common template pattern used throughout Spring (`JdbcTemplate`, `JmsTemplate`, and others). The following listing shows an example:

====
[source,java,subs="verbatim,quotes"]
Expand All @@ -286,28 +263,27 @@ public class MyXPathClass {
[[logging]]
== Message Logging and Tracing

When developing or debugging a web service, it can be quite useful to look at the content of a (SOAP) message when it arrives or before it is sent. Spring Web Services offer this functionality, through the standard Commons Logging interface.

WARNING: Make sure to use Commons Logging version 1.1 or higher. Earlier versions have class loading issues and do not integrate with the Log4J TRACE level.
When developing or debugging a web service, it can be quite useful to look at the content of a (SOAP) message when it arrives or before it is sent. Spring-WS offer this functionality, through the standard Commons Logging interface.

To log all server-side messages, set the `org.springframework.ws.server.MessageTracing` logger level to `DEBUG` or `TRACE`. On the `DEBUG` level, only the payload root element is logged. On the `TRACE` level, the entire message content is logged. If you want to log only sent messages, use the `org.springframework.ws.server.MessageTracing.sent` logger. Similarly, you can use `org.springframework.ws.server.MessageTracing.received` to log only received messages.

On the client-side, similar loggers exist: `org.springframework.ws.client.MessageTracing.sent` and `org.springframework.ws.client.MessageTracing.received`.

The following example of a `log4j.properties` configuration file logs the full content of sent messages on the client side and only the payload root element for client-side received messages. On the server-side, the payload root is logged for both sent and received messages:
The following example of a `log4j2.properties` configuration file logs the full content of sent messages on the client side and only the payload root element for client-side received messages. On the server-side, the payload root is logged for both sent and received messages:

====
[source]
----
log4j.rootCategory=INFO, stdout
log4j.logger.org.springframework.ws.client.MessageTracing.sent=TRACE
log4j.logger.org.springframework.ws.client.MessageTracing.received=DEBUG
appender.console.name=STDOUT
appender.console.type=Console
appender.console.layout.type=PatternLayout
appender.console.layout.pattern=%-5p [%c{3}] %m%n
log4j.logger.org.springframework.ws.server.MessageTracing=DEBUG
rootLogger=DEBUG,STDOUT
logger.org.springframework.ws.client.MessageTracing.sent=TRACE
logger.org.springframework.ws.client.MessageTracing.received=DEBUG
logger.org.springframework.ws.server.MessageTracing=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%p [%c{3}] %m%n
----
====

Expand Down
12 changes: 8 additions & 4 deletions spring-ws-docs/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
= Spring Web Services Reference Documentation
Arjen Poutsma, Rick Evans, Tareq Abed Rabbo, Greg Turnquist, Jay Bryant, Corneil du Plessis
Arjen Poutsma, Rick Evans, Tareq Abed Rabbo, Greg Turnquist, Jay Bryant, Corneil du Plessis, Stéphane Nicoll
:doctype: book
:revnumber: {gradle-project-version}
:revdate: {localdate}
:toc: left
:toclevels: 4
:source-highlighter: prettify
:sectnumlevels: 3

(C) 2005-2020 The original authors.
:docs-site: https://docs.spring.io
:spring-framework-docs-root: {docs-site}/spring-framework/docs
:spring-framework-api: {spring-framework-docs-root}/{spring-framework-version}/javadoc-api/org/springframework
:spring-framework-docs: https://docs.spring.io/spring-framework/reference
:spring-ws-docs-root: {docs-site}/spring-ws/docs
:spring-ws-api: {spring-ws-docs-root}/{spring-ws-version}/api/org/springframework/ws

NOTE: Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

Expand All @@ -21,7 +25,7 @@ include::preface.adoc[leveloffset=+1]
= I. Introduction
:sectnums:

This first part of the reference documentation <<what-is-spring-ws,is an overview>> of Spring Web Services and the underlying concepts. Spring-WS is then introduced, and <<why-contract-first,the concepts>> behind contract-first web service development are explained.
This first part of the reference documentation <<what-is-spring-ws,is an overview>> of Spring Web Services and the underlying concepts. Then, <<why-contract-first,the concepts>> behind contract-first web service development are explained. Finally, the third section provides <<tutorial,a tutorial>>.

include::what-is-spring-ws.adoc[leveloffset=+1]

Expand Down
2 changes: 1 addition & 1 deletion spring-ws-docs/src/docs/asciidoc/preface.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

In the current age of Service Oriented Architectures, more and more people use web services to connect previously unconnected systems. Initially, web services were considered to be just another way to do a Remote Procedure Call (RPC). Over time, however, people found out that there is a big difference between RPCs and web services. Especially when interoperability with other platforms is important, it is often better to send encapsulated XML documents that contain all the data necessary to process the request. Conceptually, XML-based web services are better compared to message queues than to remoting solutions. Overall, XML should be considered the platform-neutral representation of data, the _common language_ of SOA. When developing or using web services, the focus should be on this XML and not on Java.

Spring Web Services focuses on creating these document-driven web services. Spring Web Services facilitates contract-first SOAP service development, allowing for the creation of flexible web services by using one of the many ways to manipulate XML payloads. Spring-WS provides a powerful <<server,message dispatching framework>>, a <<security,WS-Security>> solution that integrates with your existing application security solution, and a <<client,Client-side API>> that follows the familiar Spring template pattern.
Spring-WS focuses on creating these document-driven web services. Spring-WS facilitates contract-first SOAP service development, allowing for the creation of flexible web services by using one of the many ways to manipulate XML payloads. Spring-WS provides a powerful <<server,message dispatching framework>>, a <<security,WS-Security>> solution that integrates with your existing application security solution, and a <<client,Client-side API>> that follows the familiar Spring template pattern.
Loading

0 comments on commit 10f4a3b

Please sign in to comment.