Java 单个应用程序的 REST 和 SOAP Web 服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20414615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:47:44  来源:igfitidea点击:

Both REST and SOAP Web Services for a single application

javaresttomcatsoapgradle

提问by Max

We've build an application using Spring and deployed it with Tomcat. We have a working REST interface, however one of our clients only has a SOAP client.

我们已经使用 Spring 构建了一个应用程序并使用 Tomcat 部署了它。我们有一个可用的 REST 接口,但是我们的一个客户端只有一个 SOAP 客户端。

My understanding is that a SOAP web service and a REST web service cannot coexist on the same port or application.

我的理解是 SOAP Web 服务和 REST Web 服务不能在同一个端口或应用程序中共存。

What are my options for accepting a SOAP request with as little development as possible. Should I accept a soap packet via the rest interface and parse the XML? Or can I setup a SOAP interface communicate with my REST interface and respond back?

在尽可能少的开发情况下接受 SOAP 请求的选项有哪些?我应该通过其余接口接受肥皂包并解析 XML 吗?或者我可以设置一个 SOAP 接口与我的 REST 接口进行通信并做出响应吗?

I'm using Gradle as my build tool. It would be nice to have the solution as part of a single WAR file

我使用 Gradle 作为我的构建工具。将解决方案作为单个 WAR 文件的一部分会很好

回答by Andrew White

In my experience, you canmix SOAP and REST in the same application if you're very careful about XML namespaces for JAXB. However, I wouldn't recommend it since updating one means risking the other's stability. Here is what I recommend...

根据我的经验,如果您非常注意 JAXB 的 XML 名称空间,您可以在同一个应用程序中混合使用 SOAP 和 REST。但是,我不会推荐它,因为更新一个意味着冒着另一个稳定性的风险。这是我推荐的...

  1. Setup a multi-project build in gradle
  2. Create three projects, one for the business logic, one for the REST interface, and one for the SOAP interface
  3. Modify the REST/SOAP interface to use common business logic project
  4. Deploy as two separate WARs
  1. 在 gradle 中设置多项目构建
  2. 创建三个项目,一个用于业务逻辑,一个用于REST接口,一个用于SOAP接口
  3. 修改REST/SOAP接口使用通用业务逻辑项目
  4. 部署为两个独立的 WAR

Should I accept a soap packet via the rest interface and parse the XML?

我应该通过其余接口接受肥皂包并解析 XML 吗?

SOAP is a protocol and not just a format so this probably won't work with most (any?) frameworks.

SOAP 是一种协议而不仅仅是一种格式,因此这可能不适用于大多数(任何?)框架。

Or can I setup a SOAP interface communicate with my REST interface and respond back?

或者我可以设置一个 SOAP 接口与我的 REST 接口进行通信并做出响应吗?

You probably could at the expense of performance and/or maintainability.

您可能会以牺牲性能和/或可维护性为代价。

回答by seand

It sounds like your web service is primarily REST (it's 2013) but you have to support soap for a limited case. I'd design your web service with rest primarily in mind, but perhaps use a separate mechanism to indicate to the server that the client requires soap support. If possible, have the soap client send an http request header or use modified URL that perhaps ends in .soap. In any case there's no reason why you can't support both protocols on the same app.

听起来您的 Web 服务主要是 REST(2013 年),但您必须在有限的情况下支持 soap。我会主要考虑休息来设计您的 Web 服务,但可能使用单独的机制向服务器指示客户端需要肥皂支持。如果可能,让soap 客户端发送一个http 请求标头或使用可能以.soap 结尾的修改后的URL。在任何情况下,您都没有理由不能在同一个应用程序上支持两种协议。

回答by Amanuel Nega

We have a project that has similar requirements. We still have to support SOAP and we're going forward with ReST.

我们有一个具有类似要求的项目。我们仍然需要支持 SOAP,并且我们正在推进 ReST。

There is no reason that the two will conflict. Since you're using spring, you can even have the same domain objects as a response that gets marshalled to XML and JSON as your preference.

没有理由两者会发生冲突。由于您使用的是 spring,您甚至可以将相同的域对象作为响应编组为 XML 和 JSON 作为您的偏好。

What you have to do is create different URI for the two. e.g someService/**for the SOAP and some-restfor the ReST implementations. You can have a service layer to handle shared logic (mostly the code needed on the end point and the rest controller is to fetch the required data from the service layer and sending it to be marshalled)

您需要做的是为两者创建不同的 URI。例如someService/**对于 SOAP 和some-restReST 实现。您可以有一个服务层来处理共享逻辑(主要是端点上所需的代码,其余控制器是从服务层获取所需数据并将其发送以进行编组)

Just add some entry to your web.xmlfile to indicate the rest path and the endpoint paths...

只需在您的web.xml文件中添加一些条目以指示其余路径和端点路径...

回答by Zero Code

You can do that by following this Steps:

您可以按照以下步骤操作:

 -Add annotation of both Rest and Soap on class implementation.
 -Creating interface to hold the method annotation for Soap.
 -Put Rest annotation on method in class implementation.
 -Configure "web.xml" file to add "servlet" for Rest implementation you use.  
 -Don't forget to create class extend Application like [ApplicationConfiguration.class].

1- Class Implementation

1- 类实现

@javax.jws.WebService(endpointInterface = "com.test.ebpp.autopayment.tess.ejb.GService", targetNamespace = "http://ejb.test.autopayment.ebpp.tess.com/", serviceName = "ApplicationBusinessFacadeService", portName = "ApplicationBusinessFacadePort")
@Path(value = "/ApplicationBusinessFacadeService")
public class ApplicationBusinessFacadePortBindingImpl implements
    ApplicationBusinessFacade {
    @Override
    @POST
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public ProcessResponse process(Process request) {
        //type your code 
    }
}

2- Service Interface

2-服务接口

@WebService(name = "ApplicationBusinessFacade", targetNamespace =   "http://ejb.gateway.ebpp.com/")
@XmlSeeAlso({
com.ebpp.gateway.ejb.ObjectFactory.class,
com.ebpp.ifxmessages.ObjectFactory.class
})
public interface ApplicationBusinessFacade {

@WebMethod
@WebResult(targetNamespace = "")
@RequestWrapper(localName = "process", targetNamespace = "http://ejb.gateway.ebpp.com/", className = "com.ebpp.gateway.ejb.Process")
@ResponseWrapper(localName = "processResponse", targetNamespace = "http://ejb.gateway.ebpp.com/", className = "com.ebpp.gateway.ejb.ProcessResponse")
public ProcessResponse process(
    @WebParam(name = "arg0", targetNamespace = "")
    Process arg0);
 }

3- web.xml

3- web.xml

 <servlet>        
        <servlet-name>com.ebpp.core.rs.config.ApplicationConfiguration</servlet-name>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>com.ebpp.core.rs.config.ApplicationConfiguration</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
 </servlet>