如何从 Java 中的 SOAP 端点获取响应?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12620843/
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-10-31 09:35:37  来源:igfitidea点击:

How to get response from SOAP endpoint in java?

javaweb-servicessoap

提问by Cuga

I am very new to SOAP, so was looking into some programs online, this is what I came up with but I get a null response, must be some silly thing, but need little help

我对 SOAP 很陌生,所以在网上查看了一些程序,这是我想出来的,但我得到了一个空响应,一定是一些愚蠢的事情,但几乎不需要帮助

Please take a look at my code and output below. Thanks

请看一下我的代码和下面的输出。谢谢

Code

代码

import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;

public class AtomicNumber {
  public static void main(String[] args) {
    try {
      SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
      SOAPConnection connection = sfc.createConnection();

      MessageFactory mf = MessageFactory.newInstance();
      SOAPMessage smsg = mf.createMessage();

      SOAPHeader shead = smsg.getSOAPHeader();

      SOAPBody sbody = smsg.getSOAPBody();
      shead.detachNode();
      QName bodyName = new QName("http://www.webserviceX.NET", "GetAtomicNumber", "web");
      SOAPBodyElement bodyElement = sbody.addBodyElement(bodyName);
      QName qn = new QName("ElementName");
      SOAPElement quotation = bodyElement.addChildElement(qn);

      quotation.addTextNode("iron");

      System.out.println("\n Soap Request:\n");
      smsg.writeTo(System.out);
      System.out.println();

      URL endpoint = new URL("http://www.webservicex.net/periodictable.asmx");
      SOAPMessage response = connection.call(smsg, endpoint);

    System.out.println("\n Soap Response:\n");

     System.out.println(response.getContentDescription());


    } catch (Exception ex) {
      ex.printStackTrace();
    }
}
}

My Output

我的输出

 Soap Request:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><web:GetAtomicNumber xmlns:web="http://www.webserviceX.NET"><ElementName>sodium</ElementName></web:GetAtomicNumber></SOAP-ENV:Body></SOAP-ENV:Envelope>

 Soap Response:

null

Update

更新

This is what I am getting (Exception)

这就是我得到的(例外)

<faultcode>soap:Server</faultcode>
     <faultstring>System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Data.SqlClient.SqlException: Procedure or function 'GetAtomicNumber' expects parameter '@ElementName', which was not supplied.
at WebServicex.periodictable.GetAtomicNumber(String ElementName)
 --- End of inner exception stack trace ---</faultstring>

回答by Cuga

What you want to do is auto-generate Java code for this web service. The WSDL is here: http://www.webservicex.net/periodictable.asmx?wsdl

您要做的是为该 Web 服务自动生成 Java 代码。WSDL 在这里:http: //www.webservicex.net/periodictable.asmx?wsdl

In Java, the tool to auto-generate the code is wsimport. You'll want to use something like this:

在 Java 中,自动生成代码的工具是wsimport. 你会想要使用这样的东西:

wsimport http://www.webservicex.net/periodictable.asmx?wsdl -p com.company.whateveruwant -Xnocompile -d . -keep

This will put the code you want in the specified package (here com.company.whateveruwant).

这会将您想要的代码放在指定的包中(此处com.company.whateveruwant)。

From there, all you have to do is simply invoke the SOAP method like a normal Java library:

从那里,您所要做的就是像普通 Java 库一样调用 SOAP 方法:

PeriodictableSoap soap = new Periodictable().getPeriodictableSoap();
System.out.println(soap.getAtomicNumber("Iron"));

This prints out:

这打印出来:

<NewDataSet>
  <Table>
    <AtomicNumber>26</AtomicNumber>
    <ElementName>Iron</ElementName>
    <Symbol>Fe</Symbol>
    <AtomicWeight>55.847</AtomicWeight>
    <BoilingPoint>3300</BoilingPoint>
    <IonisationPotential>7.9</IonisationPotential>
    <EletroNegativity>1.6400000000000001</EletroNegativity>
    <AtomicRadius>1.17</AtomicRadius>
    <MeltingPoint>1808</MeltingPoint>
    <Density>7874</Density>
  </Table>
</NewDataSet>

回答by kjp

Try with

试试

   QName qn = new QName("http://www.webserviceX.NET","ElementName","web");

EDIT: Also, as others have suggested - you will be better off using generated client code here - Axis, JAX-WS etc are all options.

编辑:此外,正如其他人所建议的那样 - 您最好在此处使用生成的客户端代码 - Axis、JAX-WS 等都是选项。

The correct code should be as below.

正确的代码应该如下。

  QName bodyName = new QName("http://www.webserviceX.NET", "GetAtomicNumber");
  SOAPBodyElement bodyElement = sbody.addBodyElement(bodyName);
  QName qn = new QName("ElementName");

回答by Wojtek Owczarczyk

Do you really need to use bare SOAP classes? How about generating JAX-WS artifactsto get rid of all this boilerplate?

您真的需要使用裸 SOAP 类吗?如何生成 JAX-WS 工件以摆脱所有这些样板文件?

More info (incorporating ANT) here.

更多信息(包括 ANT)请点击此处

回答by Carlos Castellanos

With cxf-codegen-plugin maven plugin you can create a client of the soap service quickly by adding these dependencies:

使用 cxf-codegen-plugin maven 插件,您可以通过添加以下依赖项来快速创建 soap 服务的客户端:

<dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>2.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>2.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-core</artifactId>
            <version>2.4.2</version>
        </dependency>

and adding this build section:

并添加此构建部分:

org.apache.cxf cxf-codegen-plugin 2.1.2 generate-sources generate-sources wsdl2java ${basedir}/target/generated-sources/cxf ${basedir}/src/main/resources/wsdlfile.wsdl -client -wsdlLocation -p com.package.for.generated.classes

org.apache.cxf cxf-codegen-plugin 2.1.2 generate-sources generate-sources wsdl2java ${basedir}/target/generated-sources/cxf ${basedir}/src/main/resources/wsdlfile.wsdl -client -wsdlLocation -p com.package.for.generated.班级

then inside ${basedir}/target/generated-sources/cxf you will have classes required to call the web service and an example of how to do it.

然后在 ${basedir}/target/generated-sources/cxf 中,您将拥有调用 Web 服务所需的类以及如何执行此操作的示例。

Hope it helps!

希望能帮助到你!

回答by shariq

@Ricky, this is the correct code.

@Ricky,这是正确的代码。

SOAPBody body = message.getSOAPBody();
QName bodyName = new QName("http://www.webserviceX.NET", "GetAtomicNumber");
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
SOAPElement symbol = bodyElement.addChildElement("MyMetal");
symbol.addTextNode("iron");
SOAPConnection connection = SOAPConnectionFactory.newInstance().createConnection();
SOAPMessage response = connection.call(message, endpoint);
connection.close();
message.writeTo(System.out);
System.out.println();
response.writeTo(System.out);
System.out.println();