转自:http://blog.csdn.net/neareast?viewmode=contents
项目中要使用webService了;今天上午直接上官网学习CXF,本文来源于对官方文档A simple JAX-WS service的翻译与实践,针对最新的cxf-2.6.1版本调整了所依赖的jar包,并在代码中补全了原文没有提到的一些类;边学边记录,谨防遗忘,顺便分享。
本例与cxf-2.6.1发行版中的示例 java_first_jaxws 相对应,适用于CXF 2.0.1及以上版本。
本文也附上了笔者代码的下载地址,欢迎下载;工程中不包含所引用的jar包,使用者参照文中的截图建立相应的user Library即可使用:
http://download.csdn.net/detail/neareast/4410086
搭建环境
commons-logging-1.1.1.jar
geronimo-activation_1.1_spec-1.0.2.jar (or Sun's Activation jar)
geronimo-annotation_1.0_spec-1.1.1.jar (JSR 250)
geronimo-javamail_1.4_spec-1.6.jar (or Sun's JavaMail jar)
geronimo-servlet_2.5_spec-1.2.jar (or Sun's Servlet jar)
geronimo-ws-metadata_2.0_spec-1.1.2.jar (JSR 181)
geronimo-jaxws_2.1_spec-1.0.jar (or Sun's jaxws-api-2.1.jar)
geronimo-stax-api_1.0_spec-1.0.1.jar (or other stax-api jar)
jaxb-api-2.1.jar
jaxb-impl-2.1.12.jar
jetty-6.1.21.jar
jetty-util-6.1.21.jar
neethi-2.0.4.jar
saaj-api-1.3.jar
saaj-impl-1.3.2.jar
wsdl4j-1.6.2.jar
wstx-asl-3.2.8.jar
XmlSchema-1.4.5.jar
xml-resolver-1.2.jar
spring的包(可选,需要使用XML配置支持时引入):
aopalliance-1.0.jar
spring-core-2.5.5.jar
spring-beans-2.5.5.jar
spring-context-2.5.5.jar
spring-web-2.5.5.jar
当然,还有最重要的,CXF的包:
cxf-2.2.3.jar
- package com.neareast.test.cxf.service;
- import java.util.Map;
- import javax.jws.WebParam;
- import javax.jws.WebService;
- import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
- import com.neareast.test.cxf.bean.User;
- import com.neareast.test.cxf.util.IntegerUserMapAdapter;
- @WebService
- public interface iHelloWorld {
- //加入WebParam注解,以保证xml文件中参数名字的正确性
- String sayHi(@WebParam(name="text") String text);
- /* Advanced usecase of passing an Interface in. JAX-WS/JAXB does not
- * support interfaces directly. Special XmlAdapter classes need to
- * be written to handle them
- */
- String sayHiToUser(User user);
- /* Map passing
- * JAXB also does not support Maps. It handles Lists great, but Maps are
- * not supported directly. They also require use of a XmlAdapter to map
- * the maps into beans that JAXB can use.
- */
- @XmlJavaTypeAdapter(IntegerUserMapAdapter.class)
- Map<Integer, User> getUsers();
- }
package com.neareast.test.cxf.service;
import java.util.Map;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import com.neareast.test.cxf.bean.User;
import com.neareast.test.cxf.util.IntegerUserMapAdapter;
@WebService
public interface iHelloWorld {
//加入WebParam注解,以保证xml文件中参数名字的正确性
String sayHi(@WebParam(name="text") String text);
/* Advanced usecase of passing an Interface in. JAX-WS/JAXB does not
* support interfaces directly. Special XmlAdapter classes need to
* be written to handle them
*/
String sayHiToUser(User user);
/* Map passing
* JAXB also does not support Maps. It handles Lists great, but Maps are
* not supported directly. They also require use of a XmlAdapter to map
* the maps into beans that JAXB can use.
*/
@XmlJavaTypeAdapter(IntegerUserMapAdapter.class)
Map<Integer, User> getUsers();
}
- package com.neareast.test.cxf.service;
- import java.util.LinkedHashMap;
- import java.util.Map;
- import javax.jws.WebService;
- import com.neareast.test.cxf.bean.User;
- @WebService(endpointInterface = "com.neareast.test.cxf.service.iHelloWorld", serviceName = "HelloWorld")
- public class HelloWorldImpl implements iHelloWorld {
- Map<Integer, User> users = new LinkedHashMap<Integer, User>();
- public String sayHi(String text) {
- System.out.println("sayHi called");
- return "Hello " + text;
- }
- public String sayHiToUser(User user) {
- System.out.println("sayHiToUser called");
- users.put(users.size() + 1, user);
- return "Hello " + user.getName();
- }
- public Map<Integer, User> getUsers() {
- System.out.println("getUsers called");
- return users;
- }
- }
package com.neareast.test.cxf.service;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.jws.WebService;
import com.neareast.test.cxf.bean.User;
@WebService(endpointInterface = "com.neareast.test.cxf.service.iHelloWorld", serviceName = "HelloWorld")
public class HelloWorldImpl implements iHelloWorld {
Map<Integer, User> users = new LinkedHashMap<Integer, User>();
public String sayHi(String text) {
System.out.println("sayHi called");
return "Hello " + text;
}
public String sayHiToUser(User user) {
System.out.println("sayHiToUser called");
users.put(users.size() + 1, user);
return "Hello " + user.getName();
}
public Map<Integer, User> getUsers() {
System.out.println("getUsers called");
return users;
}
}
@WebService注解让CXF知道我们希望使用哪个接口来创建WSDL,本例中就是iHelloWorld接口。
发布服务
- package com.neareast.test.cxf.service;
- import javax.xml.ws.Endpoint;
- public class ServiceTest {
- protected ServiceTest() throws Exception {
- // START SNIPPET: publish
- System.out.println("Starting Server");
- HelloWorldImpl implementor = new HelloWorldImpl();
- String address = "http://localhost:9000/helloWorld";
- Endpoint.publish(address, implementor);
- // END SNIPPET: publish
- }
- public static void main(String args[]) throws Exception {
- new ServiceTest();
- System.out.println("Server ready...");
- Thread.sleep(5 * 60 * 1000);
- System.out.println("Server exiting");
- System.exit(0);
- }
- }
package com.neareast.test.cxf.service;
import javax.xml.ws.Endpoint;
public class ServiceTest {
protected ServiceTest() throws Exception {
// START SNIPPET: publish
System.out.println("Starting Server");
HelloWorldImpl implementor = new HelloWorldImpl();
String address = "http://localhost:9000/helloWorld";
Endpoint.publish(address, implementor);
// END SNIPPET: publish
}
public static void main(String args[]) throws Exception {
new ServiceTest();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
第一次直接运行的时候,程序报错:
Exception in thread "main" javax.xml.ws.WebServiceException: javax.xml.ws.WebServiceException: Could not load Webservice SEI
检查代码发现,是HelloWorldImpl类的@WebService注解写错了,endpointInterface属性的值没有写对;改成正确的接口路径之后,程序运行就OK了。
service程序启动之后,用浏览器访问 http://localhost:9000/helloWorld?wsdl ,如果能够看到类似下图所示的XML文件,就说明我们的第一个webservice已经创建成功了!