From f08dc7c1e0e8fb43c5e681118fe38298efb6e0e5 Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Sun, 20 Dec 2015 20:16:54 +0100 Subject: [PATCH] cxf: multiple changes following jabx2 implementation --- .../src/main/build-resources/wsdl/example.wsdl | 12 +- .../ws/client-spring-configuration.xml | 27 +++- .../endpoints/MyCustomExceptionResolver.java | 131 ------------------- .../MyCustomMappingExceptionResolver.java | 140 +++++++++++++++++++++ .../exceptions/CustomBusinessException.java | 2 +- .../impl/CustomBindingExampleServiceImpl.java | 2 +- .../resources/spring-configuration/ws/soap-ws.xml | 34 +++-- 7 files changed, 196 insertions(+), 152 deletions(-) delete mode 100644 cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/endpoints/MyCustomExceptionResolver.java create mode 100644 cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/endpoints/MyCustomMappingExceptionResolver.java diff --git a/cxf/web-services-spring-cxf-client/src/main/build-resources/wsdl/example.wsdl b/cxf/web-services-spring-cxf-client/src/main/build-resources/wsdl/example.wsdl index 5094a3a..f0ddf0f 100644 --- a/cxf/web-services-spring-cxf-client/src/main/build-resources/wsdl/example.wsdl +++ b/cxf/web-services-spring-cxf-client/src/main/build-resources/wsdl/example.wsdl @@ -1,4 +1,4 @@ - + @@ -127,10 +127,6 @@ - - - - @@ -143,6 +139,10 @@ + + + + @@ -190,7 +190,7 @@ - + \ No newline at end of file diff --git a/cxf/web-services-spring-cxf-client/src/main/resources/spring-configuration/ws/client-spring-configuration.xml b/cxf/web-services-spring-cxf-client/src/main/resources/spring-configuration/ws/client-spring-configuration.xml index f231006..5025d2f 100644 --- a/cxf/web-services-spring-cxf-client/src/main/resources/spring-configuration/ws/client-spring-configuration.xml +++ b/cxf/web-services-spring-cxf-client/src/main/resources/spring-configuration/ws/client-spring-configuration.xml @@ -63,7 +63,8 @@ at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:888) ESTE ERROR SE PRODUCE PORQUE cxf-codegen-plugin GENERA Examples QUE ES UN inteface @WebService - maven-jaxb2-plugin NO GENERA ESTOS OBJETOS (otra razón más para usar maven-jaxb2-plugin) + maven-jaxb2-plugin NO GENERA ESTOS OBJETOS pero maven-jaxb2-plugin NO ES BUENO PARA GENERAR CLASES + DESDE WSDLs POR LAS RAZONES EXPLICADAS EN EL pom.xml DEL PROYECTO web-services-spring-jaxb2-client. --> @@ -92,14 +93,34 @@ class="org.springframework.ws.client.support.interceptor.PayloadValidatingInterceptor"> - classpath:examples.xsd - classpath:parent.xsd + + classpath:parent.xsd + + classpath:examples.xsd + + diff --git a/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/endpoints/MyCustomExceptionResolver.java b/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/endpoints/MyCustomExceptionResolver.java deleted file mode 100644 index f2a375f..0000000 --- a/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/endpoints/MyCustomExceptionResolver.java +++ /dev/null @@ -1,131 +0,0 @@ -package de.spring.webservices.endpoints; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import javax.xml.transform.Result; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.oxm.Marshaller; -import org.springframework.util.CollectionUtils; -import org.springframework.ws.soap.SoapFault; -import org.springframework.ws.soap.SoapFaultDetail; -import org.springframework.ws.soap.server.endpoint.AbstractSoapFaultDefinitionExceptionResolver; -import org.springframework.ws.soap.server.endpoint.SoapFaultDefinition; -import org.springframework.ws.soap.server.endpoint.SoapFaultDefinitionEditor; - -import de.spring.webservices.auto.Element; -import de.spring.webservices.auto.ExampleFault; -import de.spring.webservices.exceptions.CustomBusinessException; - -public class MyCustomExceptionResolver extends AbstractSoapFaultDefinitionExceptionResolver { - private static final Logger LOGGER = LoggerFactory.getLogger(MyCustomExceptionResolver.class); - - private Marshaller marshaller; - - private Map exceptionMappings = new LinkedHashMap<>(); - - /** - * Set the mappings between exception class names and SOAP Faults. The exception class name can be a substring, with - * no wildcard support at present. - * - *

The values of the given properties object should use the format described in - * {@code SoapFaultDefinitionEditor}. - * - *

Follows the same matching algorithm as {@code SimpleMappingExceptionResolver}. - * - * @param mappings exception patterns (can also be fully qualified class names) as keys, fault definition texts as - * values - * @see SoapFaultDefinitionEditor - */ - public void setExceptionMappings(Properties mappings) { - for (Map.Entry entry : mappings.entrySet()) { - if (entry.getKey() instanceof String && entry.getValue() instanceof String) { - exceptionMappings.put((String)entry.getKey(), (String)entry.getValue()); - } - } - } - - @Override - protected SoapFaultDefinition getFaultDefinition(Object endpoint, Exception ex) { - if (!CollectionUtils.isEmpty(exceptionMappings)) { - String definitionText = null; - int deepest = Integer.MAX_VALUE; - for (String exceptionMapping : exceptionMappings.keySet()) { - int depth = getDepth(exceptionMapping, ex); - if (depth >= 0 && depth < deepest) { - deepest = depth; - definitionText = exceptionMappings.get(exceptionMapping); - } - } - if (definitionText != null) { - SoapFaultDefinitionEditor editor = new SoapFaultDefinitionEditor(); - editor.setAsText(definitionText); - return (SoapFaultDefinition) editor.getValue(); - } - } - return null; - } - - /** - * Return the depth to the superclass matching. {@code 0} means ex matches exactly. Returns {@code -1} if - * there's no match. Otherwise, returns depth. Lowest depth wins. - * - *

Follows the same algorithm as RollbackRuleAttribute, and SimpleMappingExceptionResolver - */ - protected int getDepth(String exceptionMapping, Exception ex) { - return getDepth(exceptionMapping, ex.getClass(), 0); - } - - @SuppressWarnings("unchecked") - private int getDepth(String exceptionMapping, Class exceptionClass, int depth) { - if (exceptionClass.getName().indexOf(exceptionMapping) != -1) { - return depth; - } - if (exceptionClass.equals(Throwable.class)) { - return -1; - } - return getDepth(exceptionMapping, (Class) exceptionClass.getSuperclass(), depth + 1); - } - - protected void customizeFault(Object endpoint, Exception ex, SoapFault fault) { - SoapFaultDetail detail = fault.addFaultDetail(); - Result result = detail.getResult(); - - Element element = new Element(); - element.setMessage(ex.getMessage()); - - if (ex instanceof CustomBusinessException) { - List arguments = element.getMessageArgs(); - arguments.add("ARGUMENT 1"); - arguments.add("ARGUMENT 2"); - } - - ExampleFault customFault = new ExampleFault(); - customFault.setTechnicalError(getStackTrace(ex)); - List elements = customFault.getElements(); - elements.add(element); - - try { - marshaller.marshal(customFault, result); - } catch (Exception marshallEx) { - LOGGER.error("", marshallEx); - } - } - - public void setMarshaller(Marshaller marshaller) { - this.marshaller = marshaller; - } - - private static String getStackTrace(final Throwable throwable) { - final StringWriter sw = new StringWriter(); - final PrintWriter pw = new PrintWriter(sw, true); - throwable.printStackTrace(pw); - return sw.getBuffer().toString(); - } -} diff --git a/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/endpoints/MyCustomMappingExceptionResolver.java b/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/endpoints/MyCustomMappingExceptionResolver.java new file mode 100644 index 0000000..f07d42e --- /dev/null +++ b/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/endpoints/MyCustomMappingExceptionResolver.java @@ -0,0 +1,140 @@ +package de.spring.webservices.endpoints; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.xml.transform.Result; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.oxm.Marshaller; +import org.springframework.util.CollectionUtils; +import org.springframework.ws.soap.SoapFault; +import org.springframework.ws.soap.SoapFaultDetail; +import org.springframework.ws.soap.server.endpoint.AbstractSoapFaultDefinitionExceptionResolver; +import org.springframework.ws.soap.server.endpoint.SoapFaultDefinition; +import org.springframework.ws.soap.server.endpoint.SoapFaultDefinitionEditor; + +import de.spring.webservices.auto.Element; +import de.spring.webservices.auto.ExampleFault; +import de.spring.webservices.exceptions.CustomBusinessException; + +public class MyCustomMappingExceptionResolver extends AbstractSoapFaultDefinitionExceptionResolver { + private static final Logger LOGGER = LoggerFactory.getLogger(MyCustomMappingExceptionResolver.class); + + private Marshaller marshaller; + + private Map exceptionMappings = new LinkedHashMap<>(); + + /** + * Set the mappings between exception class names and SOAP Faults. The exception class name can be a substring, with + * no wildcard support at present. + * + *

The values of the given properties object should use the format described in + * {@code SoapFaultDefinitionEditor}. + * + *

Follows the same matching algorithm as {@code SimpleMappingExceptionResolver}. + * + * @param mappings exception patterns (can also be fully qualified class names) as keys, fault definition texts as + * values + * @see SoapFaultDefinitionEditor + */ + public void setExceptionMappings(Properties mappings) { + for (Map.Entry entry : mappings.entrySet()) { + if (entry.getKey() instanceof String && entry.getValue() instanceof String) { + exceptionMappings.put((String)entry.getKey(), (String)entry.getValue()); + } + } + } + + @Override + protected SoapFaultDefinition getFaultDefinition(Object endpoint, Exception ex) { + if (!CollectionUtils.isEmpty(exceptionMappings)) { + String definitionText = null; + int deepest = Integer.MAX_VALUE; + for (String exceptionMapping : exceptionMappings.keySet()) { + int depth = getDepth(exceptionMapping, ex); + if (depth >= 0 && depth < deepest) { + deepest = depth; + definitionText = exceptionMappings.get(exceptionMapping); + } + } + if (definitionText != null) { + SoapFaultDefinitionEditor editor = new SoapFaultDefinitionEditor(); + editor.setAsText(definitionText); + return (SoapFaultDefinition) editor.getValue(); + } + } + return null; + } + + /** + * Return the depth to the superclass matching. {@code 0} means ex matches exactly. Returns {@code -1} if + * there's no match. Otherwise, returns depth. Lowest depth wins. + * + *

Follows the same algorithm as RollbackRuleAttribute, and SimpleMappingExceptionResolver + */ + protected int getDepth(String exceptionMapping, Exception ex) { + return getDepth(exceptionMapping, ex.getClass(), 0); + } + + @SuppressWarnings("unchecked") + private int getDepth(String exceptionMapping, Class exceptionClass, int depth) { + if (exceptionClass.getName().indexOf(exceptionMapping) != -1) { + return depth; + } + if (exceptionClass.equals(Throwable.class)) { + return -1; + } + return getDepth(exceptionMapping, (Class) exceptionClass.getSuperclass(), depth + 1); + } + + protected void customizeFault(Object endpoint, Exception ex, SoapFault fault) { + ExampleFault customFault = new ExampleFault(); + customFault.setTechnicalError(getStackTrace(ex)); + + Element element = buildElement(ex); + List elements = customFault.getElements(); + elements.add(element); + + SoapFaultDetail detail = fault.addFaultDetail(); + Result result = detail.getResult(); + try { + marshaller.marshal(customFault, result); + } catch (Exception marshallEx) { + LOGGER.error("MyCustomMappingExceptionResolver: marshaller error", marshallEx); + } + } + + public void setMarshaller(Marshaller marshaller) { + this.marshaller = marshaller; + } + + private Element buildElement(Exception ex) { + Element element = new Element(); + element.setMessage(ex.getMessage()); + + if (ex instanceof CustomBusinessException) { + CustomBusinessException customEx = (CustomBusinessException) ex; + List messageArgs = element.getMessageArgs(); + List argumentsEx = customEx.getArguments(); + + for (String argumentEx: argumentsEx) { + messageArgs.add(argumentEx); + } + } + + return element; + } + + private String getStackTrace(Throwable throwable) { + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw, true); + throwable.printStackTrace(pw); + return sw.getBuffer().toString(); + } +} diff --git a/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/exceptions/CustomBusinessException.java b/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/exceptions/CustomBusinessException.java index 952e765..549c0b9 100644 --- a/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/exceptions/CustomBusinessException.java +++ b/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/exceptions/CustomBusinessException.java @@ -3,7 +3,7 @@ package de.spring.webservices.exceptions; import java.util.List; /** - * This exception will be caught by de.spring.webservices.endpoints.MyCustomExceptionResolver + * This exception will be caught by de.spring.webservices.endpoints.MyCustomMappingExceptionResolver * */ public class CustomBusinessException extends RuntimeException { diff --git a/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/services/impl/CustomBindingExampleServiceImpl.java b/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/services/impl/CustomBindingExampleServiceImpl.java index c5ce222..9863bae 100644 --- a/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/services/impl/CustomBindingExampleServiceImpl.java +++ b/cxf/web-services-spring-cxf-server/src/main/java/de/spring/webservices/services/impl/CustomBindingExampleServiceImpl.java @@ -28,7 +28,7 @@ public class CustomBindingExampleServiceImpl implements // see soap-ws.xml Spring configuration file. // throw new BusinessException("This feature has not been implemented yet."); - // Example about how works de.spring.webservices.endpoints.MyCustomExceptionResolver + // Example about how works de.spring.webservices.endpoints.MyCustomMappingExceptionResolver // see soap-ws.xml Spring configuration file. // List arguments = new ArrayList<>(); // arguments.add("ARGUMENT 1"); diff --git a/cxf/web-services-spring-cxf-server/src/main/resources/spring-configuration/ws/soap-ws.xml b/cxf/web-services-spring-cxf-server/src/main/resources/spring-configuration/ws/soap-ws.xml index 27ccc48..6dd10fc 100644 --- a/cxf/web-services-spring-cxf-server/src/main/resources/spring-configuration/ws/soap-ws.xml +++ b/cxf/web-services-spring-cxf-server/src/main/resources/spring-configuration/ws/soap-ws.xml @@ -98,16 +98,11 @@ + targetNamespace="http://gumartinm.name/spring-ws/exampleService"> - - - - - classpath:parent.xsd + + classpath:examples.xsd @@ -164,7 +170,7 @@ class="org.springframework.ws.soap.server.endpoint.SoapFaultMappingExceptionResolver"> + - SERVER -- 2.1.4