【问题标题】:Simple curl failing from linux command line简单的 curl 从 linux 命令行失败
【发布时间】:2012-01-25 13:49:22
【问题描述】:

我们有一个简单的 REST 请求,我可以在我的 Mac 上手动使用 RESTClient(来自 wiztools)。网址为http://ws-argos.clsamerica.com/argosDws/services/DixService?getXml,正文如下:

<soap:Envelope 
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:typ="http://service.dataxmldistribution.argos.cls.fr/types">
  <soap:Body>
  <typ:xmlRequest>
     <typ:username>******</typ:username>
     <typ:password>******</typ:password>
     <typ:platformId>62518,62688,62520,62602,62608</typ:platformId>
     <typ:nbDaysFromNow>10</typ:nbDaysFromNow>
  </typ:xmlRequest>
 </soap:Body>
</soap:Envelope>

这会返回带有大量真实数据的简洁 XML。所以我知道数据是可以抓取的。但是,我想在 Linux 中的夜间脚本上自动执行此操作,并尝试使用以下两个脚本使用 CURL:

curl -H "content-type: application/soap+xml" \
 -H "SOAPAction:" \
 -d@soap.xml \
 -X POST http://ws-argos.clsamerica.com/argosDws/services/DixService?getXml \
> output.xml

调用soap.xml:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:typ="http://service.dataxmldistribution.argos.cls.fr/types">
<soap:Body>
  <typ:xmlRequest>
     <typ:username>******</typ:username>
     <typ:password>******</typ:password>
     <typ:platformId>62518,62688,62520,62602,62608</typ:platformId>
     <typ:nbDaysFromNow>10</typ:nbDaysFromNow>
  </typ:xmlRequest>
</soap:Body>

输出是:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
 <soap:Body><soap:Fault>    
 <soap:Code><soap:Value>soap:Sender</soap:Value></soap:Code>
 <soap:Reason><soap:Text xml:lang="en">Error reading XMLStreamReader.</soap:Text>
 </soap:Reason>
 </soap:Fault></soap:Body></soap:Envelope>

有谁知道如何解决这个问题,或者有更好的自动化方法?我是 CURL 的新手,但如果有人提出这种可能性,我可以在 Java 中创建一些东西(带有示例;-))

【问题讨论】:

    标签: java web-services soap curl jax-ws


    【解决方案1】:

    我没有使用过 Curl,但由于问题的作者会对 Java 代码感到满意,请参见下文。我遵循了这个例子:How to Build a SOAP Client on Google App Engine

    这是一个可用于为 Argos Web 服务生成代码的脚本:

    wsdluri='https://ws-argos.cls.fr/argosDws/services/DixService?wsdl'
    gensrcdir='./src'
    targetpackage='com.mypackage'
    genoutdir='./war/WEB-INF/classes'
    wsimport -extension -d "$genoutdir" -s "$gensrcdir" -p $targetpackage -keep "$wsdluri"
    

    下面是生成代码的简单测试:

    @Test
    public void test_parse() throws IOException, DixException_Exception {
        try {
        DixServicePortType argos =  new DixService().getDixServicePort();
        CsvRequestType params = new CsvRequestType();
        params.setShowHeader(true);
        params.setUsername("your_user_name");
        params.setPassword("your_password");
        params.setDisplaySensor(true);
        // params.setProgramNumber("your_program_number"); 
        params.setPlatformId("your_device_id"); 
        params.setNbDaysFromNow(2);
        StringResponseType csvres = argos.getCsv(params);
        assertNotNull(csvres);
        System.out.println(csvres.getReturn()); 
    
        StringResponseType xmlres = argos.getXml(params);
        assertNotNull(xmlres);
        System.out.println(xmlres.getReturn());
    
        } catch (SOAPFaultException e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
    }
    

    注意,虽然我已将 Web 服务指向 https 地址,但生成的代码似乎仍通过 http 连接。我想尝试 https,但我必须手动更改它。

    现在我想使用 Jaxb 来解析 XML 响应。我可以处理 CSV 输出,这很简单,但既然是肥皂,我们不妨以同样的方式做所有事情。 欢迎提出任何建议。

    [编辑] 我已经成功地获得了 XML 数据的模式,并使用“xjc”编译器生成了类,以便通过 jaxb 进行解组。 获取架构很简单:

        StringResponseType xmlSchema = argos.getXsd(new XsdRequestType());
        assertNotNull(xmlSchema);
        System.out.println(xmlSchema.getReturn()); 
        // save schema to argos.xsd file
    

    然后你可以调用“xjc”来生成类:

    xjc -p com.mypackage argos.xsd
    

    不幸的是,我以前遇到过一个问题,即缺少“XmlRootElement”注释的情况。在这方面有很多SO questions。 据我了解,这是强制“jxc”将某些名称视为唯一名称的问题(另请参阅this article)。因为我不想更改架构,所以我尝试通过外部绑定配置文件设置“jxc”。那没有用,但对其他人有用。 所以最后,我对已将 XmlRootElement 注释添加到生成的类的架构进行了一些小的手动更改:

    <xs:annotation>
        <xs:appinfo>
          <jaxb:globalBindings>
              <xjc:simple />
          </jaxb:globalBindings>
        </xs:appinfo>
    </xs:annotation>
    
    <xs:element name="data" type="data"/>
    

    现在我可以使用 Jaxb 解析 XML 数据。下面是一个使用 Restlet 的 jaxb 连接器的示例:

    ConverterHelper decoder = new JaxbConverter();
    Data data = decoder.toObject(new StringRepresentation( xmlres.getReturn()), Data.class, null);
    

    希望对您有所帮助,如果您对此解决方案有任何疑问,请发表评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-16
      • 1970-01-01
      • 2017-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      • 2019-04-23
      相关资源
      最近更新 更多