java - 逆向工程 : How to generate SOAP Request XML in the backend?

标签 java xml soap jax-ws java-ee-7

我有以下类(class):

WS 接口(interface):

package com.mypackage;

import javax.ejb.Remote;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

@Remote
@SOAPBinding(style = Style.DOCUMENT)
@WebService(name = "MathService", targetNamespace = "http://mypackage.com/")
public interface MathServiceWS {

    @WebResult(name = "result", targetNamespace = "http://mypackage.com/")
    @RequestWrapper(localName = "addRequest", className = "AddRequest", targetNamespace = "http://mypackage.com/")
    @WebMethod(action = "http://mypackage.com/add", operationName = "add")
    @ResponseWrapper(localName = "addResponse", className = "AddResponse", targetNamespace = "http://mypackage.com/")
    Long add(@WebParam(name = "add", targetNamespace = "http://mypackage.com/") AddBean add);
}

WS 实现:

package com.mypackage;

import javax.ejb.Stateless;
import javax.jws.WebService;

@Stateless(mappedName = "MathService")
@WebService(serviceName = "MathService", endpointInterface = "com.mypackage.MathServiceWS", portName = "MathServicePort", targetNamespace = "http://mypackage.com/")
public class MathService implements MathServiceWS {

    @Override
    public Long add(AddBean add) {
        Long first = new Long(add.getFirst().intValue());
        Long second = new Long(add.getSecond().intValue());
        return Long.valueOf(Math.addExact(first.longValue(), second.longValue()));
    }
}

bean :

package com.mypackage;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
    name = "Add",
    namespace = "http://mypackage.com/",
    propOrder = {
        "first",
        "second"
    }
)
public class AddBean implements Serializable {

    private static final long serialVersionUID = -7727938355039425419L;

    @XmlElement(required = true)
    private Integer first;

    @XmlElement(required = true)
    private Integer second;

    public AddBean() {

    }

    public Integer getFirst() {
        return first;
    }

    public void setFirst(Integer first) {
        this.first = first;
    }

    public Integer getSecond() {
        return second;
    }

    public void setSecond(Integer second) {
        this.second = second;
    }
}

部署此 WS 后,当我在 SoapUI 中添加 WSDL 时,添加方法请求在提供用户输入后如下所示:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myp="http://mypackage.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <myp:addRequest>
         <myp:add>
            <first>1</first>
            <second>2</second>
         </myp:add>
      </myp:addRequest>
   </soapenv:Body>
</soapenv:Envelope>

现在我想在我的 com.mypackage.MathService.add(AddBean) 方法中使用给定的用户输入包含上述 SOAP 请求 XML。

  • com.mypackage.AddBean 上使用 JAXB 仅生成部分请求
  • WebService Handlers 无法满足我的要求

任何指针都会非常有帮助。

最佳答案

您可以创建自定义 SOAPHandler 对象,并可以读取请求有效负载并通过自定义属性将其设置为 SOAPMessageContext。确保将范围设置为应用程序。

在您的服务类中,使用 @javax.annotation.Resource 注入(inject) javax.xml.ws.WebServiceContext 并通过您的自定义属性访问负载集。

例如:
1.创建处理程序并注册它。

public class PopulateSOAPMessagePayloadHandler implements SOAPHandler<SOAPMessageContext> {
    public static final String SOAP_MESSAGE_PAYLOAD = "__soap_message_payload";

    @Override
    public boolean handleMessage(SOAPMessageContext smc) {
        Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (!outboundProperty.booleanValue()) {
            // for incoming:
            ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);
            try {
                smc.getMessage().writeTo(bout);
                String payload = bout.toString(StandardCharsets.UTF_8.name());

                smc.put(SOAP_MESSAGE_PAYLOAD, payload);  //Set payload
                smc.setScope(SOAP_MESSAGE_PAYLOAD, MessageContext.Scope.APPLICATION);  //make it application scope

            } catch (SOAPException | IOException e) {
                e.printStackTrace();
                // handle exception if needed
                throw new WebServiceException(e);
            }

        }
        return true;
    }
 // Other method (no-op) omitted 
}


2.获取负载

public class MathService implements MathServiceWS {
    @Resource
    private WebServiceContext context;

    @Override
    public Long add(AddBean add) {
        String payload = (String) context.getMessageContext().get(SOAP_MESSAGE_PAYLOAD);

        Long first = new Long(add.getFirst().intValue());
        Long second = new Long(add.getSecond().intValue());
        return Long.valueOf(Math.addExact(first.longValue(), second.longValue()));
    }
}

希望对您有所帮助。

关于java - 逆向工程 : How to generate SOAP Request XML in the backend?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52050112/

相关文章:

java - 如何将文本从一个 Activity 传递到另一个 Activity (android studio)

php - 带有 .p12 SSL 证书的curl/soap 请求

java - 基本身份验证 Java SOAP Web 服务客户端

java - 对在 HttpClient 中创建 cookie 的不同方法感到困惑

java - 扫描仪在使用 next() 或 nextFoo() 后跳过 nextLine()?

java - Java中不同维度的二维数组相乘时出现问题

java - 如何在内容面板中创建 3 个水平布局框

r - 无法在 R/RStudio 中安装 XML 包

xml - XSLT IE6 默认处理器

wcf - 带有 rest 和 soap 端点的真实世界示例 wcf