1:使用ServerFactoryBean发布服务: 使用CXF发布一个服务,与JDK6发布一个服务完全不同 * 即使是不使用@WebService注解,一样可以发布成功 * 即使此类没有对外公布的方法一样可以发布成功
使用CXF发布一个服务,与JDK6发布一个服务完全不同
* 即使是不使用@WebService注解,一样可以发布成功
* 即使此类没有对外公布的方法一样可以发布成功
代码示例:
package cn.itcast.ws; import org.apache.cxf.frontend.ServerFactoryBean; public class HiServiceImpl1 { public String sayHi(String name) { return "hi: " + name; } public static void main(String[] args) { //声明实例 ServerFactoryBean bean = new ServerFactoryBean(); //绑定到发布地址的端口 bean.setAddress("http://localhost:8888/hi"); //设置服务接口,若没有,则为本类ࣩ bean.setServiceClass(HiServiceImpl1.class); //设置接口实现类,即服务类 bean.setServiceBean(new HiServiceImpl1()); //发布服务 bean.create(); System.out.println("发布成功"); } }
2:使用JaxWsServerFactoryBean发布服务:
*JaxWsServerFactoryBean是ServerFactoryBean的子类,也是功能扩展类。
* 此类,必须要在被发布为服务的类上添加@WebService注解,如果不加注解,虽然不出错,但也不会对外暴露任何方法
* 使用此类生成的wsdl文件更加规范。
代码示例:
package cn.itcast.ws; import javax.jws.WebService; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; @WebService public class HiServiceImpl2 { public String sayHi(String name) { return "hi: " + name; } public static void main(String[] args) { JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean(); //绑定到发布地址的端口 bean.setAddress("http://localhost:8888/hi"); //设置服务接口,若没有,则为本类ࣩ bean.setServiceClass(HiServiceImpl2.class); //设置接口实现类,即服务类 bean.setServiceBean(new HiServiceImpl2()); //发布服务 bean.create(); System.out.println("发布成功"); } }
附,使用接口和及其实现类来发布WebService服务 接口类:
package cn.itcast.ws; import javax.jws.WebService; @WebService public interface HiService { public String sayHi(String name); }实现类:
package cn.itcast.ws; public class HiServiceImpl implements HiService{ public String sayHi(String name) { return "hi: " + name; } }服务发布类:
package cn.itcast.ws; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; public class Server { public static void main(String[] args) { JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean(); //绑定到发布地址的端口 bean.setAddress("http://localhost:8888/hi"); //设置服务接口,若没有,则为本类ࣩ bean.setServiceClass(HiService.class); //设置接口实现类,即服务类 bean.setServiceBean(new HiServiceImpl()); //发布服务 bean.create(); System.out.println("发布成功"); } }
使用ClientProxyFactoryBean客户端调用:
package cn.itcast.ws; import org.apache.cxf.frontend.ClientProxyFactoryBean; /** * 1.使用ServerFactoryBean发布服务以后,在没有接口的情况下, * 可以使用wsimport生成的客户端代码调用成功。 * * 2.但如果要使用ClientProxyFactoryBean客户端去调用服务器,则必须要先在服务器端创建一个接口。 * (一直以来,Spring都要求面向接口编程,而cxf与Spring能很好的整合,也就在此。), * 所以,必须要重写服务器端的代码。这将导致刚才使用wsimport生成的调用代码失效。 * * 3.如果在其他项目中调用,仍然需wsimport生成的类,但只需要一个接口。 * @author pengdi * */ public class Client { public static void main(String[] args) { //创建客户端类 ClientProxyFactoryBean bean = new ClientProxyFactoryBean(); //设置访问地址 bean.setAddress("http://localhost:8888/hi"); /* * 1.若服务接口在同一项目中,直接使用本项目中的接口类HiService * 2.若在不同项目中调用,则类HiService是用wsimport生成且修改过的 */ bean.setServiceClass(HiService.class); //通过create方法返回接口实例 HiService hs = (HiService)bean.create(); String str = hs.sayHi("hahah"); System.out.println(str); } }上述服务发布类都能够成功执行发布,但是最后使用 ClientProxyFactoryBean客户端调用时报如下错误:
四月 25, 2017 10:52:15 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean checkServiceClassAnnotations
警告: A JAX-WS Annotation was found on cn.itcast.ws.HiService while using the Simple frontend. For better results, use the JAX-WS frontend.
四月 25, 2017 10:52:15 下午 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://ws.itcast.cn/}HiService from class cn.itcast.ws.HiService
Exception in thread "main" org.apache.cxf.binding.soap.SoapFault: Unmarshalling Error: 意外的元素 (uri:"http://ws.itcast.cn/", local:"arg0")。所需元素为<{}name>
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:86)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:52)
at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:41)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:112)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:801)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1680)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1559)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1356)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:653)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:324)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:277)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.frontend.ClientProxy.invoke(ClientProxy.java:81)
at com.sun.proxy.$Proxy24.sayHi(Unknown Source)
at cn.itcast.ws.Client.main(Client.java:29)
很是不解,希望看到的各位也能看看,明个再找找解决方案吧。