如何在同一端口托管SOAP服务和REST服务?

有谁知道如何配置它,以便SOAP服务和REST服务可以在应用程序服务器之外使用Jersey(Grizzly)共享同一个端口?

  • 我的肥皂服务在www.someurl.com:port/soap/crm
  • 我的rest服务是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:地址已经在使用中:bind’

我的肥皂服务接待设置如下:

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

我的rest服务课像往常一样注释……

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

我在这方面有点新手,任何指针都会受到赞赏。 请不要打扰我建议运行应用程序服务器。 这不是问题所在 – 问题是如何在不转移到其他Web服务框架的情况下解决端口绑定问题?

注意RE BOUNTY:我不能完全忘记这一点

“赏金获胜者将演示如何在同一端点上一起使用Jersey for REST和Java SOAP服务(带注释的JAX-WS)。 答案不需要更改Rest和Soap带注释的类。但是,HTTP服务器代码更改或接受配置更改以使其正常工作。切换到Jetty或其他应用程序服务器是不可接受的解决方案必须100%嵌入并使用Java SE和Java Web服务库运行。“

Jetty的覆盖function允许您在同一个Jetty实例/端口上部署两个具有不同路径的不同Web应用程序。

您将拥有一个带有Jersey servlet(用于REST)的web.xml和带有SOAP servlet的另一个web.xml。

http://www.eclipse.org/jetty/documentation/current/overlay-deployer.html

你所说的只是两个不同的接口,用于公开服务,是的,你可以将它们托管在一个端口上,只需将它部署在同一个容器中,你就可以使两个接口都运行起来。

请确保您没有上下文路径冲突,这似乎不会出现在上面问题中提到的url中。

例如,将其余接口部署为:

http://www.someurl.com:port2/crm,所以肥皂不应该部署在同一个url上,www.someurl.com:port1 / soap / crm,这没关系。

您还应该解释一下如何将接口部署为单独的war文件或单个war文件。

如果您使用诸如tomcat之类的公共容器作为Web服务,那么您可以获得对同一端口上的两个服务的请求。 您可以将REST和基于SOAP的服务部署为应用程序的一部分。 容器将接受传入的请求,并根据应用程序上下文将它们转发到应用程序。 在应用程序web.xml中,您可以根据请求URL映射配置发送请求的位置。

无法在同一端口上启动多个服务。

如果希望通过同一端口访问应用程序,则必须使用Application Server。

您必须注意服务器上的两个应用程序都可以使用不同的URL(web.xml)访问。

现在可以通过同一端口访问同一Application Server上的所有应用程序。

这是我用于在单个端口(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 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 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(); } } }