I have one issue. I've generated a WS server from a wsdl and i'm am trying to understand the exceptions handiling. Basically in the WSDL is defined a custom exception called Throwable_Exception. Now I've tired to test the fault in the SOAP response and it work and thats the result:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>TEST Custom Exception</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
The text in the "faultstring" tag is the messagge that i've thrown in the exception. Now my goal its to send in the response this kind of informations:
- A readable messagge about the exception
- The exception thrown from the server
- eventually the details about the exception
I've seen on an guide from Oracle that the SOAP fault envelope should be like this:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>Your name is required.</faultstring>
<detail>
<ns2:MissingName xmlns:ns2="http://examples/">
<message>Your name is required.</message>
</ns2:MissingName>
<ns2:exception xmlns:ns2="http://jax-ws.dev.java.net/"
note="To disable this feature, set
com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace system
property to false">
<message>Your name is required.</message>
<ns2:stackTrace>
<ns2:frame file="HelloWorld.java"
line="14" method="sayHelloWorld"/>
...
</ns2:stackTrace>
</ns2:exception>
</detail>
</S:Fault>
</S:Body>
</S:Envelope>
The thing is that in my code as you see, it doesn't show the "detail" tag. You guys know how to show this kind of information in the SOAP response?
public String myMethod(String field1, String field2) throws Throwable_Exception {
LOG.info("Executing operation myMethod");
try {
java.lang.String _return = "";
List<String> testExceptions = new ArrayList<>();
testExceptions.get(0);
return _return;
} catch (IndexOutOfBoundsException ex) {
throw new Throwable_Exception("TEST Custom Exception", ex.getCause());
}
//throw new Throwable_Exception("Throwable...");
}
In the impl class I've tried to force an IndexOutOfBoundsException as well and tried to use this constructor:
public Exception(String message, Throwable cause) {
super(message, cause);
}
and I thought that this approach could resolve the issue but apparently not.
Note: the WS is deployed on WildFly18.
CodePudding user response:
for everyone still looking for the answer I've understood that basically if you have an xsd schema, you have to define the complex type of your exception detail. For example:
<xs:complexType name="YourCustomException">
<xs:sequence>
<xs:element name="exName" type="xs:string" minOccurs="0"></xs:element>
<xs:element name="exMessage" type="xs:string" minOccurs="0"></xs:element>
<xs:element name="exDetails" type="xs:string" minOccurs="0"></xs:element>
</xs:sequence>
</xs:complexType>
in Java your going to have the class from this complexType and his exception class. In the exception class you have to bring an attribute of the complexType (if you generate the classes with CXF or some other tools everything is taken care of) and you have to figure your preferred way for instanciate the complexType in your customException so in the SOAP Fault the "detail" tag is populated.
Example of the CustomException in Java:
@WebFault(name = "YourCustomException", targetNamespace = "http://serviceendpoint/")
public class YourCustomException_Exception extends Exception {
private it.your.package.YourCustomException YourCustomException;
public YourCustomException_Exception() {
super();
}
public YourCustomException_Exception(String message) {
super(message);
}
public YourCustomException_Exception(String message, java.lang.Throwable cause) {
super(message);
this.YourCustomException = new YourCustomException();
this.YourCustomException.setExName(cause.getClass().getName());
this.YourCustomException.setExMessage(cause.getMessage());
this.YourCustomException.setExDetails(cause.getLocalizedMessage());
}
}
example of the ComplexType in Java:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "YourCustomException ", propOrder = {
"exName",
"exMessage",
"exDetails"
})
public class YourCustomException {
protected String exName;
protected String exMessage;
protected String exDetails;
public String getExName() {
return exName;
}
public void setExName(String exName) {
this.exName = exName;
}
public String getExMessage() {
return exMessage;
}
public void setExMessage(String exMessage) {
this.exMessage = exMessage;
}
public String getExDetails() {
return exDetails;
}
public void setExDetails(String exDetails) {
this.exDetails = exDetails;
}
}
SOAP Fault in the response forcing an IndexOutOfBounds in the method called:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Error in your method</faultstring>
<detail>
<ns2:YourCustomException xmlns:ns2="http://serviceendpoint/">
<exName>java.lang.IndexOutOfBoundsException</exName>
<exMessage>Index: 0, Size: 0</exMessage>
<exDetails>Index: 0, Size: 0</exDetails>
</ns2:YourCustomException >
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Hope this helps.