Added echo sample

This commit is contained in:
Arjen Poutsma
2013-11-08 12:02:45 +01:00
parent 94576a6ab2
commit edbba3dfe0
22 changed files with 649 additions and 2 deletions

2
.gitignore vendored
View File

@@ -10,4 +10,6 @@ atlassian-ide-plugin*.xml
/build
/*/build
/*/*/build
/*/*/*/build
.gradle

View File

@@ -1,2 +1,47 @@
spring-ws-samples
=================
# Spring Web Services Samples
[Spring Web Services] is a product of the Spring community focused on creating
document-driven, contract-first Web services. This repository contains sample
projects illustrating usage of Spring Web Services.
## Sample Applications
The following sample applications demonstrate the capabilities of [Spring Web
Services]. See the README within each sample project for more information and
additional instructions.
- [echo](./echo) - a simple sample that shows a bare-bones Echo service
- [tutorial](./tutorial) - contains the code from the Spring-WS tutorial
## Running the Server
Most of the sample apps can be built and run using the following commands from
within the sample's folder.
```sh
$ ./gradlew tomcatRun
```
Or alternatively, run the following to create war archive which can be deployed
in any Web Container.
```sh
$ ./gradlew war
```
## Running the Client(s)
Most of the sample apps have a separate ``client`` directory containing clients
that connect to the server. You can run these clients by using the following
command from within each of client subdirectories:
```sh
$ gradle runClient
```
## License
[Spring Web Services] is released under version 2.0 of the [Apache License].
[Spring Web Services]: http://projects.spring.io/spring-ws
[Apache License]: http://www.apache.org/licenses/LICENSE-2.0

15
echo/README.md Normal file
View File

@@ -0,0 +1,15 @@
# Spring Web Service Tutorial
This sample shows a bare-bones echoing service. Incoming messages are handled
via DOM, and a simple 'business logic' service is used to obtain the result.
## Build and deploy
See the main [README](../README.md) for build instructions.
## License
[Spring Web Services] is released under version 2.0 of the [Apache License].
[Spring Web Services]: http://projects.spring.io/spring-ws
[Apache License]: http://www.apache.org/licenses/LICENSE-2.0

29
echo/build.gradle Normal file
View File

@@ -0,0 +1,29 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.gradle.api.plugins:gradle-tomcat-plugin:0.9.9'
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
repositories {
maven { url 'http://repo.spring.io/libs-release' }
}
dependencies {
testCompile("junit:junit:4.10")
testCompile("org.easymock:easymock:3.1")
}
}
task wrapper(type: Wrapper) {
gradleVersion = '1.8'
}

View File

