7

SOAP サービスと REST サービスが、アプリケーション サーバーの外部で Jersey (Grizzly) を使用して同じポートを共有できるように構成する方法を知っている人はいますか?

  • 私の石鹸サービスは www.someurl.com:port/soap/crm にあります
  • 私の残りのサービスは www.someurl.com:port/crm にあります

これらのサービスは同じポートを共有しますが、同じベース URL ではないため、そのポートで並行して実行できるはずです。ただし、ポートバインドエラーがあります..

これらはすべてカスタム サービス アプリケーションにあり、web.xml などはありません。

REST サービスは Jersey を使用しており、Soap サービスはエンドポイントで公開されたクラス 'ReceptionService' です。

URI soapUri = URI.create("192.168.0.0:1234\soap\Crm")
URI restUri = URI.create("192.168.0.0:1234\crm")

// START SOAP SERVICE
Object reception = getObjectResource(ReceptionService.class);
Endpoint e = Endpoint.publish(soapUri, reception);

// START REST SERVICE    
ResourceConfig rc = new ResourceConfig().packages("company.rest");
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(restUri, rc);

これを試してみると、Grizzly は「java.net.BindException: Address already in use: bind」を吐き出します。

私の石鹸サービスの受付は次のように設定されています。

    @WebService(targetNamespace = "company.crm")
    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL,      parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
    public class Reception implements ReceptionService {
     ... methods
    }

私の残りのサービスクラスは、いつものように注釈が付けられています...

@Path("hello/{username}")
public class Hello { ... }

私はこれについて少し初心者であり、どんな指針もいただければ幸いです。そして、私がアプリケーション サーバーを実行していることをわざわざ提案しないでください。それはここでは問題ではありません。問題は、他の Web サービス フレームワークに移行せずにポート バインドの問題を回避するにはどうすればよいかということです。

報奨金に関する注意: これを十分に繰り返すことはできません

「バウンティの勝者は、Jersey for REST と Java SOAP サービス (注釈付き JAX-WS) を同じエンドポイントで一緒に使用する方法を示します。答えは、Rest および Soap 注釈付きクラスへの変更を必要としません。しかし、HTTP サーバーコードの変更またはそれを機能させるための構成変更は許容されます。Jetty またはその他のアプリケーション サーバーへの切り替えは許容されません。ソリューションは 100% 組み込まれ、Java SE および Java Web サービス ライブラリを使用して実行される必要があります。」

4

5 に答える 5

3

あなたが言っているのは、サービスを公開するための2つの異なるインターフェースに他なりません。はい、それらを単一のポートでホストして、同じコンテナーにデプロイするだけで、両方のインターフェースを稼働させることができます。

上記の質問で言及した URL では発生していないように見える、コンテキスト パスの競合がないことを確認してください。

たとえば、残りのインターフェイスを次のようにデプロイします。

www.someurl.com:port2/crm であるため、soap は同じ URL www.someurl.com:port1/soap/crm にデプロイしないでください。これは問題ありません。

また、インターフェイスを個別の war ファイルとして、または単一の war ファイルとして展開する方法についても少し説明する必要があります。

于 2013-07-15T06:26:04.877 に答える
2

Web サービスに tomcat などの一般的なコンテナーを使用している場合は、同じポートに到着する両方のサービスの要求を取得できます。アプリケーションの一部として、REST ベースと SOAP ベースのサービスの両方をデプロイできます。コンテナーは着信要求を受け入れ、アプリケーションのコンテキストに応じてそれらをアプリケーションに転送します。アプリケーション web.xml では、リクエスト URL マッピングに応じてリクエストの送信先を構成できます。

于 2013-07-15T06:17:16.583 に答える
2

同じポートで複数のサービスを開始することはできません。

同じポートを介してアプリにアクセスできるようにする場合は、アプリケーション サーバーを使用する必要があります。

サーバー上の両方のアプリに異なる URL (web.xml) でアクセスできるように注意する必要があります。

同じ Application Server 上のすべてのアプリケーションが、同じポート経由でアクセスできるようになりました。

于 2013-07-23T14:39:35.680 に答える
0

これは、1 つのポート (2 つの異なるコンテキスト パス) で REST サービスと SOAP サービスの両方をホストするために使用するコードのほとんどであり、アプリに完全に埋め込まれ (明らかに Grizzly を使用)、Spring で構成されています...

