[SWS-130] Ref manual typos, grammar corrections, etc.

This commit is contained in:
Rick Evans
2007-05-28 13:08:11 +00:00
parent 71ce4da266
commit c8306f6932
5 changed files with 129 additions and 152 deletions

View File

@@ -11,12 +11,12 @@
</para>
<para>
The package <package>org.springframework.ws.client.core</package> provides the core functionality for using
the client-side access API. It contains template classes that simplifies the use of Web services, much like
the client-side access API. It contains template classes that simplify the use of Web services, much like
the <classname>JdbcTemplate</classname> does for JDBC. The design principle common to Spring template
classes is to provide helper methods to perform common operations and for more sophisticated usage, delegate
to user implemented callback interfaces. The Web service template
follows the same design. The classes offer various convenience methods for the sending and receiving of XML
messages, marshalling objects to XML before sending, and allows for multiple transports,
messages, marshalling objects to XML before sending, and allows for multiple transport options.
</para>
</section>
<section>
@@ -60,7 +60,7 @@
</section>
</section>
<section>
<title>Sending and receiving a<interfacename>WebServiceMessage</interfacename>
<title>Sending and receiving a <interfacename>WebServiceMessage</interfacename>
</title>
<para>
The <classname>WebServiceTemplate</classname> contains many convenience methods to send and receive
@@ -136,7 +136,7 @@ public class WebServiceClient {
<interfacename>WebServiceMessageCallback</interfacename>
</title>
<para>
To accommodate the setting of SOAP headers, and other settings on the message, the
To accommodate the setting of SOAP headers and other settings on the message, the
<interfacename>WebServiceMessageCallback</interfacename> interface gives you access to the message
after it has been created, but before it is sent. The example below demonstrates how to set the SOAP
Action header on a message that is created by marshalling an object.

View File

@@ -4,7 +4,7 @@
<chapter id="common">
<title>Shared components</title>
<para>
In this chapter, we will explore the the components which are shared between client- and server side
In this chapter, we will explore the the components which are shared between client- and server-side
Spring-WS development. These interfaces and classes represent the building blocks of Spring-WS, so
it is important to understand what they do, even if you do not use them directly.
</para>
@@ -13,14 +13,14 @@
<section id="web-service-message">
<title><interfacename>WebServiceMessage</interfacename></title>
<para>
One of the core interfaces within Spring Web Services is the
<interfacename>WebServiceMessage</interfacename>. 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 <interfacename>javax.xml.transform.Source</interfacename> or a
One of the core interfaces of Spring Web Services is the <interfacename>WebServiceMessage</interfacename>.
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
<interfacename>javax.xml.transform.Source</interfacename> or a
<interfacename>javax.xml.transform.Result</interfacename>. <interfacename>Source</interfacename> and
<interfacename>Result</interfacename> are tagging interfaces that represent an abstraction over XML
input and output. Concrete implementations wrap various XML representations, as indicated in the table
below.
input and output. Concrete implementations wrap various XML representations, as indicated in the
following table.
<informaltable>
<tgroup cols="2">
<thead>
@@ -74,7 +74,7 @@
<section id="soap-message">
<title><interfacename>SoapMessage</interfacename></title>
<para>
The <interfacename>SoapMessage</interfacename> is an extension of
The <interfacename>SoapMessage</interfacename> is a subclass of
<interfacename>WebServiceMessage</interfacename>. It contains SOAP-specific methods, such as getting
SOAP Headers, SOAP Faults, etc. Generally, your code should not be dependent on
<interfacename>SoapMessage</interfacename>, because the content of the SOAP Body can be obtained via
@@ -87,12 +87,10 @@
<section id="message-factories">
<title>Message Factories</title>
<para>
Concrete message implementation are created by a
<interfacename>WebServiceMessageFactory</interfacename>. This factory can create an empty message, or
read a message based on an input stream.
There are two concrete implementations of <interfacename>WebServiceMessageFactory</interfacename>.
One is based on SAAJ, the SOAP with Attachments API for Java, the other based on Axis 2's AXIOM, the
AXis Object Model.
Concrete message implementations are created by a <interfacename>WebServiceMessageFactory</interfacename>.
This factory can create an empty message, or read a message based on an input stream. There are two
concrete implementations of <interfacename>WebServiceMessageFactory</interfacename>; one is based on
SAAJ, the SOAP with Attachments API for Java, the other based on Axis 2's AXIOM, the AXis Object Model.
</para>
<section>
<title><classname>SaajSoapMessageFactory</classname></title>
@@ -101,13 +99,12 @@
create <classname>SoapMessage</classname> implementations. SAAJ is part of J2EE 1.4, so it should be
supported under most modern application servers. You wire up a
<classname>SaajSoapMessageFactory</classname> like so:
<programlisting><![CDATA[
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />]]></programlisting>
<programlisting><![CDATA[<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory" />]]></programlisting>
</para>
<note>
<para>
SAAJ is based on DOM, the Document Object Model. This means that all SOAP messages are
stored in memory as a whole. For larger SOAP messages, this may not be very performant.
stored <emphasis>in memory</emphasis>. For larger SOAP messages, this may not be very performant.
In that case, the <classname>AxiomSoapMessageFactory</classname> might be more applicable.
</para>
</note>
@@ -260,7 +257,7 @@ public class MyXPathClass {
<section id="xpath-template">
<title><classname>XPathTemplate</classname></title>
<para>
The <interfacename>XPathExpression</interfacename> only allows you to evaluate a single, pre-compiled
The <interfacename>XPathExpression</interfacename> allows you to evaluate only a single, pre-compiled
expression. A more flexible, though slower, alternative is the <classname>XpathTemplate</classname>.
This class follows the common template pattern used throughout Spring (JdbcTemplate, JmsTemplate, etc.).
Here is an example:
@@ -277,10 +274,6 @@ public class MyXPathClass {
}
}]]></programlisting>
<para>
Of course, the template could have been injected with a
constructor argument or a setter.
</para>
</section>
</section>
</chapter>

View File

@@ -165,9 +165,8 @@ public interface Unmarshaller {
<para>
Even though there are two separate marshalling interfaces (<interfacename>Marshaller</interfacename>
and <interfacename>Unmarshaller</interfacename>), all implementations found in Spring-WS implement both in
one class. This means that you can wire up one marshaller class and refer to it as marshaller and
unmarshaller in your <filename>applicationContext.xml</filename>
.
one class. This means that you can wire up one marshaller class and refer to it both as a marshaller and an
unmarshaller in your <filename>applicationContext.xml</filename>.
</para>
<section>
<title>XmlMappingException</title>
@@ -317,7 +316,7 @@ public class Application {
implementation of JAXB. Alternatively, JAXB2 offers a way to generate a schema from annotated Java classes.
</para>
<para>
Spring supports both the JAXB 1.0 as the JAXB 2.0 API as XML marshalling strategy, following the
Spring supports both the JAXB 1.0 and the JAXB 2.0 API as XML marshalling strategies, following the
<interfacename>Marshaller</interfacename> and <interfacename>Unmarshaller</interfacename>
interfaces described in <xref linkend="oxm-marshaller-unmarshaller"/>. The corresponding integration
classes reside in the <package>org.springframework.oxm.jaxb</package> package.
@@ -330,7 +329,7 @@ public class Application {
requires a context path to operate, which you can set using the <property>contextPath</property>
property. The context path is a list of colon (:) separated Java package names that contain schema
derived classes. The marshaller has an additional <property>validating</property> property which
defines whether to validate invoming XML.
defines whether to validate incoming XML.
</para>
<para>
The next sample bean configuration shows how to configure a <classname>JaxbMarshaller</classname>
@@ -423,26 +422,23 @@ public class Application {
<section id="oxm-xmlbeans">
<title>XMLBeans</title>
<para>
XMLBeans is an XML binding tool that has full XML Schema support, and offers full XML Infoset fidelity. It
takes a different approach that most other O/X mapping frameworks, in that all classes that are
generated from an XML Schema are all derived from <interfacename>XmlObject</interfacename>, and contain
XML binding information in them.
XMLBeans is an XML binding tool that has full XML Schema support, and offers full XML Infoset
fidelity. It takes a different approach to that of most other O/X mapping frameworks, in that
all classes that are generated from an XML Schema are all derived from
<interfacename>XmlObject</interfacename>, and contain XML binding information in them.
</para>
<para>
For more information on XMLBeans, refer to the <ulink url="http://xmlbeans.apache.org/">
<citetitle>XMLBeans web site </citetitle></ulink>. The Spring-WS integration classes reside in the
<package>org.springframework.oxm.xmlbeans</package> package.
<citetitle>XMLBeans web site </citetitle></ulink>. The Spring-WS integration classes reside
in the <package>org.springframework.oxm.xmlbeans</package> package.
</para>
<section>
<title>XmlBeansMarshaller</title>
<para>
The
<classname>XmlBeansMarshaller</classname>
implements both the
<interfacename>Marshaller</interfacename>
and
<interfacename>Unmarshaller</interfacename>
interface. It can be wired up as follows:
The <classname>XmlBeansMarshaller</classname>
implements both the <interfacename>Marshaller</interfacename>
and <interfacename>Unmarshaller</interfacename>
interfaces. It can be configured as follows:
</para>
<programlisting><![CDATA[
<beans>
@@ -453,13 +449,9 @@ public class Application {
</beans>]]></programlisting>
<note>
<para>
Note that the
<classname>XmlBeansMarshaller</classname>
can only marshal objects of type
<interfacename>XmlObject</interfacename>
, and not every
<classname>java.lang.Object</classname>
.
Note that the <classname>XmlBeansMarshaller</classname>
can only marshal objects of type <interfacename>XmlObject</interfacename>,
and not every <classname>java.lang.Object</classname>.
</para>
</note>
</section>
@@ -470,7 +462,7 @@ public class Application {
<section id="oxm-jibx">
<title>JiBX</title>
<para>
The JiBX framework offers a solution similar to JDO does for ORM: a binding definition defines the
The JiBX framework offers a solution similar to that which JDO provides for ORM: a binding definition defines the
rules for how your Java objects are converted to or from XML. After preparing the binding and compiling the
classes, a JiBX binding compiler enhances the class files, and adds code to handle converting instances of
the classes from or to XML.

View File

@@ -7,16 +7,15 @@
<section id="security-introduction">
<title>Introduction</title>
<para>
In this chapter, we will show you how to add WS-Security aspects to your Web services. We will focus on the
This chapter explains how to add WS-Security aspects to your Web services. We will focus on the
three different areas of WS-Security, namely:
</para>
<formalpara>
<title>Authentication</title>
<para>
This is the process of determining whether a
<emphasis>principal</emphasis>
is who they claim to be. In this context, a "principal" generally means a user, device or some other
system which can perform an action in your application.
This is the process of determining whether a <emphasis>principal</emphasis> is who they claim to be.
In this context, a "principal" generally means a user, device or some other system which can perform
an action in your application.
</para>
</formalpara>
<formalpara>
@@ -47,8 +46,8 @@
<note>
<para>
Note that WS-Security (especially encryption and signing) requires substantial amounts of memory, and
will also decrease performance. If performance is important to you, you might want to consider using not
using WS-Security.
will also decrease performance. If performance is important to you, you might want to consider not using
WS-Security.
</para>
</note>
</section>
@@ -132,12 +131,12 @@
</section>
<section id="keystore">
<title>Key stores</title>
<title>Keystores</title>
<para>
For most cryptographic operations, you will use standard <classname>java.security.KeyStore</classname>
objects. This includes certificate verification, message signing, signature verification, encryption, but
objects. This includes certificate verification, message signing, signature verification, and encryption, but
excludes username and time-stamp verification. This section aims to give you some background knowledge on
key stores, and the Java tools that you can use to store keys and certificates in a key store file. This
keystores, and the Java tools that you can use to store keys and certificates in a keystore file. This
information is mostly not related to Spring-WS, but to the general cryptographic features of Java.
</para>
<para>
@@ -171,31 +170,30 @@
<section>
<title>KeyTool</title>
<para>
Supplied with your Java Virtual Machine is the <command>keytool</command>, a key and certificate
management utility. You can use this tool to create new key stores, add new private keys and
Supplied with your Java Virtual Machine is the <command>keytool</command> program, a key and certificate
management utility. You can use this tool to create new keystores, add new private keys and
certificates to them, etc. It is beyond the scope of this document to provide a full reference of
the <command>keytool</command> command, but you can find a reference <ulink
url="http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/keytool.html">
<citetitle>here</citetitle></ulink>, or by giving the command <prompt>keytool -help</prompt> on
the command line.
the <command>keytool</command> command, but you can find a reference
<ulink url="http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/keytool.html"><citetitle>here</citetitle></ulink>,
or by giving the command <prompt>keytool -help</prompt> on the command line.
</para>
</section>
<section>
<title>KeyStoreFactoryBean</title>
<para>
To easily load a key store using Spring configuration, you can use the
To easily load a keystore using Spring configuration, you can use the
<classname>KeyStoreFactoryBean</classname>. It has a resource location property, which you can set to
point to the path of the key store to load. A password may be given to check the integrity of the
key store data. If a password is not given, integrity checking is not performed.
point to the path of the keystore to load. A password may be given to check the integrity of the
keystore data. If a password is not given, integrity checking is not performed.
</para>
<programlisting><![CDATA[
<programlisting><![CDATA[
<bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
<property name="password" value="password"/>
<property name="location" value="classpath:org/springframework/ws/soap/security/xwss/test-keystore.jks"/>
</bean>]]></programlisting>
<caution>
<para>
If you don't specify the location property, a new, empty key store will be created, which is most
If you don't specify the location property, a new, empty keystore will be created, which is most
likely not what you want.
</para>
</caution>
@@ -203,8 +201,8 @@
<section id="security-key-store-callback-handler">
<title>KeyStoreCallbackHandler</title>
<para>
To use the key stores within a <classname>XwsSecurityInterceptor</classname>, you will need to define a
<classname>KeyStoreCallbackHandler</classname>. This callback has three properties with type key store:
To use the keystores within a <classname>XwsSecurityInterceptor</classname>, you will need to define a
<classname>KeyStoreCallbackHandler</classname>. This callback has three properties with type keystore:
(<methodname>keyStore</methodname>, <methodname>trustStore</methodname>, and
<methodname>symmetricStore</methodname>). The exact stores used by the handler depend on the
cryptographic operations that are to be performed by this handler. For private key operation, the
@@ -216,7 +214,7 @@
<thead>
<row>
<entry>Cryptographic operation</entry>
<entry>Key store used</entry>
<entry>Keystore used</entry>
</row>
</thead>
<tbody>
@@ -349,7 +347,7 @@
<para>
The simplest password validation handler is the
<classname>SimplePasswordValidationCallbackHandler</classname>. This handler validates passwords
against a in-memory <classname>Properties</classname> object, which you can specify using the
against an in-memory <classname>Properties</classname> object, which you can specify using the
<methodname>users</methodname> property, like so:
</para>
<programlisting><![CDATA[
@@ -412,7 +410,7 @@
<citetitle>good tutorial</citetitle></ulink> available.
</para>
<para>
The <classname>JaasPlainTextPasswordValidationCallbackHandler</classname> only requires a
The <classname>JaasPlainTextPasswordValidationCallbackHandler</classname> requires only a
<methodname>loginContextName</methodname> to operate. It creates a new JAAS
<classname>LoginContext</classname> using this name, and handles the standard JAAS
<classname>NameCallback</classname> and <classname>PasswordCallback</classname> using the username
@@ -440,12 +438,12 @@
<section>
<title>Digest Username Authentication</title>
<para>
When using password digests, the SOAP message also contain a <literal>UsernameToken</literal> element,
When using password digests, the SOAP message also contains a <literal>UsernameToken</literal> element,
which itself contains a <literal>Username</literal> element and a <literal>Password</literal> element.
The difference is that the password is not sent as plain text, but as a <emphasis>digest</emphasis>.The
The difference is that the password is not sent as plain text, but as a <emphasis>digest</emphasis>. The
recipient compares this digest to the digest he calculated from the known password of the user, and if
they are the same, the user is authenticated. It can be compared to the Digest
Authentication provided by HTTP servers.
they are the same, the user is authenticated. It can be compared to the Digest Authentication provided
by HTTP servers.
</para>
<para>
To require that every incoming message contains a <literal>UsernameToken</literal> element with a
@@ -483,7 +481,7 @@
The <classname>AcegiPlainTextPasswordValidationCallbackHandler</classname> requires an Acegi
<classname>UserDetailService</classname> to operate. It uses this service to retrieve the password
of the user specified in the token. The digest of the password contained in this details object is
then compared with the digest in the message. If they are equal, the user has succesfully
then compared with the digest in the message. If they are equal, the user has successfully
authenticated, and a <classname>UsernamePasswordAuthenticationToken</classname> is stored in the
<classname>SecurityContextHolder</classname>. You can set the service using the
<methodname>userDetailsService</methodname>. Additionally, you can set a
@@ -512,12 +510,11 @@
<para>
To make sure that all incoming SOAP messages carry a <literal>BinarySecurityToken</literal>, the
security policy file should contain a <literal>RequireSignature</literal> element. This element can
carry further other elements, which will be covered in <xref linkend="security-verifying-signatures"/>.
You can find a reference of possible child elements <ulink
url="http://java.sun.com/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565769">
<citetitle>here</citetitle></ulink>.
further carry other elements, which will be covered in <xref linkend="security-verifying-signatures"/>.
You can find a reference of possible child elements
<ulink url="http://java.sun.com/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565769"><citetitle>here</citetitle></ulink>.
</para>
<programlisting><![CDATA[
<programlisting><![CDATA[
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
...
<xwss:RequireSignature requireTimestamp="false">
@@ -532,7 +529,7 @@
<note>
<para>
In most cases, certificate <emphasis>authentication</emphasis> should be preceded by certificate
<emphasis>validation</emphasis>, since you only want authenticate against valid certificates.
<emphasis>validation</emphasis>, since you only want to authenticate against valid certificates.
Invalid certificates such as certificates for which the expiration date has passed, or which are not
in your store of trusted certificates, should be ignored.
</para>
@@ -562,7 +559,7 @@
<section>
<title>KeyStoreCallbackHandler</title>
<para>
The <classname>KeyStoreCallbackHandler</classname> uses a standard Java key store to validate
The <classname>KeyStoreCallbackHandler</classname> uses a standard Java keystore to validate
certificates. This certificate validation process consists of the following steps:
<orderedlist>
<listitem>
@@ -573,7 +570,7 @@
</listitem>
<listitem>
<para>
If the certificate is not in the private key store, the handler will check whether the
If the certificate is not in the private keystore, the handler will check whether the
the current date and time are within the validity period given in the certificate.
If they are not, the certificate is invalid; if it is, it will continue with the final
step.
@@ -583,16 +580,16 @@
<para>
Finally, a <emphasis>certification path</emphasis> for the certificate is created. This
basically means that the handler will determine whether the certificate has been issued
by any of the certificate authorities in the <methodname>trustStore</methodname>. If it
a certification path can be built succesfully, the certificate is valid. Otherwise, it
is not.
by any of the certificate authorities in the <methodname>trustStore</methodname>. If
a certification path can be built successfully, the certificate is valid. Otherwise,
the certificate is not.
</para>
</listitem>
</orderedlist>
</para>
<para>
To use the <classname>KeyStoreCallbackHandler</classname> for certificate validation purposes, you
will most likely only set the <methodname>trustStore</methodname> property:
will most likely set only the <methodname>trustStore</methodname> property:
<programlisting><![CDATA[
<beans>
<bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
@@ -612,10 +609,10 @@
<title>AcegiCertificateValidationCallbackHandler</title>
<para>
The <classname>AcegiCertificateValidationCallbackHandler</classname> requires an Acegi
<classname>AuthenticationManager</classname> to operate. It uses this manager authenticate against a
<classname>AuthenticationManager</classname> to operate. It uses this manager to authenticate against a
<classname>X509AuthenticationToken</classname> that it creates. The configured authentication
manager is expected to supply a provider which can handle this token (usually an instance of
<classname>X509AuthenticationProvider</classname>). If authentication is succesfull, the token is
<classname>X509AuthenticationProvider</classname>). If authentication is succesful, the token is
stored in the <classname>SecurityContextHolder</classname>. You can set the authentication manager
using the <methodname>authenticationManager</methodname> property:
</para>
@@ -800,7 +797,7 @@
To decrypt incoming SOAP messages, the security policy file should contain a
<literal>RequireEncryption</literal> element. This element can further carry a
<literal>EncryptionTarget</literal> element which indicates which part of the message should be
encrypted, a <literal>SymmetricKey</literal> to indicate that a shared secret instead of the regular
encrypted, and a <literal>SymmetricKey</literal> to indicate that a shared secret instead of the regular
private key should be used to decrypt the message. You can read a description of the other elements
<ulink url="http://java.sun.com/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565951">
<citetitle>here</citetitle></ulink>.
@@ -846,7 +843,7 @@
<para>
To encrypt outgoing SOAP messages, the security policy file should contain a <literal>Encrypt</literal>
element. This element can further carry a <literal>EncryptionTarget</literal> element which indicates
which part of the message should be encrypted, a <literal>SymmetricKey</literal> to indicate that a
which part of the message should be encrypted, and a <literal>SymmetricKey</literal> to indicate that a
shared secret instead of the regular private key should be used to decrypt the message. You can read a
description of the other elements <ulink
url="http://java.sun.com/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565951">

View File

@@ -10,7 +10,7 @@
<classname>MessageDispatcher</classname> that dispatches incoming
messages to endpoints, with configurable endpoint mappings, response
generation, and endpoint interception.
The simplest endpoint is a <interfacename>PayloadEndpoint</interfacename>, just offering a
The simplest endpoint is a <interfacename>PayloadEndpoint</interfacename>, which just offers the
<literal>Source invoke(Source request)</literal> method. You are of course free to
implement this interface directly, but you will probably prefer to extend one of
the included abstract implementations such as
@@ -86,7 +86,7 @@
<para>
Exceptions that are thrown during handling of the request get picked up by any of the endpoint exception
resolvers that are declared in the application context. Using these exception resolvers allows you to define
custom behaviors in case such exceptions get thrown, such as return a SOAP Fault.
custom behaviors (such as returning a SOAP Fault) in case such exceptions get thrown.
</para>
<para>
The <classname>MessageDispatcher</classname> has several properties, for setting endpoint adapters,
@@ -184,8 +184,8 @@
<para>
Alternatively, there is the <interfacename>MessageEndpoint</interfacename>, which operates on a
whole <link linkend="message-context"><interfacename>MessageContext</interfacename></link> rather than just
the payload. Typically, your code should only not be dependent on messages, because the payload should
contain the interesting information. Only when it is necessary to perform actions on the mesage as a whole,
the payload. Typically, your code should not be dependent on messages, because the payload should
contain the information of interest. Only when it is necessary to perform actions on the message as a whole,
such as adding a SOAP header, get an attachment, and so forth, should you need to implement
<interfacename>MessageEndpoint</interfacename>, though these actions are usually performed in a
<link linkend="server-endpoint-interceptor">endpoint interceptor</link>.
@@ -195,11 +195,11 @@
<para>
One of the most basic ways to handle the incoming XML payload is by using a DOM (Document Object Model)
API. By extending from <classname>AbstractDomPayloadEndpoint</classname>, you can use the
<package>org.w3c.dom.Element</package> and related classes to handle the request, and create the
<package>org.w3c.dom.Element</package> and related classes to handle the request and create the
response. When using the <classname>AbstractDomPayloadEndpoint</classname> as the baseclass for your
endpoints you only have to override the <methodname>invokeInternal(Element, Document)</methodname>
method, implement your logic, and return an <interfacename>Element</interfacename> if you want a
response. Here is a short example consisting of a class and a declaration in the application context.
method, implement your logic, and return an <interfacename>Element</interfacename> if a response is
necessary. Here is a short example consisting of a class and a declaration in the application context.
</para>
<programlisting><![CDATA[package samples;
@@ -226,7 +226,7 @@ public class SampleEndpoint extends AbstractDomPayloadEndpoint {
<constructor-arg value="Hello World!"/>
</bean>]]></programlisting>
<para>
The above class and the declaration in the application context is all you need besides setting up an
The above class and the declaration in the application context are all you need besides setting up an
endpoint mapping (see the section entitled <xref linkend="server-endpoint-mapping" />) to get this very
simple endpoint working. The SOAP message handled by this endpoint will look something like:
</para>
@@ -245,7 +245,7 @@ public class SampleEndpoint extends AbstractDomPayloadEndpoint {
Hello
</request>]]></programlisting>
<para>
The SOAP reponse looks like:
The SOAP response looks like:
</para>
<programlisting><![CDATA[<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>]]><emphasis role="bold"><![CDATA[
@@ -330,8 +330,8 @@ public class MarshallingOrderEndpoint extends AbstractMarshallingPayloadEndpoint
it is a normal transactional service, probably using DAOs to obtain data from a database.
In the <methodname>invokeInternal</methodname> method, we cast the request object to an
<classname>OrderRequest</classname> 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, which we
returned. The returned object is marshalled into XML, and used as the payload of the response message.
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:
</para>
<programlisting id="server-order-request"><![CDATA[<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
@@ -366,10 +366,10 @@ public class MarshallingOrderEndpoint extends AbstractMarshallingPayloadEndpoint
<section id="server-at-endpoint">
<title><interfacename>@Endpoint</interfacename></title>
<para>
The previous two programming models were based on inheritance, and handled individual XML mesages.
Spring Web Services offer another endpoint with which you aggregate multiple handling into one
controller, thus grouping functionality together. This model is based on annotations, so you can only
use it under Java 5 and higher. Here is an example that uses the same marshalled objects as above:
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:
</para>
<programlisting><![CDATA[package samples;
@@ -466,7 +466,7 @@ public class AnnotationOrderEndpoint {
@PayloadRoot(localPart = "orderRequest", namespace = "http://samples")
public Source getOrder(]]><emphasis role="bold"><![CDATA[@XPathParam("/s:orderRequest/@id") double orderId]]></emphasis><![CDATA[) {
Order order = orderService.getOrder((int) orderId);
// create Source from order and return it
]]><lineannotation>// create Source from order and return it</lineannotation><![CDATA[
}
}]]></programlisting>
@@ -517,9 +517,9 @@ public class AnnotationOrderEndpoint {
<interfacename>EndpointMapping</interfacename>.
</para>
<para>
A <interfacename>EndpointMapping</interfacename> delivers a <classname>EndpointInvocationChain</classname>,
An <interfacename>EndpointMapping</interfacename> delivers a <classname>EndpointInvocationChain</classname>,
which contains the endpoint that matches the incoming request, and may also contain a list of endpoint
interceptors that are applied to the request and response. When a request comes in, the
interceptors that will be applied to the request and response. When a request comes in, the
<classname>MessageDispatcher</classname> will hand it over to the endpoint mapping to let it inspect the
request and come up with an appropriate <classname>EndpointInvocationChain</classname>. Then
the <classname>MessageDispatcher</classname> will invoke the endpoint and any interceptors in the chain.
@@ -528,7 +528,8 @@ public class AnnotationOrderEndpoint {
The concept of configurable endpoint mappings that can optionally contain interceptors (which can manipulate
the request or the response, or both) is extremely powerful. A lot of supporting functionality can be built
into custom <interfacename>EndpointMapping</interfacename>s. For example, there could be a custom endpoint mapping that
chooses an endpoint not only based on the contents of a message, but also a specific SOAP headers.
chooses an endpoint not only based on the contents of a message, but also on a specific SOAP header(or
indeed multiple SOAP headers).
</para>
<para>
Most endpoint mappings inherit from the <classname>AbstractEndpointMapping</classname>, which offers an
@@ -581,7 +582,7 @@ public class AnnotationOrderEndpoint {
<classname>PayloadRootQNameEndpointMapping</classname>, you can use the <literal>SOAPAction</literal>
HTTP header to route messages. Every client sends this header when making a SOAP request, and the
header value used for a request is defined in the WSDL. By making the <literal>SOAPAction</literal>
unique per operation, you can use it a a discriminator. Here is an example:
unique per operation, you can use it as a discriminator. Here is an example:
</para>
<programlisting><![CDATA[<beans>
<bean id="endpointMapping" class="org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping">
@@ -602,10 +603,10 @@ public class AnnotationOrderEndpoint {
</bean>
</beans>]]></programlisting>
<para>
The mapping above routes requests which have the a <literal>SOAPAction</literal> of
The mapping above routes requests which have a <literal>SOAPAction</literal> of
<uri>http://samples/RequestOrder</uri> to the <literal>'getOrderEndpoint'</literal>. Requests with
<uri>http://samples/CreateOrder</uri> will be routed to the <literal>'createController'</literal>.
Note that using SOAP Action headers is SOAP-specific, so it cannot be used when using Plain Old XML.
Note that using SOAP Action headers is SOAP-specific, so it cannot be used with Plain Old XML messages.
</para>
</section>
<section id="server-method-endpoint-mapping">
@@ -639,15 +640,15 @@ public class AnnotationOrderEndpoint {
<section id="server-endpoint-interceptor">
<title>Intecepting requests - the <interfacename>EndpointInterceptor</interfacename> interface</title>
<para>
The endpoint mapping mechanism has the notion of endpoint interceptors, that can be extremely useful
The endpoint mapping mechanism has the notion of endpoint interceptors. These can be extremely useful
when you want to apply specific functionality to certain requests, for example, dealing with
security-related SOAP headers, or logging the request and response message.
security-related SOAP headers, or the logging of request and response message.
</para>
<para>
Interceptors located in the endpoint mapping must implement
<interfacename>EndpointInterceptor</interfacename> from the
Interceptors located in the endpoint mapping must implement the
<interfacename>EndpointInterceptor</interfacename> interface from the
<package>org.springframework.ws.server</package> package. This interface defines three methods, one that
can be used for handling the request message has been determined <emphasis>before</emphasis> the actual
can be used for handling the request message <emphasis>before</emphasis> the actual
endpoint will be executed, one that can be used for handling a normal response message, and one that
can be used for handling fault messages, both of which will be called <emphasis>after</emphasis> the
endpoint is executed. These three methods should provide enough flexibility to do all kinds of
@@ -659,7 +660,7 @@ public class AnnotationOrderEndpoint {
returns <literal>true</literal>, the endpoint execution chain will continue, when it returns
<literal>false</literal>, the <classname>MessageDispatcher</classname> interprets this to mean that
the interceptor itself
has taken care of things and does not continue executing the other interceptors and the actual endoint
has taken care of things and does not continue executing the other interceptors and the actual endpoint
in the invocation chain. The <methodname>handleResponse(..)</methodname> and
<methodname>handleFault(..)</methodname> methods also have a boolean return value. When these methods
return <literal>false</literal>, the response will not be sent back to the client.
@@ -676,8 +677,8 @@ public class AnnotationOrderEndpoint {
When developing a Web service, it can be useful to log the incoming and outgoing XML messages to
the log. Spring Web Services facilitates this with the
<classname>PayloadLoggingInterceptor</classname> and the
<classname>SoapEnvelopeLoggingInterceptor</classname>. The former just logs the payload of the
message to the Commons Logging Log; the latter logs the entire SOAP Envelope, including SOAP
<classname>SoapEnvelopeLoggingInterceptor</classname>. The former logs just the payload of the
message to the Commons Logging Log; the latter logs the entire SOAP envelope, including SOAP
headers. This example shows you how to define them in an endpoint mapping:
</para>
<programlisting><![CDATA[<beans>
@@ -756,7 +757,7 @@ public class AnnotationOrderEndpoint {
response messages using <filename>/WEB-INF/oldResponses.xslt</filename>. Note that, since
endpoint interceptors are registered at the endpoint mapping level, you can simply create a
endpoint mapping that applies to the "old style" messages, and add the interceptor to that mapping.
Hence, the transformation will only apply to these "old style" message.
Hence, the transformation will apply only to these "old style" message.
</para>
</section>
</section>
@@ -769,23 +770,21 @@ public class AnnotationOrderEndpoint {
Endpoint exception resolvers somewhat resemble the exception mappings that can be
defined in the web application descriptor <filename>web.xml</filename>.
However, they provide a more flexible way to handle exceptions. They provide information about what
endpoint was invoked when the exception was thrown.
Furthermore, a programmatic way of handling exceptions gives you many more options for how to respond
appropriately.
Finally, rather than expose the innards of your application by giving an exception and stack trace, you
can handle the exception any way you want, for example return a SOAP fault with a specific fault code and string.
endpoint was invoked when the exception was thrown. Furthermore, a programmatic way of handling exceptions
gives you many more options for how to respond appropriately. Rather than expose the innards of your
application by giving an exception and stack trace, you can handle the exception any way you want, for
example by returning a SOAP fault with a specific fault code and string.
</para>
<para>
Endpoint exception resolvers are automatically picked up by the <classname>MessageDispatcher</classname>, so
you don't have to configure them explicitly.
Endpoint exception resolvers are automatically picked up by the <classname>MessageDispatcher</classname>,
so no explicit configuration is necessary.
</para>
<para>
Besides implementing the <classname>EndpointExceptionResolver</classname> interface, which is only a
matter of implementing the <methodname>resolveException(MessageContext, endpoint, Exception)</methodname>
method, you may also use one of the default implementations.
The simplest implementation is the <classname>SimpleSoapExceptionResolver</classname>, which simply
always creates a SOAP 1.1 Server or SOAP 1.2 Receiver Fault, and uses the exception message as the fault
string.
The simplest implementation is the <classname>SimpleSoapExceptionResolver</classname>, which just
creates a SOAP 1.1 Server or SOAP 1.2 Receiver Fault, and uses the exception message as the fault string.
</para>
<para>
A more sophisticated implementation is the <classname>SoapFaultMappingExceptionResolver</classname>.
@@ -808,11 +807,10 @@ public class AnnotationOrderEndpoint {
</beans>]]></programlisting>
<para>
The key values and default endpoint use the format <literal>faultCode,faultString,locale</literal>, where
only the fault code is required.
If the fault string is not set, it will default to the exception message.
If the language is not set, it will default to English.
The configuration above will map exceptions of type <classname>ValidationFailureException</classname>
to a sender side SOAP Fault with a fault string "Invalid request":
only the fault code is required. If the fault string is not set, it will default to the exception message.
If the language is not set, it will default to English. The above configuration will map exceptions of
type <classname>ValidationFailureException</classname> to a client-side SOAP Fault with a fault string
<literal>"Invalid request"</literal>, as can be seen in the following response:
</para>
<programlisting><![CDATA[<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>]]><emphasis role="bold"><![CDATA[
@@ -823,11 +821,9 @@ public class AnnotationOrderEndpoint {
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>]]></programlisting>
<para>
If any other exception occurs, it will return the default fault: a server side fault with the exception
If any other exception occurs, it will return the default fault: a server-side fault with the exception
message as fault string.
</para>
<para>
Finally, it is possible to annotate exception classes with the <interfacename>@SoapFault</interfacename>
Finally, it is also possible to annotate exception classes with the <interfacename>@SoapFault</interfacename>
annotation, to indicate the SOAP Fault that should be returned whenever that exception is thrown.
The elements of the annotation include a fault code enumeration, fault string or reason, and language. Here
is an example exception:
@@ -845,9 +841,8 @@ public class MyBusinessException extends Exception {
}
}]]></programlisting>
<para>
Whever the <classname>MyBusinessException</classname> is thrown with the constructor string
<literal>Oops!</literal> during endpoint invocation, it will result in
the following response:
Whenever the <classname>MyBusinessException</classname> is thrown with the constructor string
<literal>"Oops!"</literal> during endpoint invocation, it will result in the following response:
</para>
<programlisting><![CDATA[<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>