@@ -0,0 +1,4 @@
task runClient(dependsOn: 'classes', type:JavaExec) {
main = "org.springframework.ws.samples.echo.client.saaj.EchoClient"
classpath = sourceSets.main.runtimeClasspath
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.echo.client.saaj;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
/**
* A client for the Echo Web Service that uses SAAJ.
*
* @author Ben Ethridge
* @author Arjen Poutsma
*/
public class EchoClient {
public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/echo";
public static final String PREFIX = "tns";
private SOAPConnectionFactory connectionFactory;
private MessageFactory messageFactory;
private URL url;
public EchoClient(String url) throws SOAPException, MalformedURLException {
connectionFactory = SOAPConnectionFactory.newInstance();
messageFactory = MessageFactory.newInstance();
this.url = new URL(url);
}
private SOAPMessage createEchoRequest() throws SOAPException {
SOAPMessage message = messageFactory.createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name echoRequestName = envelope.createName("echoRequest", PREFIX, NAMESPACE_URI);
SOAPBodyElement echoRequestElement = message.getSOAPBody()
.addBodyElement(echoRequestName);
echoRequestElement.setValue("Hello");
return message;
}
public void callWebService() throws SOAPException, IOException {
SOAPMessage request = createEchoRequest();
SOAPConnection connection = connectionFactory.createConnection();
SOAPMessage response = connection.call(request, url);
if (!response.getSOAPBody().hasFault()) {
writeEchoResponse(response);
}
else {
SOAPFault fault = response.getSOAPBody().getFault();
System.err.println("Received SOAP Fault");
System.err.println("SOAP Fault Code :" + fault.getFaultCode());
System.err.println("SOAP Fault String :" + fault.getFaultString());
}
}
private void writeEchoResponse(SOAPMessage message) throws SOAPException {
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
Name echoResponseName = envelope.createName("echoResponse", PREFIX, NAMESPACE_URI);
SOAPBodyElement echoResponseElement = (SOAPBodyElement) message
.getSOAPBody().getChildElements(echoResponseName).next();
String echoValue = echoResponseElement.getTextContent();
System.out.println();
System.out.println("Echo Response [" + echoValue + "]");
System.out.println();
}
public static void main(String[] args) throws Exception {
String url = "http://localhost:8080/echo-server/services";
if (args.length > 0) {
url = args[0];
}
EchoClient echoClient = new EchoClient(url);
echoClient.callWebService();
}
}

View File

@@ -0,0 +1,11 @@
ext.springWsVersion = '2.1.4.RELEASE'
dependencies {
compile("org.springframework.ws:spring-ws-core:$springWsVersion")
runtime("log4j:log4j:1.2.16")
}
task runClient(dependsOn: 'classes', type:JavaExec) {
main = "org.springframework.ws.samples.echo.client.sws.EchoClient"
classpath = sourceSets.main.runtimeClasspath
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.echo.client.sws;
import java.io.IOException;
import javax.xml.transform.Source;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.xml.transform.ResourceSource;
import org.springframework.xml.transform.StringResult;
public class EchoClient extends WebServiceGatewaySupport {
private Resource request;
public void setRequest(Resource request) {
this.request = request;
}
public void echo() throws IOException {
Source requestSource = new ResourceSource(request);
StringResult result = new StringResult();
getWebServiceTemplate().sendSourceAndReceiveToResult(requestSource, result);
System.out.println();
System.out.println(result);
System.out.println();
}
public static void main(String[] args) throws IOException {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("applicationContext.xml", EchoClient.class);
EchoClient echoClient = (EchoClient) applicationContext.getBean("echoClient");
echoClient.echo();
}
}

View File

@@ -0,0 +1,7 @@
log4j.rootLogger=WARN, stdout
log4j.logger.org.springframework.ws=DEBUG
log4j.logger.org.springframework.xml=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="echoClient" class="org.springframework.ws.samples.echo.client.sws.EchoClient">
<property name="defaultUri" value="http://localhost:8080/echo-server/services"/>
<property name="request" value="classpath:org/springframework/ws/samples/echo/client/sws/echoRequest.xml"/>
</bean>
</beans>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<echoRequest xmlns="http://www.springframework.org/spring-ws/samples/echo">Hello</echoRequest>

21
echo/server/build.gradle Normal file
View File

@@ -0,0 +1,21 @@
ext.springVersion = '3.2.4.RELEASE'
ext.springWsVersion = '2.1.4.RELEASE'
ext.tomcatVersion = '7.0.42'
apply plugin: 'war'
apply plugin: 'tomcat'
tomcatRun {
contextPath = 'echo-server'
}
dependencies {
compile("org.springframework.ws:spring-ws-core:$springWsVersion")
runtime("log4j:log4j:1.2.16")
tomcat("org.apache.tomcat.embed:tomcat-embed-core:$tomcatVersion",
"org.apache.tomcat.embed:tomcat-embed-logging-juli:$tomcatVersion")
tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:$tomcatVersion") {
exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj'
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.echo.service;
/**
* Defines the "business logic" of the web service.
*
* @author Ingo Siebert
* @author Arjen Poutsma
*/
public interface EchoService {
/**
* Returns the given string.
*
* @return <code>s</code>
*/
String echo(String s);
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.echo.service.impl;
import org.springframework.stereotype.Service;
import org.springframework.ws.samples.echo.service.EchoService;
/**
* Default implementation of <code>EchoService</code>.
*
* @author Ingo Siebert
* @author Arjen Poutsma
*/
@Service
public class EchoServiceImpl implements EchoService {
public String echo(String s) {
return s;
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.echo.ws;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.ws.samples.echo.service.EchoService;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
/**
* Simple echoing Web service endpoint. Uses a <code>EchoService</code> to create a response string.
*
* @author Ingo Siebert
* @author Arjen Poutsma
*/
@Endpoint
public class EchoEndpoint {
/**
* Namespace of both request and response.
*/
public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/echo";
/**
* The local name of the expected request.
*/
public static final String ECHO_REQUEST_LOCAL_NAME = "echoRequest";
/**
* The local name of the created response.
*/
public static final String ECHO_RESPONSE_LOCAL_NAME = "echoResponse";
private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
private final EchoService echoService;
@Autowired
public EchoEndpoint(EchoService echoService) {
this.echoService = echoService;
}
/**
* Reads the given <code>requestElement</code>, and sends a the response back.
*
* @param requestElement the contents of the SOAP message as DOM elements
* @return the response element
*/
@PayloadRoot(localPart = ECHO_REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI)
@ResponsePayload
public Element handleEchoRequest(@RequestPayload Element requestElement) throws ParserConfigurationException {
Assert.isTrue(NAMESPACE_URI.equals(requestElement.getNamespaceURI()), "Invalid namespace");
Assert.isTrue(ECHO_REQUEST_LOCAL_NAME.equals(requestElement.getLocalName()), "Invalid local name");
NodeList children = requestElement.getChildNodes();
Text requestText = null;
for (int i = 0; i < children.getLength(); i++) {
if (children.item(i).getNodeType() == Node.TEXT_NODE) {
requestText = (Text) children.item(i);
break;
}
}
if (requestText == null) {
throw new IllegalArgumentException("Could not find request text node");
}
String echo = echoService.echo(requestText.getNodeValue());
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
Element responseElement = document.createElementNS(NAMESPACE_URI, ECHO_RESPONSE_LOCAL_NAME);
Text responseText = document.createTextNode(echo);
responseElement.appendChild(responseText);
return responseElement;
}
}

View File

@@ -0,0 +1,7 @@
log4j.rootLogger=WARN, stdout
log4j.logger.org.springframework.ws=DEBUG
log4j.logger.org.springframework.xml=DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified"
targetNamespace="http://www.springframework.org/spring-ws/samples/echo"
xmlns:tns="http://www.springframework.org/spring-ws/samples/echo">
<element name="echoRequest">
<simpleType>
<restriction base="string">
<pattern value="([A-Z]|[a-z])+"/>
</restriction>
</simpleType>
</element>
<element name="echoResponse" type="string"/>
</schema>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sws="http://www.springframework.org/schema/web-services"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<description>
This web application context contains Spring-WS beans. The beans defined in this context are automatically
detected by Spring-WS, similar to the way Controllers are picked up in Spring Web MVC.
</description>
<context:component-scan base-package="org.springframework.ws.samples.echo"/>
<sws:annotation-driven />
<sws:interceptors>
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<description>
This interceptor validates both incoming and outgoing message contents according to the 'echo.xsd' XML
Schema file.
</description>
<property name="schema" value="/WEB-INF/echo.xsd"/>
<property name="validateRequest" value="true"/>
<property name="validateResponse" value="true"/>
</bean>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor">
<description>
This interceptor logs the message payload.
</description>
</bean>
</sws:interceptors>
<sws:dynamic-wsdl id="echo" portTypeName="Echo" locationUri="http://localhost:8080/echo/services">
<sws:xsd location="/WEB-INF/echo.xsd"/>
</sws:dynamic-wsdl>
</beans>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>
"Echo" WebService
</display-name>
<description>Returns a given string(only A-Z and a-z chars allowed). See echo.xsd file.</description>
<!-- Defines the Spring-WS MessageDispatcherServlet -->
<servlet>
<servlet-name>spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<!-- Transform the location attributes in WSDLs -->
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<!-- Map all requests to this servlet -->
<servlet-mapping>
<servlet-name>spring-ws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

View File

@@ -0,0 +1,75 @@
/*
* Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ws.samples.echo.ws;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.springframework.ws.samples.echo.service.EchoService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import static org.easymock.EasyMock.*;
public class EchoEndpointTest {
private EchoEndpoint endpoint;
private Document requestDocument;
private Document responseDocument;
private EchoService mock;
@Before
public void setUp() throws Exception {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
requestDocument = documentBuilder.newDocument();
responseDocument = documentBuilder.newDocument();
mock = createMock(EchoService.class);
endpoint = new EchoEndpoint(mock);
}
@Test
public void testInvokeInternal() throws Exception {
Element echoRequest =
requestDocument.createElementNS(EchoEndpoint.NAMESPACE_URI, EchoEndpoint.ECHO_REQUEST_LOCAL_NAME);
String content = "ABC";
Text requestText = requestDocument.createTextNode(content);
echoRequest.appendChild(requestText);
String result = "DEF";
expect(mock.echo(content)).andReturn(result);
replay(mock);
Element echoResponse = endpoint.handleEchoRequest(echoRequest);
Assert.assertEquals("Invalid namespace", EchoEndpoint.NAMESPACE_URI, echoResponse.getNamespaceURI());
Assert.assertEquals("Invalid namespace", EchoEndpoint.ECHO_RESPONSE_LOCAL_NAME, echoResponse.getLocalName());
Text responseText = (Text) echoResponse.getChildNodes().item(0);
Assert.assertEquals("Invalid content", result, responseText.getNodeValue());
verify(mock);
}
}

View File

@@ -0,0 +1,5 @@
log4j.rootCategory=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n

2
echo/settings.gradle Normal file
View File

@@ -0,0 +1,2 @@
include "server", "client:saaj", "client:spring-ws"