I am using @WebFault to throw custom exception.
The basic workflow I used is:
1. Create Servive and exception java code and compile them.
2. Invoke 'wsgen' to generate WSDL and related java classes.
3. Invoke 'wsimport' to generate related java classes.
4. Call Test to invoke the service and catch the custom exception.
In step 1, the code is as below:
package faultbean.iristest.server;
@javax.jws.WebService (serviceName="AddNumbers")
public class AddNumbers{
public String addNumbers(int arg0, int arg1) throws AddNumbersException
{
if(arg0 + arg1 <0){
throw new AddNumbersException("Sum is less than 0.");
}
return "Result = " + String.valueOf(arg0 + arg1);
}
package faultbean.iristest.server;
import javax.xml.ws.WebFault;
@WebFault()
public class AddNumbersException extends Exception {
private String message = null;
public AddNumbersException(){
}
public AddNumbersException(String message){
this.message = message;
}
public String getInfo(){
return message;
}
}
In step4, My test is:
package faultbean.iristest.test;
// verify the use of @WebFault() with all default values
public void testAddNumbersException(){
String actual = null;
try {
actual = invokeService(1,-2,"test1");
} catch (AddNumbersException_Exception e) {
System.out.println(e.getFaultInfo().getInfo());
}
}
But in step4, the 'Info' field in fautbean returend by e.getFaultInfo() is
always empty.
I have searched and found in
http://www.docjar.com/html/api/org/apache/cxf/jaxws/interceptors/WebFaultOutInterceptor.java.html
. It seems CXF must define @WebFault(faultBean="xxxx") to make the
dynamically generated faultbean be recognized.
private Object createFaultInfoBean(WebFault fault, Throwable cause) {
138 if (!StringUtils.isEmpty(fault.faultBean())) {
139 try {
140 Class<?> cls =
ClassLoaderUtils.loadClass(fault.faultBean(),
141
cause.getClass());
142 if (cls != null) {
143 Object ret = cls.newInstance();
144 //copy props
145 Method meth[] = cause.getClass().getMethods();
146 for (Method m : meth) {
147 if (m.getParameterTypes().length == 0
148 && (m.getName().startsWith("get")
149 || m.getName().startsWith("is"))) {
150 try {
151 String name;
152 if (m.getName().startsWith("get")) {
153 name = "set" +
m.getName().substring(3);
154 } else {
155 name = "set" +
m.getName().substring(2);
156 }
157 Method m2 = cls.getMethod(name,
m.getReturnType());
158 m2.invoke(ret, m.invoke(cause));
159 } catch (Exception e) {
160 //ignore
161 }
162 }
163 }
164 return ret;
165 }
166 } catch (ClassNotFoundException e1) {
167 //ignore
168 } catch (InstantiationException e) {
169 //ignore
170 } catch (IllegalAccessException e) {
171 //ignore
172 }
173 }
174
175 LOG.fine("Using @WebFault annotated class "
176 + cause.getClass().getName()
177 + " as faultInfo since getFaultInfo() was not
found");
178 return cause;
179 }
Per jax-ws spec, we can leave this alone to let the jax-ws runtime generate
the faultbean for you automatically and faultBean is optional in @WebFault
annotation.
So the question is:
1. Do we must implement getFaultInfo() and define the faultbean by ourself
to make it work? -- I will suppose NO
2. If we let CXF generate the faultbean for you automatically, do we must
define faultBean in @WebFault annotation?
3. Or is there any pre-reqirement to use dynamicaally generated faultbeans
in CXF? Is my above work flow incorrect?
Thanks a lot!
--
View this message in context:
http://cxf.547215.n5.nabble.com/Webfault-tp5716784.html
Sent from the cxf-user mailing list archive at Nabble.com.