package com.mycompany.structure.web.grizzly;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.BindException;
import java.util.EnumSet;
import java.util.LinkedList;
import javax.servlet.DispatcherType;
import javax.servlet.Servlet;
import com.mycompany.structure.web.jersey.jackson.JsonResourceConfig;
import com.mycompany.structure.web.jersey.spring.ExposedApplicationContext;
import org.glassfish.grizzly.http.server.HttpHandler;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.NetworkListener;
import org.glassfish.grizzly.jaxws.JaxwsHandler;
import org.glassfish.grizzly.servlet.WebappContext;
import org.glassfish.jersey.servlet.ServletContainer;
import org.smallmind.nutsnbolts.lang.web.PerApplicationContextFilter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

public class GrizzlyInitializingBean implements DisposableBean, ApplicationContextAware, ApplicationListener, BeanPostProcessor {

  private static final Class[] NO_ARG_SIGNATURE = new Class[0];
  private HttpServer httpServer;
  private LinkedList<WebService> serviceList = new LinkedList<>();
  private ServletInstaller[] servletInstallers;
  private String host;
  private String contextPath;
  private String restPath;
  private String soapPath;
  private int port;
  private boolean debug = false;

  public void setHost (String host) {

    this.host = host;
  }

  public void setPort (int port) {

    this.port = port;
  }

  public void setContextPath (String contextPath) {

    this.contextPath = contextPath;
  }

  public void setRestPath (String restPath) {

    this.restPath = restPath;
  }

  public void setSoapPath (String soapPath) {

    this.soapPath = soapPath;
  }

  public void setServletInstallers (ServletInstaller[] servletInstallers) {

    this.servletInstallers = servletInstallers;
  }

  public void setDebug (boolean debug) {

    this.debug = debug;
  }

  @Override
  public synchronized void onApplicationEvent (ApplicationEvent event) {

    if (event instanceof ContextRefreshedEvent) {

      if (debug) {
        System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
      }
      httpServer = new HttpServer();
      httpServer.addListener(new NetworkListener("grizzly2", host, port));

      WebappContext webappContext = new WebappContext("Grizzly Application Context");
      webappContext.addServlet("JAX-RS Application", new ServletContainer(new JsonResourceConfig(ExposedApplicationContext.getApplicationContext()))).addMapping(restPath + "/*");
      webappContext.addFilter("per-application-data", new PerApplicationContextFilter()).addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), restPath + "/*");
      webappContext.addListener("org.springframework.web.context.request.RequestContextListener");

      for (ServletInstaller servletInstaller : servletInstallers) {
        try {

          Constructor<? extends Servlet> servletConstructor;
          Servlet servlet;
          String urlPattern;

          servletConstructor = servletInstaller.getServletClass().getConstructor(NO_ARG_SIGNATURE);
          servlet = servletConstructor.newInstance();

          webappContext.addServlet(servletInstaller.getDisplayName(), servlet).addMapping((urlPattern = servletInstaller.getUrlPattern()) == null ? "/" : urlPattern);
        }
        catch (Exception exception) {
          throw new GrizzlyInitializationException(exception);
        }
      }

      webappContext.deploy(httpServer);

      for (WebService webService : serviceList) {

        HttpHandler httpHandler = new JaxwsHandler(webService.getService(), false);

        httpServer.getServerConfiguration().addHttpHandler(httpHandler, soapPath + webService.getPath());
      }

      try {
        httpServer.start();
      }
      catch (IOException ioException) {
        if (!(ioException instanceof BindException)) {
          throw new GrizzlyInitializationException(ioException);
        }
      }
    }
  }

  @Override
  public void setApplicationContext (ApplicationContext applicationContext) {

    ExposedApplicationContext.register(applicationContext);
  }

  @Override
  public Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException {

    return bean;
  }

  @Override
  public Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException {

    ServicePath servicePath;

    if ((servicePath = bean.getClass().getAnnotation(ServicePath.class)) != null) {
      serviceList.add(new WebService(servicePath.value(), bean));
    }

    return bean;
  }

  @Override
  public synchronized void destroy () {

    if (httpServer != null) {
      httpServer.shutdown();
    }
  }
}
于 2014-08-24T07:43:27.967 に答える