2016-03-22 24 views
7

Tomcat için bir web hizmetini program aracılığıyla yayımlamak istiyorum.
JAX-WS veya Apache CXF
ile Endpoint.publish(...)'a benzer.Web hizmetini tomcat'e program aracılığıyla yayınlama

Soru web.xml ve/veya sun-jaxws.xml (her bir hizmet için) kullanmaya gerek olmadan

//how to tell this tomcat? 
Endpoint.publish("http://0.0.0.0:8080/SimpleService", serviceImpl); 
//or better something like this: 
Endpoint.publish("/SimpleService", serviceImpl); 

:
bunu başarmak için bilinen herhangi bir yolu var mı (JAX-WS veya Apache CXF veya. ..)?

(Zaten yayınlanan benzer sorular olduğunu biliyoruz. Fakat bunların hiçbiri, sorumu cevaplar.)

+0

Gereksinimlerinizden emin değilim. Bir uygulamayı, istekleri almak için programlı olarak yeni bir son nokta yayınlayan tomcat'e (web.xml'ye ihtiyacınız var) dağıtmak istiyorsunuz. Doğru mu? – pedrofb

+0

Tomcat yöneticisi web uygulaması yeni bir web uygulaması dağıtmak için kullanılabilir (doğru URL'yi arayarak) (https://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html#Deploy_A_New_Application_from_a_Local_Path) – Maxx

cevap

1

Bu benim kendi soruya bir anwer olduğunu.
Bu işi yapmayı başardım [Apache CXF'nin yardımıyla webservice'i tomcat'a program aracılığıyla yayınla].

Ben CXFNonSpringServlet sınıflandırma ve web.xml bunu tescil: Bu benim CXFNonSpringServlet sınıflandırma edilir

<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> 

:

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(); 
      } 
     } 
    } 
} 

yukarıdaki Servlet edecek İşte


basitleştirilmiş çalışma örneğidir SOAP-WebService olarak 2 basit arayüz yayınlamak.
uygulama dinamik olduğunu (Proxy)

Bu benim MyServiceInterceptor geçerli: MyServiceInterceptor sınıfı esas MyWebServiceInvocationHandler geçerli SOAPMessage enjekte etmekte kullanılan

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); 
       } 
      } 
     } 
    } 
} 

. Gerçek Hizmet Yöntemi'ni çağırmaktan sorumluyuz (buradaki hiçbir kodun gerekmediğini düşünüyorum), benim MyWebServiceInvocationHandler (bence burada kod gerekmez) sorumludur. Sadece InvocationHandler'u uygular ve Sabun Mesajı için bir alana sahiptir (bkz. MyServiceInterceptor). Bu SOAPMessage-Details (Header gibi) almak için gereklidir.

Bu yardımcı olur umarım.
Şerefe!

İlgili konular