java – 如何以编程方式将webservice发布到tomcat

前端之家收集整理的这篇文章主要介绍了java – 如何以编程方式将webservice发布到tomcat前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想以编程方式向tomcat发布web服务.
例如JAX-WS或Apache CXF
与Endpoint.publish(…)类似.
  1. //how to tell this tomcat?
  2. Endpoint.publish("http://0.0.0.0:8080/SimpleService",serviceImpl);
  3. //or better something like this:
  4. Endpoint.publish("/SimpleService",serviceImpl);

无需使用web.xml和/或sun-jaxws.xml(对于每个服务)

题:
有没有任何已知的方法来实现它(使用JAX-WS或Apache CXF或……)?

(我知道已经发布了类似的问题.但是他们都没有回答我的问题.)

解决方法

这是我自己的问题.
我设法在Apache CXF的帮助下[以编程方式将webservice发布到tomcat].

这是一个简化的工作示例:

我将一个CXFNonSpringServlet子类化并在web.xml中注册

  1. <servlet>
  2. <servlet-name>MyCXFServlet</servlet-name>
  3. <display-name>CXF Servlet</display-name>
  4. <servlet-class>de.test.MyCXFServlet</servlet-class>
  5. <load-on-startup>2</load-on-startup>
  6. <async-supported>true</async-supported>
  7. </servlet>
  8.  
  9. <servlet-mapping>
  10. <servlet-name>MyCXFServlet</servlet-name>
  11. <url-pattern>/soap/*</url-pattern>
  12. </servlet-mapping>

这是我的子类CXFNonSpringServlet:

  1. import java.lang.reflect.Method;
  2. import java.lang.reflect.Proxy;
  3. import java.util.HashSet;
  4. import java.util.Set;
  5. import javax.jws.WebMethod;
  6. import javax.servlet.ServletConfig;
  7. import org.apache.cxf.endpoint.Server;
  8. import org.apache.cxf.frontend.Serverfactorybean;
  9. import org.apache.cxf.service.factory.ReflectionServicefactorybean;
  10. import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
  11.  
  12. public class MyCXFServlet extends CXFNonSpringServlet
  13. {
  14. @Override
  15. protected void loadBus(ServletConfig sc)
  16. {
  17. super.loadBus(sc);
  18. publishServices();
  19. }
  20.  
  21. private void publishServices()
  22. {
  23. Set<Class> serviceInterfaces = new HashSet<>();
  24. serviceInterfaces.add(de.test.IUserService.class);
  25. serviceInterfaces.add(de.test.ILoginService.class);
  26.  
  27. for (Class aSVCInterface : serviceInterfaces)
  28. {
  29. final String serviceName = aSVCInterface.getSimpleName();
  30.  
  31. try
  32. {
  33. ReflectionServicefactorybean reflectionFactory = new ReflectionServicefactorybean(){
  34. @Override
  35. protected boolean isValidMethod(Method method)
  36. {
  37. boolean ret = super.isValidMethod(method);
  38. WebMethod wm = method.getAnnotation(WebMethod.class);
  39. if (wm != null && wm.exclude())
  40. ret = false;
  41. return ret;
  42. }
  43.  
  44. @Override
  45. protected String getServiceName() //Override for custom service name
  46. {
  47. return serviceName;
  48. }
  49.  
  50. };
  51. reflectionFactory.setServiceClass(aSVCInterface);
  52.  
  53. Object proxiedServiceObject = Proxy.newProxyInstance(this.getClass().getClassLoader(),new Class[]{aSVCInterface},new de.test.MyWebServiceInvocationHandler(aSVCInterface));
  54.  
  55. Serverfactorybean factory = new Serverfactorybean(reflectionFactory);
  56. factory.setBus(getBus());
  57. factory.setServiceClass(aSVCInterface);
  58. factory.setServiceBean(proxiedServiceObject);
  59. factory.setAddress("/" + serviceName);
  60. Server svr = factory.create();
  61. svr.getEndpoint().getInInterceptors().add(new de.test.MyServiceInterceptor());
  62. }
  63. catch (Exception exception)
  64. {
  65. exception.printStackTrace();
  66. }
  67. }
  68. }
  69. }

上面的Servlet将发布2个简单的接口作为SOAP-WebService.
实现是动态的(代理)

这是我的MyServiceInterceptor:

  1. import java.lang.reflect.InvocationHandler;
  2. import java.lang.reflect.Proxy;
  3. import org.apache.cxf.binding.soap.SoapMessage;
  4. import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
  5. import org.apache.cxf.endpoint.Endpoint;
  6. import org.apache.cxf.interceptor.Fault;
  7. import org.apache.cxf.message.Exchange;
  8. import org.apache.cxf.phase.Phase;
  9. import org.apache.cxf.service.Service;
  10. import org.apache.cxf.service.invoker.BeanInvoker;
  11. import org.apache.cxf.service.invoker.Invoker;
  12.  
  13. public class MyServiceInterceptor extends AbstractSoapInterceptor
  14. {
  15. public MyServiceInterceptor()
  16. {
  17. super(Phase.PRE_INVOKE);
  18. }
  19.  
  20. @Override
  21. public void handleMessage(SoapMessage p_message) throws Fault
  22. {
  23. final Exchange exchange = p_message.getExchange();
  24. final Endpoint endpoint = exchange.get(Endpoint.class);
  25. final Service service = endpoint.getService();
  26. final Invoker invoker = service.getInvoker();
  27.  
  28. if (invoker instanceof BeanInvoker)
  29. {
  30. BeanInvoker bi = (BeanInvoker)invoker;
  31. Object serviceObj = bi.getServiceObject(null);
  32. if (Proxy.isProxyClass(serviceObj.getClass()))
  33. {
  34. InvocationHandler ih = Proxy.getInvocationHandler(serviceObj);
  35. if (ih instanceof MyWebServiceInvocationHandler)
  36. {
  37. MyWebServiceInvocationHandler h = (MyWebServiceInvocationHandler)ih;
  38. h.setSoapMessage(p_message);
  39. }
  40. }
  41. }
  42. }
  43. }

MyServiceInterceptor-Class主要用于将当前SOAPMessage注入MyWebServiceInvocationHandler.

我的MyWebServiceInvocationHandler(我认为,这里不需要代码)负责调用真正的Service-Method.它只是实现了InvocationHandler并且有一个Soap-Message字段(参见MyServiceInterceptor).这是获取SOAPMessage-Details(如Header)所必需的.

希望这可以帮助.干杯!

猜你在找的Java相关文章