Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Citrus框架验证JSON中嵌入的XML?_Java_Json_Xml_Citrus Framework - Fatal编程技术网

Java 如何使用Citrus框架验证JSON中嵌入的XML?

Java 如何使用Citrus框架验证JSON中嵌入的XML?,java,json,xml,citrus-framework,Java,Json,Xml,Citrus Framework,在我的Citrus测试中,我试图验证嵌入JSON文档(WireMock的输出)中的XML消息。需要解析XML文本,因为它包含我想忽略的时间戳。JSON消息的XML部分如下所示: "requests": [ { "id": "52844d5a-59de-4288-8000-7f48fcda41e5", "request": { "body": "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.o

在我的Citrus测试中,我试图验证嵌入JSON文档(WireMock的输出)中的XML消息。需要解析XML文本,因为它包含我想忽略的时间戳。JSON消息的XML部分如下所示:

"requests": [
{
    "id": "52844d5a-59de-4288-8000-7f48fcda41e5",
    "request": {
        "body": "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"> [content omitted] </soapenv:Body></soapenv:Envelope>",
}
]
        variable("jsonXml", "'citrus:readFile('classpath:output/esb/add_conf_to_cart/response2.xml')'");

        http()
                .client(wiremockClient)
                .send()
                .get("/__admin/requests")
                .accept("application/json");

        HttpClientResponseActionBuilder body = http()
                .client(wiremockClient)
                .receive()
                .response(HttpStatus.OK)
                .messageType(MessageType.JSON)
                .validate("$.requests[0].request.body", "@matchesXml(${jsonXml})@")
                ;
class DummyAction extends AbstractTestAction {

    private File expectedOutputFile;

    public DummyAction(File expectedOutputFile) {
        this.expectedOutputFile = expectedOutputFile;
    }

    @Override
    public void doExecute(TestContext testContext) {
        String body = testContext.getVariable("body");
        Assert.assertTrue(body.startsWith("<soapenv:Envelope "), "Request should start with '<soapenv:Envelope '");
    }
}
其中respon2.xml只包含xml文本(上面显示的JSON消息中“body”的内容),我从Citrus得到的错误是

com.consol.citrus.exceptions.CitrusRuntimeException: Failed to parse JSON text
…
Caused by: net.minidev.json.parser.ParseException: Unexpected token <soapenv:Envelope xmlns:soapenv=
com.consol.citrus.exceptions.CitrusRuntimeException:无法解析JSON文本
…
原因:net.minidev.json.parser.ParseException:意外的令牌澄清
关于你目前的解决方案,我有两点意见:

  • extractFromPayload(..)
    将JSON的
    body
    部分提取到一个名为
    body
    的文件中。这与
    有效负载(…)
    部分无关。您刚刚将
    body
    的JSON内容存储到一个柑橘变量
    body
    中。你可能知道,也可能不知道

  • payload(…)
    方法将始终验证接收到的整个有效负载,即整个JSON对象

  • 如果您只想验证响应的一部分,请使用:
    .validate(“$.some.json.path”,“someValue”)

  • 解决方案 Citrus为您的用例提供了一个内部方法,有关详细信息,请参阅文档

    仅验证XML结构 这是最简单的解决方案:

    http()
    .客户(wiremockClient)
    .receive()
    .响应(HttpStatus.OK)
    .messageType(messageType.JSON)
    .validate($.requests[0].request.body“,@matchesXml('classpath:readFile('classpath:output/esb/add_conf_to_cart/response2.xml'))@)
    
    验证整个JSON响应 在您的例子中,只需匹配整个JSON结构,并将方法
    @matchesXml(“”)@
    放入正确的JSON条目中:

    http()
    .客户(wiremockClient)
    .receive()
    .响应(HttpStatus.OK)
    .messageType(messageType.JSON)
    .payload(“{\n”+
    “\”请求\“:{\n”+
    “id\:\“52844d5a-59de-4288-8000-7f48fcda41e5\,\n”+
    “\”请求\“:{\n”+
    “\“body\:\”@matchesXml(“[内容省略]”)@\”\n”+
    “}\n”+
    “}\n”+
    "}");
    
    评论
    • 放入
      payload
      的字符串必须是有效的JSON,即JSON值中的引号必须转义
    • Java字符串中的引号也必须转义,因此我们必须编写
      \\\”
    • Citrus首先将
      有效负载
      字符串解析为JSON,并将其作为JSON对象保存在内部,其中转义引号未被转义。然后将该字符串传递给验证函数
      匹配XML
    • 您当前的示例不是有效的XML,因为标记
      从未打开
    • 将有效负载请求放在单独的文件中要容易得多,只需注意该文件仍然必须是有效的JSON,即引号必须用反斜杠转义,如so
      \“
    • 您可能希望从单独的文件中读取XML内容。在这种情况下,您可以使用柑橘的功能
    • 对于
      负载
      ,仍然需要在XML中转义引号。您可以使用:
      citrus:translate('citrus:readFile('classpath:some/path/to/response.xml')、“\”、“\\”)执行此操作。
    • 转义是非常棘手的,因为我们处理的是引号和反斜杠,这在Java、JSON和XML中是特殊的
    • 其工作应如下:
    创建一个文件
    response\u validation.json

    {
    “请求”:{
    “id”:“52844d5a-59de-4288-8000-7f48fcda41e5”,
    “请求”:{
    “正文”:“@matchesXml('${jsonEscapedXmlInput}')@”
    }
    }
    }
    
    在您的测试用例中,创建柑橘变量
    jsonEscapedXmlInput
    ,该变量读取并转义XML文件:

    variable("jsonEscapedXml", "citrus:translate('citrus:readFile('classpath:output/esb/add_conf_to_cart/response2.xml')', '\\\"', '\\\\\"')")
    
    然后使用它

    http()
        .client(wiremockClient)
        .receive()
        .response(HttpStatus.OK)
        .messageType(MessageType.JSON)
        .payload(new ClassPathResource("classpath:validation/response_validation.json"))
    ;
    
    澄清 关于你目前的解决方案,我有两点意见:

  • extractFromPayload(..)
    将JSON的
    body
    部分提取到一个名为
    body
    的文件中。这与
    有效负载(…)
    部分无关。您刚刚将
    body
    的JSON内容存储到一个柑橘变量
    body
    中。你可能知道,也可能不知道

  • payload(…)
    方法将始终验证接收到的整个有效负载,即整个JSON对象

  • 如果您只想验证响应的一部分,请使用:
    .validate(“$.some.json.path”,“someValue”)

  • 解决方案 Citrus为您的用例提供了一个内部方法,有关详细信息,请参阅文档

    仅验证XML结构 这是最简单的解决方案:

    http()
    .客户(wiremockClient)
    .receive()
    .响应(HttpStatus.OK)
    .messageType(messageType.JSON)
    .validate($.requests[0].request.body“,@matchesXml('classpath:readFile('classpath:output/esb/add_conf_to_cart/response2.xml'))@)
    
    验证整个JSON响应 在您的例子中,只需匹配整个JSON结构,并将方法
    @matchesXml(“”)@
    放入正确的JSON条目中:

    http()
    .客户(wiremockClient)
    .receive()
    .响应(HttpStatus.OK)
    .messageType(messageType.JSON)
    .payload(“{\n”+
    “\”请求\“:{\n”+
    “id\:\“52844d5a-59de-4288-8000-7f48fcda41e5\,\n”+
    “\”请求\“:{\n”+
    “\“body\:\”@matchesXml(“[内容省略]”)@\”\n”+
    “}\n”+
    “}\n”+
    "}");
    
    评论
    • 放入
      payload
      的字符串必须是有效的JSON,即JSON值中的引号必须转义
    • Java字符串中的引号也必须转义,因此我们必须编写
      \\\”
    • Citrus首先将
      有效负载
      字符串解析为JSON,并将其作为JSON对象保存在内部,其中转义引号未被转义。然后将该字符串传递给验证函数
      匹配XML
    • 你的狗
      .validate("$.requests[0].request.body", "@matchesXml('${jsonXml}')@")
      
      .validate("$.requests[0].request.body", "@matchesXml(${jsonXml})@")
      
          http()
                  .client(wiremockClient)
                  .receive()
                  .response(HttpStatus.OK)
                  .messageType(MessageType.JSON)
                  .extractFromPayload("$.requests[0].request.body", "body")
          ;
          action(action(new DummyAction(new File(EXPECTED_OUTPUT_FILE)));
      
      class DummyAction extends AbstractTestAction {
      
          private File expectedOutputFile;
      
          public DummyAction(File expectedOutputFile) {
              this.expectedOutputFile = expectedOutputFile;
          }
      
          @Override
          public void doExecute(TestContext testContext) {
              String body = testContext.getVariable("body");
              Assert.assertTrue(body.startsWith("<soapenv:Envelope "), "Request should start with '<soapenv:Envelope '");
          }
      }