Hi, My comment inline ------------- Freeman(Yue) Fang
Red Hat, Inc. FuseSource is now part of Red Hat Web: http://fusesource.com | http://www.redhat.com/ Twitter: freemanfang Blog: http://freemanfang.blogspot.com http://blog.sina.com.cn/u/1473905042 weibo: http://weibo.com/u/1473905042 On 2012-10-17, at 上午10:21, iris ding wrote: > 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. > For a mapped exception the faultBean in @WebFault could be optional but you must have a getFaultInfo method in the mapped exception class which can return a faultBean. That said, have faultBean in @webFault or have a getFaultInfo method which can return a faultBean. > So the question is: > 1. Do we must implement getFaultInfo() and define the faultbean by ourself > to make it work? -- I will suppose NO You need define a faultBean class anyway which get marshaled/unmarshalled by jaxb > 2. If we let CXF generate the faultbean for you automatically, do we must > define faultBean in @WebFault annotation? Generate faultBean automatically may cause expected exception message lost. For accurately pass exception message onwire, I suggest you have a faultBean yourself. > 3. Or is there any pre-reqirement to use dynamicaally generated faultbeans > in CXF? Is my above work flow incorrect? Generally we recommend the wsdl first way, which means you needn't worry about the jaxws/jaxb annotation yourself, using code-first way is not that easy and you need ensure your code exactly follow the jax-ws spec. Normally when people use code-first way, they use simple frontend but not the jaws frontend. Btw, wsgen and wsimport are tools from jaxws reference implementation(metro) but not from CXF, though it's not a big deal in terms of functionality get involved here. Freeman > > 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.
