java – 如何以编程方式将webservice发布到tomcat
我想以编程方式向tomcat发布web服务.
例如JAX-WS或Apache CXF 与Endpoint.publish(…)类似. //how to tell this tomcat? Endpoint.publish("http://0.0.0.0:8080/SimpleService",serviceImpl); //or better something like this: Endpoint.publish("/SimpleService",serviceImpl); 无需使用web.xml和/或sun-jaxws.xml(对于每个服务) 题: (我知道已经发布了类似的问题.但是他们都没有回答我的问题.) 解决方法
这是我自己的问题.
我设法在Apache CXF的帮助下[以编程方式将webservice发布到tomcat]. 这是一个简化的工作示例: 我将一个CXFNonSpringServlet子类化并在web.xml中注册: <servlet> <servlet-name>MyCXFServlet</servlet-name> <display-name>CXF Servlet</display-name> <servlet-class>de.test.MyCXFServlet</servlet-class> <load-on-startup>2</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>MyCXFServlet</servlet-name> <url-pattern>/soap/*</url-pattern> </servlet-mapping> 这是我的子类CXFNonSpringServlet: import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashSet; import java.util.Set; import javax.jws.WebMethod; import javax.servlet.ServletConfig; import org.apache.cxf.endpoint.Server; import org.apache.cxf.frontend.ServerFactoryBean; import org.apache.cxf.service.factory.ReflectionServiceFactoryBean; import org.apache.cxf.transport.servlet.CXFNonSpringServlet; public class MyCXFServlet extends CXFNonSpringServlet { @Override protected void loadBus(ServletConfig sc) { super.loadBus(sc); publishServices(); } private void publishServices() { Set<Class> serviceInterfaces = new HashSet<>(); serviceInterfaces.add(de.test.IUserService.class); serviceInterfaces.add(de.test.ILoginService.class); for (Class aSVCInterface : serviceInterfaces) { final String serviceName = aSVCInterface.getSimpleName(); try { ReflectionServiceFactoryBean reflectionFactory = new ReflectionServiceFactoryBean(){ @Override protected boolean isValidMethod(Method method) { boolean ret = super.isValidMethod(method); WebMethod wm = method.getAnnotation(WebMethod.class); if (wm != null && wm.exclude()) ret = false; return ret; } @Override protected String getServiceName() //Override for custom service name { return serviceName; } }; reflectionFactory.setServiceClass(aSVCInterface); Object proxiedServiceObject = Proxy.newProxyInstance(this.getClass().getClassLoader(),new Class[]{aSVCInterface},new de.test.MyWebServiceInvocationHandler(aSVCInterface)); ServerFactoryBean factory = new ServerFactoryBean(reflectionFactory); factory.setBus(getBus()); factory.setServiceClass(aSVCInterface); factory.setServiceBean(proxiedServiceObject); factory.setAddress("/" + serviceName); Server svr = factory.create(); svr.getEndpoint().getInInterceptors().add(new de.test.MyServiceInterceptor()); } catch (Exception exception) { exception.printStackTrace(); } } } } 上面的Servlet将发布2个简单的接口作为SOAP-WebService. 这是我的MyServiceInterceptor: import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Exchange; import org.apache.cxf.phase.Phase; import org.apache.cxf.service.Service; import org.apache.cxf.service.invoker.BeanInvoker; import org.apache.cxf.service.invoker.Invoker; public class MyServiceInterceptor extends AbstractSoapInterceptor { public MyServiceInterceptor() { super(Phase.PRE_INVOKE); } @Override public void handleMessage(SoapMessage p_message) throws Fault { final Exchange exchange = p_message.getExchange(); final Endpoint endpoint = exchange.get(Endpoint.class); final Service service = endpoint.getService(); final Invoker invoker = service.getInvoker(); if (invoker instanceof BeanInvoker) { BeanInvoker bi = (BeanInvoker)invoker; Object serviceObj = bi.getServiceObject(null); if (Proxy.isProxyClass(serviceObj.getClass())) { InvocationHandler ih = Proxy.getInvocationHandler(serviceObj); if (ih instanceof MyWebServiceInvocationHandler) { MyWebServiceInvocationHandler h = (MyWebServiceInvocationHandler)ih; h.setSoapMessage(p_message); } } } } } MyServiceInterceptor-Class主要用于将当前SOAPMessage注入MyWebServiceInvocationHandler. 我的MyWebServiceInvocationHandler(我认为,这里不需要代码)负责调用真正的Service-Method.它只是实现了InvocationHandler并且有一个Soap-Message字段(参见MyServiceInterceptor).这是获取SOAPMessage-Details(如Header)所必需的. 希望这可以帮助.干杯! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |