WebService服务发布往往比较混乱,Axis2的发布形式与XFire发布方式差别很大,而Java6 Web服务的发布与Axis2、XFire的Web服务的发布方式也有着天壤之别,它们之间没有经验可以借鉴。
因此,很有必要钻研下Java6的Web服务的发布方式。
从前面两篇文章可以看出Java6对WebService的发布提供了API级别的直接支持,发布只需要一行代码就搞定了。但是作为一个服务,就需要启动,总不能每次启动都去运行一个Main方法来启动吧。
实际中Web服务的发布常常伴随着Web容器的启动而发布,而在Java6中,我们没法直接像Axis2和XFire那样直接去发布,但是可以通过变通的方法,通过Servlet来和容器绑定起来,在容器启动的时候发布服务。
下面以Tomcat为例,来实现Java6 Web服务的发布。
1、开发WebService服务
package com.mediacross.adnetwork.base.webservice;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;
import com.mediacross.adnetwork.base.service.RoleService;
@WebService
public class MessageService extends SpringBeanAutowiringSupport {
@Autowired
private RoleService roleService;
public String getReportData(String data) {
String returnData = "";
if(roleService==null){
return "aasdf";
}
try {
String[] dataStrs = data.split("&");
for (int i = 0; i < dataStrs.length; i++) {
returnData = returnData + "," + dataStrs[i].split("#")[0];
}
returnData = returnData.substring(1);
} catch (Exception e) {
returnData = "";
}
return returnData;
}
public String getMoData(String info) {
String returnData = "";
try {
String[] infoStrs = info.split("&");
for (int i = 0; i < infoStrs.length; i++) {
returnData = returnData + "," + infoStrs[i].split("#")[0];
}
returnData = returnData.substring(1);
} catch (Exception e) {
returnData = "";
}
return returnData;
}
}
2、开发发布服务的Servlet,为了通用性,最好选择GenericServlet来继承
package com.mediacross.adnetwork.base.servlet;
import java.io.IOException;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.xml.ws.Endpoint;
import com.mediacross.adnetwork.base.webservice.MessageService;
public class WSServlet extends GenericServlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
System.out.println("准备启动WebService服务:http://192.168.1.8:8080/adnetwork/com.mediacross.adnetwork.base.webservice.MessageService");
//发布一个WebService
Endpoint.publish("http://192.168.1.8:8000/adnetwork/com.mediacross.adnetwork.base.webservice.MessageService", new MessageService());
System.out.println("已成功启动WebService服务:http://192.168.1.8:8080/adnetwork/com.mediacross.adnetwork.base.webservice.MessageService");
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
System.out.println("此Servlet不处理任何业务逻辑,仅仅yonglai发布一个Web服务:http://192.168.14.117:8888/java6ws/Java6WS");
}
}
3、配置web.xml
<servlet>
<servlet-name>WSServlet</servlet-name>
<servlet-class>com.mediacross.adnetwork.base.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WSServlet</servlet-name>
<url-pattern>/servlet/WSServlet</url-pattern>
</servlet-mapping>
注意,上面的Servlet比一般Servlet配置多了一行:
<load-on-startup>1</load-on-startup>
,这样写的目的是Servlet能伴随容易的启动在第一时间加载。以便服务能尽可能早的发布,否则,只有在第一次请求该Servlet的时候,才会被加载到容器。
4、部署、启动并测试
http://192.168.1.8:8000/adnetwork/com.mediacross.adnetwork.base.webservice.MessageService?wsdl
可见,服务伴随着tomcat的启动发布成功。
5、总结
1)、Java6的服务发布的总体思想是通过Java6 API的调用达到发布的目的,截止目前,已经看到两种发布方式,一种是直接调用API:
Endpoint.publish("http://192.168.1.8:8000/adnetwork/com.mediacross.adnetwork.base.webservice.MessageService", new MessageService())
另一种是,本例中Servlet方式。
2)、Endpoint.publish是一个后台线程,一旦发布了就会一直等待处理Web服务的请求,只有当main方法退出,或者容器关闭的时候,才自动退出。
3)、其实除了这种方式,也可以整合Spring来实现服务的发布,这就和Spring的Ioc容器整合在一起了。不管什么,道理就一个,调用Endpoint.publish()方法来实现服务的发布。
4)、在发布服务的时候,应该避免使用Tomcat容器的端口,一面发生冲突,在本文中,Tomcat使用的端口是8080,而Web服务发布使用的端口是8888。