2016-03-22 17 views
7

私はというウェブサービスをtomcatに公開したいと思います。
JAX-WSまたはApache CXFの場合
Endpoint.publish(...)に似ています。webserviceをtomcatにプログラムで公開するには

質問web.xmlおよび/またはsun-jaxws.xml(各サービスの)を使用することなく、

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


はそれを達成するために、任意の既知の方法はあります(JAX-WSまたはApache CXFかと。 ..)?

(私はすでに掲載同様の質問があることを知っている。しかし、それらのどれもが本当に私の質問に答えるません。)

+0

私はあなたの要件をよく分かりません。要求を受け取るためにプログラムでエンドポイントを公開するtomcat(web.xmlが必要なので)にアプリケーションをデプロイしたいとします。それが正しいか? – pedrofb

+0

Tomcatマネージャのweb-appを使用して、(正しいURLを呼び出して)新しいWebアプリケーションをデプロイすることができます(https://tomcat.apache.org/tomcat-6.0-doc/manager-howto.html#Deploy_A_New_Application_from_a_Local_Path) – Maxx

答えて

1

これは私自身の質問にanwerです。
私はApache CXFの助けを借りてを[がwebcatをプログラムで公開する]ことができました。ここで

が簡略化作業例です:

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

上記のサーブレットをします2つの簡単なインターフェイスをSOAP-WebServiceとして公開します。
実装は動的である(プロキシ)

これは私のMyServiceInterceptorです:MyServiceInterceptor-Classは、主MyWebServiceInvocationHandlerに現在SOAPMessageのを注入するために使用される

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


私のMyWebServiceInvocationHandler(ここではコードは必要ありません)は、実際のサービスメソッドを呼び出す責任があります。これは単にInvocationHandlerを実装し、Soap-Messageのフィールドを持っています(MyServiceInterceptor参照)。これは、SOAPMessage-Details(ヘッダなど)を取得するために必要です。

これが役に立ちます。
乾杯!

関連する問題