Merged WSNamespace into WSPath

This commit is contained in:
Ziver Koc 2021-03-02 21:01:55 +01:00
parent bb8d6a93b4
commit fd7f197a17
10 changed files with 77 additions and 103 deletions

View file

@ -128,14 +128,6 @@ public interface WSInterface {
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@interface WSHeader {} @interface WSHeader {}
/**
* Specifies the name space for the method.
*/
@Retention(RetentionPolicy.RUNTIME)
@interface WSNamespace {
String value();
}
/** /**
* Specifies the request type. * Specifies the request type.
*/ */
@ -146,10 +138,10 @@ public interface WSInterface {
} }
/** /**
* Sets a specific URL path for the method overriding the auto generated path. * Sets a specific URL path for the method overriding the auto generated path. This will also be used as the namespace.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target({ElementType.TYPE, ElementType.METHOD})
@interface WSPath { @interface WSPath {
String value(); String value();
} }

View file

@ -25,7 +25,6 @@
package zutil.net.ws; package zutil.net.ws;
import zutil.net.ws.WSInterface.WSDocumentation; import zutil.net.ws.WSInterface.WSDocumentation;
import zutil.net.ws.WSInterface.WSNamespace;
import zutil.net.ws.WSInterface.WSPath; import zutil.net.ws.WSInterface.WSPath;
import zutil.net.ws.WSInterface.WSRequestType; import zutil.net.ws.WSInterface.WSRequestType;
@ -50,11 +49,11 @@ public class WSMethodDef {
/** /**
* A list of input parameters * A list of input parameters
**/ **/
private ArrayList<WSParameterDef> inputs; private ArrayList<WSParameterDef> inputs = new ArrayList<>();
/** /**
* A List of return parameters of the method * A List of return parameters of the method
**/ **/
private ArrayList<WSParameterDef> outputs; private ArrayList<WSParameterDef> outputs = new ArrayList<>();
/** /**
* The object type of output object * The object type of output object
**/ **/
@ -62,7 +61,7 @@ public class WSMethodDef {
/** /**
* A List of exceptions that this method throws * A List of exceptions that this method throws
**/ **/
private ArrayList<Class<?>> exceptions; private ArrayList<Class<?>> exceptions = new ArrayList<>();
/** /**
* The real method that this class represent, can be null if its a remote method * The real method that this class represent, can be null if its a remote method
**/ **/
@ -72,9 +71,9 @@ public class WSMethodDef {
**/ **/
private String doc; private String doc;
/** /**
* The namespace of the method * The URL path of the method
**/ **/
private String namespace; private String path;
/** /**
* The type of request required to execute the method * The type of request required to execute the method
**/ **/
@ -83,38 +82,34 @@ public class WSMethodDef {
* The published name of the method * The published name of the method
**/ **/
private String name; private String name;
/**
* The endpoint location
**/
private String path;
/** /**
* @param wsDef is the parent web service defining interface * @param wsDef is the parent web service defining interface
* @param me is a method in a class that implements WSInterface * @param method is a method in a class that implements WSInterface
*/ */
protected WSMethodDef(WebServiceDef wsDef, Method me) { protected WSMethodDef(WebServiceDef wsDef, Method method) {
if (!WSInterface.class.isAssignableFrom(me.getDeclaringClass())) if (!WSInterface.class.isAssignableFrom(method.getDeclaringClass()))
throw new ClassCastException("Declaring class does not implement WSInterface!"); throw new ClassCastException("Declaring class does not implement WSInterface!");
this.wsDef = wsDef; this.wsDef = wsDef;
this.method = me; this.method = method;
this.inputs = new ArrayList<>();
this.outputs = new ArrayList<>();
this.exceptions = new ArrayList<>();
this.name = method.getName(); this.name = method.getName();
// Handle documentation and namespace // Handle documentation and namespace
WSDocumentation docAnnotation = method.getAnnotation(WSDocumentation.class); WSDocumentation docAnnotation = this.method.getAnnotation(WSDocumentation.class);
if (docAnnotation != null) if (docAnnotation != null)
doc = docAnnotation.value(); doc = docAnnotation.value();
WSNamespace namespaceAnnotation = method.getAnnotation(WSNamespace.class); WSPath namespaceAnnotation = this.method.getAnnotation(WSPath.class);
if (namespaceAnnotation != null) if (namespaceAnnotation != null)
namespace = namespaceAnnotation.value(); path = namespaceAnnotation.value();
else else
namespace = wsDef.getNamespace() + "?#" + name; path = name;
if (path.startsWith("/"))
path = path.substring(1);
// ------------------------------------------------ // ------------------------------------------------
// Handle inputs // Handle inputs
@ -137,7 +132,7 @@ public class WSMethodDef {
// Handle outputs // Handle outputs
// ------------------------------------------------ // ------------------------------------------------
this.outputClass = method.getReturnType(); this.outputClass = this.method.getReturnType();
if (WSReturnObject.class.isAssignableFrom(outputClass)) { if (WSReturnObject.class.isAssignableFrom(outputClass)) {
Field[] fields = outputClass.getFields(); Field[] fields = outputClass.getFields();
@ -150,8 +145,8 @@ public class WSMethodDef {
outputs.add(ret_param); outputs.add(ret_param);
} }
} else if (outputClass != void.class) { } else if (outputClass != void.class) {
WSInterface.WSReturnName returnNameAnnotation = method.getAnnotation(WSInterface.WSReturnName.class); WSInterface.WSReturnName returnNameAnnotation = this.method.getAnnotation(WSInterface.WSReturnName.class);
WSParameterDef ret_param = new WSParameterDef(this, method.getReturnType(), new Annotation[]{returnNameAnnotation}); WSParameterDef ret_param = new WSParameterDef(this, this.method.getReturnType(), new Annotation[]{returnNameAnnotation});
if (ret_param.getName() == null) if (ret_param.getName() == null)
ret_param.setName("return"); ret_param.setName("return");
@ -163,13 +158,13 @@ public class WSMethodDef {
// Handle Exceptions // Handle Exceptions
// ------------------------------------------------ // ------------------------------------------------
Collections.addAll(exceptions, method.getExceptionTypes()); Collections.addAll(exceptions, this.method.getExceptionTypes());
// ------------------------------------------------ // ------------------------------------------------
// Handle the request type // Handle the request type
// ------------------------------------------------ // ------------------------------------------------
WSRequestType requestTypeAnnotation = method.getAnnotation(WSRequestType.class); WSRequestType requestTypeAnnotation = this.method.getAnnotation(WSRequestType.class);
if (requestTypeAnnotation != null) { if (requestTypeAnnotation != null) {
this.requestType = requestTypeAnnotation.value(); this.requestType = requestTypeAnnotation.value();
} else { } else {
@ -186,19 +181,6 @@ public class WSMethodDef {
else else
this.requestType = WSInterface.RequestType.GET; this.requestType = WSInterface.RequestType.GET;
} }
// ------------------------------------------------
// Handle endpoint path
// ------------------------------------------------
WSPath pathAnnotation = method.getAnnotation(WSPath.class);
if (pathAnnotation != null)
path = pathAnnotation.value();
else
path = this.name;
if (!path.startsWith("/"))
path = '/' + path;
} }
/** /**
@ -212,7 +194,7 @@ public class WSMethodDef {
* @return the path to the WS method endpoint * @return the path to the WS method endpoint
*/ */
public String getPath() { public String getPath() {
return path; return wsDef.getPath() + "/" + path;
} }
/** /**
@ -257,19 +239,12 @@ public class WSMethodDef {
return requestType; return requestType;
} }
/**
* @return the namespace or endpoint url of the method
*/
public String getNamespace() {
return namespace;
}
/** /**
* Invokes a specified method * Invokes a specified method
* *
* @param params a vector with arguments * @param params a vector with arguments
* @param obj the object the method will called on * @param obj the object the method will called on
*/ */
public Object invoke(Object obj, Object[] params) throws Exception { public Object invoke(Object obj, Object[] params) throws Exception {
return this.method.invoke(obj, params); return this.method.invoke(obj, params);

View file

@ -38,24 +38,27 @@ import java.util.Set;
public class WebServiceDef { public class WebServiceDef {
/** This is the WSInterface class **/ /** This is the WSInterface class **/
private Class<? extends WSInterface> intf; private Class<? extends WSInterface> intf;
/** Namespace of the service **/
private String namespace;
/** Name of the web service **/ /** Name of the web service **/
private String name; private String name;
/** Path or namespace of the service **/
private String path = "";
/** Human readable description of the service **/ /** Human readable description of the service **/
private String documentation = ""; private String documentation = "";
/** A map of methods in this Service **/ /** A map of methods in this Service **/
private HashMap<String,WSMethodDef> methods = new HashMap<>(); private HashMap<String,WSMethodDef> methods = new HashMap<>();
public WebServiceDef(Class<? extends WSInterface> intf){ public WebServiceDef(Class<? extends WSInterface> intf){
this.intf = intf; this.intf = intf;
name = intf.getSimpleName(); name = intf.getSimpleName();
WSInterface.WSNamespace namespaceAnnotation = intf.getAnnotation(WSInterface.WSNamespace.class); WSInterface.WSPath pathAnnotation = intf.getAnnotation(WSInterface.WSPath.class);
if (namespaceAnnotation != null) if (pathAnnotation != null) {
this.namespace = namespaceAnnotation.value(); this.path = pathAnnotation.value();
if (path.endsWith("/")) // remove last backslash
path = path.substring(0, path.length()-1);
}
WSInterface.WSDocumentation documentationAnnotation = intf.getAnnotation(WSInterface.WSDocumentation.class); WSInterface.WSDocumentation documentationAnnotation = intf.getAnnotation(WSInterface.WSDocumentation.class);
if (documentationAnnotation != null) if (documentationAnnotation != null)
@ -63,14 +66,14 @@ public class WebServiceDef {
for(Method m : intf.getDeclaredMethods()){ for(Method m : intf.getDeclaredMethods()){
// Check for public methods // Check for public methods
if ((m.getModifiers() & Modifier.PUBLIC) > 0 && if ((m.getModifiers() & Modifier.PUBLIC) > 0 && !m.isAnnotationPresent(WSInterface.WSIgnore.class)){
!m.isAnnotationPresent(WSInterface.WSIgnore.class)){
WSMethodDef method = new WSMethodDef(this, m); WSMethodDef method = new WSMethodDef(this, m);
methods.put(method.getName(), method); methods.put(method.getName(), method);
} }
} }
} }
/** /**
* @return the class that defines this web service * @return the class that defines this web service
*/ */
@ -93,16 +96,16 @@ public class WebServiceDef {
} }
/** /**
* @param name is the name of the method * @param name is the name of the method
* @return if there is a method by the given name * @return if there is a method by the given name
*/ */
public boolean hasMethod( String name ){ public boolean hasMethod( String name ){
return methods.containsKey( name ); return methods.containsKey( name );
} }
/** /**
* @param name is the name of the method * @param name is the name of the method
* @return the method or null if there is no such method * @return the method or null if there is no such method
*/ */
public WSMethodDef getMethod( String name ){ public WSMethodDef getMethod( String name ){
return methods.get( name ); return methods.get( name );
@ -125,8 +128,8 @@ public class WebServiceDef {
/** /**
* @return the namespace of this web service ( usually the URL of the service ) * @return the namespace of this web service ( usually the URL of the service )
*/ */
public String getNamespace(){ public String getPath(){
return namespace; return path;
} }
public WSInterface newInstance() throws InstantiationException, IllegalAccessException { public WSInterface newInstance() throws InstantiationException, IllegalAccessException {

View file

@ -107,7 +107,7 @@ public class SOAPClientInvocationHandler implements InvocationHandler {
Element body = envelope.addElement("soap:Body"); Element body = envelope.addElement("soap:Body");
Element method = body.addElement(""); Element method = body.addElement("");
method.addNamespace("m", methodDef.getNamespace()); method.addNamespace("m", methodDef.getPath());
method.setName("m:" + methodDef.getName() + "Request"); method.setName("m:" + methodDef.getName() + "Request");
List<WSParameterDef> outputParamDefs = methodDef.getOutputs(); List<WSParameterDef> outputParamDefs = methodDef.getOutputs();

View file

@ -291,7 +291,7 @@ public class SOAPHttpPage implements HttpPage{
// generate response XML // generate response XML
if (outputParamDefs.size() > 0) { if (outputParamDefs.size() > 0) {
Element response = responseRoot.addElement(""); Element response = responseRoot.addElement("");
response.addNamespace("m", methodDef.getNamespace() ); response.addNamespace("m", methodDef.getPath() );
response.setName("m:" + methodDef.getName() + "Response"); response.setName("m:" + methodDef.getName() + "Response");
if (outputParams instanceof WSReturnObject) { if (outputParams instanceof WSReturnObject) {

View file

@ -56,7 +56,7 @@ public class WSDLServiceSOAP extends WSDLService{
// definitions -> binding -> operation -> soap:operation // definitions -> binding -> operation -> soap:operation
Element soap_operation = operation.addElement("soap:operation"); Element soap_operation = operation.addElement("soap:operation");
soap_operation.addAttribute("soapAction", method.getNamespace()); soap_operation.addAttribute("soapAction", method.getPath());
// ------------------------------------------------ // ------------------------------------------------
// Input // Input
@ -67,7 +67,7 @@ public class WSDLServiceSOAP extends WSDLService{
// definitions -> binding -> operation -> input -> body // definitions -> binding -> operation -> input -> body
Element input_body = input.addElement("soap:body"); Element input_body = input.addElement("soap:body");
input_body.addAttribute("use", "literal"); input_body.addAttribute("use", "literal");
input_body.addAttribute("namespace", method.getNamespace()); input_body.addAttribute("namespace", method.getPath());
// ------------------------------------------------ // ------------------------------------------------
// Output // Output
@ -79,7 +79,7 @@ public class WSDLServiceSOAP extends WSDLService{
// definitions -> binding -> operation -> input -> body // definitions -> binding -> operation -> input -> body
Element output_body = output.addElement("soap:body"); Element output_body = output.addElement("soap:body");
output_body.addAttribute("use", "literal"); output_body.addAttribute("use", "literal");
output_body.addAttribute("namespace", method.getNamespace()); output_body.addAttribute("namespace", method.getPath());
} }
} }
} }

View file

@ -107,8 +107,8 @@ public class WSDLWriter {
definitions.addNamespace("http", "http://schemas.xmlsoap.org/wsdl/http/"); definitions.addNamespace("http", "http://schemas.xmlsoap.org/wsdl/http/");
definitions.addNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); definitions.addNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
definitions.addNamespace("soap-enc", "http://schemas.xmlsoap.org/soap/encoding/"); definitions.addNamespace("soap-enc", "http://schemas.xmlsoap.org/soap/encoding/");
definitions.addNamespace("tns", ws.getNamespace() + "?type"); definitions.addNamespace("tns", ws.getPath() + "/type");
definitions.addAttribute("targetNamespace", ws.getNamespace()); definitions.addAttribute("targetNamespace", ws.getPath());
generateType(definitions); generateType(definitions);
generateMessages(definitions); generateMessages(definitions);
@ -306,7 +306,7 @@ public class WSDLWriter {
// definitions -> types // definitions -> types
Element typeE = definitions.addElement("wsdl:types"); Element typeE = definitions.addElement("wsdl:types");
Element schema = typeE.addElement("xsd:schema"); Element schema = typeE.addElement("xsd:schema");
schema.addAttribute("targetNamespace", ws.getNamespace() + "?type"); schema.addAttribute("targetNamespace", ws.getPath() + "/type");
// empty type // empty type
Element empty = schema.addElement("xsd:complexType"); Element empty = schema.addElement("xsd:complexType");
@ -316,7 +316,10 @@ public class WSDLWriter {
for (int i=0; i<types.size(); i++) { for (int i=0; i<types.size(); i++) {
Class<?> c = types.get(i); Class<?> c = types.get(i);
// --------------------------------------------
// Generate Array type // Generate Array type
// --------------------------------------------
if (c.isArray()) { if (c.isArray()) {
Class<?> ctmp = ClassUtil.getArrayClass(c); Class<?> ctmp = ClassUtil.getArrayClass(c);
@ -338,7 +341,11 @@ public class WSDLWriter {
if (!types.contains(ctmp)) if (!types.contains(ctmp))
types.add(ctmp); types.add(ctmp);
} }
// --------------------------------------------
// Generate SOAPObject type // Generate SOAPObject type
// --------------------------------------------
else if (WSReturnObject.class.isAssignableFrom(c)) { else if (WSReturnObject.class.isAssignableFrom(c)) {
Element type = schema.addElement("xsd:complexType"); Element type = schema.addElement("xsd:complexType");
type.addAttribute("name", SOAPHttpPage.getSOAPClassName(c)); type.addAttribute("name", SOAPHttpPage.getSOAPClassName(c));

View file

@ -24,13 +24,10 @@
package zutil.net.ws.rest; package zutil.net.ws.rest;
import org.junit.Test;
import zutil.net.ws.WSInterface; import zutil.net.ws.WSInterface;
import zutil.net.ws.WebServiceDef;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.HashMap;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -42,7 +39,7 @@ public class RESTClientTest {
public interface OpenWeartherMap extends WSInterface { public interface OpenWeartherMap extends WSInterface {
@WSNamespace("") @WSPath("")
int weather(@WSParamName("q") String city); int weather(@WSParamName("q") String city);
} }

View file

@ -28,7 +28,7 @@ import org.dom4j.Document;
import org.dom4j.io.OutputFormat; import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter; import org.dom4j.io.XMLWriter;
import zutil.net.ws.WSInterface; import zutil.net.ws.WSInterface;
import zutil.net.ws.WSInterface.WSNamespace; import zutil.net.ws.WSInterface.WSPath;
import zutil.net.ws.WSInterface.WSParamName; import zutil.net.ws.WSInterface.WSParamName;
import zutil.net.ws.WSReturnObject; import zutil.net.ws.WSReturnObject;
import zutil.net.ws.WebServiceDef; import zutil.net.ws.WebServiceDef;
@ -85,7 +85,7 @@ public class SOAPTest {
// ---------------------------------------------------- // ----------------------------------------------------
@SuppressWarnings("unused") @SuppressWarnings("unused")
@WSNamespace("http://test.se:8080/") @WSPath("http://test.se:8080/")
public static class MainSOAPClass implements WSInterface{ public static class MainSOAPClass implements WSInterface{
public MainSOAPClass(){} public MainSOAPClass(){}

View file

@ -39,9 +39,9 @@ public class WSDLWriterTest {
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"\n" + "\n" +
"<wsdl:definitions xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap-enc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tns=\"http://test.se:8080/?type\" targetNamespace=\"http://test.se:8080/\">\n" + "<wsdl:definitions xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap-enc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:tns=\"http://test.se:8080/type\" targetNamespace=\"http://test.se:8080\">\n" +
" <wsdl:types>\n" + " <wsdl:types>\n" +
" <xsd:schema targetNamespace=\"http://test.se:8080/?type\">\n" + " <xsd:schema targetNamespace=\"http://test.se:8080/type\">\n" +
" <xsd:complexType name=\"empty\">\n" + " <xsd:complexType name=\"empty\">\n" +
" <xsd:sequence/>\n" + " <xsd:sequence/>\n" +
" </xsd:complexType>\n" + " </xsd:complexType>\n" +
@ -125,42 +125,42 @@ public class WSDLWriterTest {
" <wsdl:binding name=\"MainSOAPClassBinding\" type=\"tns:MainSOAPClassPortType\">\n" + " <wsdl:binding name=\"MainSOAPClassBinding\" type=\"tns:MainSOAPClassPortType\">\n" +
" <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n" + " <soap:binding style=\"rpc\" transport=\"http://schemas.xmlsoap.org/soap/http\"/>\n" +
" <wsdl:operation name=\"stringArrayMethod\">\n" + " <wsdl:operation name=\"stringArrayMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#stringArrayMethod\"/>\n" + " <soap:operation soapAction=\"http://test.se:8080/stringArrayMethod\"/>\n" +
" <wsdl:input>\n" + " <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#stringArrayMethod\"/>\n" + " <soap:body use=\"literal\" namespace=\"http://test.se:8080/stringArrayMethod\"/>\n" +
" </wsdl:input>\n" + " </wsdl:input>\n" +
" <wsdl:output>\n" + " <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#stringArrayMethod\"/>\n" + " <soap:body use=\"literal\" namespace=\"http://test.se:8080/stringArrayMethod\"/>\n" +
" </wsdl:output>\n" + " </wsdl:output>\n" +
" </wsdl:operation>\n" + " </wsdl:operation>\n" +
" <wsdl:operation name=\"simpleReturnClassMethod\">\n" + " <wsdl:operation name=\"simpleReturnClassMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" + " <soap:operation soapAction=\"http://test.se:8080/simpleReturnClassMethod\"/>\n" +
" <wsdl:input>\n" + " <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" + " <soap:body use=\"literal\" namespace=\"http://test.se:8080/simpleReturnClassMethod\"/>\n" +
" </wsdl:input>\n" + " </wsdl:input>\n" +
" <wsdl:output>\n" + " <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#simpleReturnClassMethod\"/>\n" + " <soap:body use=\"literal\" namespace=\"http://test.se:8080/simpleReturnClassMethod\"/>\n" +
" </wsdl:output>\n" + " </wsdl:output>\n" +
" </wsdl:operation>\n" + " </wsdl:operation>\n" +
" <wsdl:operation name=\"exceptionMethod\">\n" + " <wsdl:operation name=\"exceptionMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#exceptionMethod\"/>\n" + " <soap:operation soapAction=\"http://test.se:8080/exceptionMethod\"/>\n" +
" <wsdl:input>\n" + " <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#exceptionMethod\"/>\n" + " <soap:body use=\"literal\" namespace=\"http://test.se:8080/exceptionMethod\"/>\n" +
" </wsdl:input>\n" + " </wsdl:input>\n" +
" </wsdl:operation>\n" + " </wsdl:operation>\n" +
" <wsdl:operation name=\"specialReturnMethod\">\n" + " <wsdl:operation name=\"specialReturnMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#specialReturnMethod\"/>\n" + " <soap:operation soapAction=\"http://test.se:8080/specialReturnMethod\"/>\n" +
" <wsdl:input>\n" + " <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#specialReturnMethod\"/>\n" + " <soap:body use=\"literal\" namespace=\"http://test.se:8080/specialReturnMethod\"/>\n" +
" </wsdl:input>\n" + " </wsdl:input>\n" +
" <wsdl:output>\n" + " <wsdl:output>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#specialReturnMethod\"/>\n" + " <soap:body use=\"literal\" namespace=\"http://test.se:8080/specialReturnMethod\"/>\n" +
" </wsdl:output>\n" + " </wsdl:output>\n" +
" </wsdl:operation>\n" + " </wsdl:operation>\n" +
" <wsdl:operation name=\"voidMethod\">\n" + " <wsdl:operation name=\"voidMethod\">\n" +
" <soap:operation soapAction=\"http://test.se:8080/?#voidMethod\"/>\n" + " <soap:operation soapAction=\"http://test.se:8080/voidMethod\"/>\n" +
" <wsdl:input>\n" + " <wsdl:input>\n" +
" <soap:body use=\"literal\" namespace=\"http://test.se:8080/?#voidMethod\"/>\n" + " <soap:body use=\"literal\" namespace=\"http://test.se:8080/voidMethod\"/>\n" +
" </wsdl:input>\n" + " </wsdl:input>\n" +
" </wsdl:operation>\n" + " </wsdl:operation>\n" +
" </wsdl:binding>\n" + " </wsdl:binding>\n" +