Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.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 尝试记录子对象时,Restdoc抛出org.springframework.restdocs.snippet.SnippetException_Java_Mockmvc_Spring Restdocs - Fatal编程技术网

Java 尝试记录子对象时,Restdoc抛出org.springframework.restdocs.snippet.SnippetException

Java 尝试记录子对象时,Restdoc抛出org.springframework.restdocs.snippet.SnippetException,java,mockmvc,spring-restdocs,Java,Mockmvc,Spring Restdocs,我有一个OrderInfo类: @ApiModel(description = "object needed to make an order") public class OrderInfo implements Serializable { private static final long serialVersionUID = 1L; @JsonProperty("purchase") private PurchaseInfo purchase = null; @J

我有一个OrderInfo类:

@ApiModel(description = "object needed to make an order")

public class OrderInfo  implements Serializable {
  private static final long serialVersionUID = 1L;

  @JsonProperty("purchase")
  private PurchaseInfo purchase = null;

  @JsonProperty("paymentMode")
  private PaymentMode paymentMode = null;

  @JsonProperty("serialNumber")
  private String serialNumber = null;

  public OrderInfo purchase(PurchaseInfo purchase) {
    this.purchase = purchase;
    return this;
  }

  @ApiModelProperty(required = true, value = "coming from commercialization")
  @NotNull
  @Valid
  public PurchaseInfo getPurchase() {
    return purchase;
  }

  public void setPurchase(PurchaseInfo purchase) {
    this.purchase = purchase;
  }

  public OrderInfo paymentMode(PaymentMode paymentMode) {
    this.paymentMode = paymentMode;
    return this;
  }

  @ApiModelProperty(required = true, value = "")
  @NotNull
  @Valid
  public PaymentMode getPaymentMode() {
    return paymentMode;
  }

  public void setPaymentMode(PaymentMode paymentMode) {
    this.paymentMode = paymentMode;
  }

  public OrderInfo serialNumber(String serialNumber) {
    this.serialNumber = serialNumber;
    return this;
  }


  @ApiModelProperty(value = "The serial number of the registered device")
  public String getSerialNumber() {
    return serialNumber;
  }

  public void setSerialNumber(String serialNumber) {
    this.serialNumber = serialNumber;
  }
}
具有PurchaseInfo子对象:

@ApiModel(description = "Info necessary to order a video, an episode or a season")

public class PurchaseInfo  implements Serializable {
  private static final long serialVersionUID = 1L;

  @JsonProperty("id")
  private String id = null;

  @JsonProperty("pricingId")
  private String pricingId = null;

  @JsonProperty("price")
  private Double price = null;

  @JsonProperty("type")
  private ArticleType type = null;

  public PurchaseInfo id(String id) {
    this.id = id;
    return this;
  }


  @ApiModelProperty(required = true, value = "id of the commercialization")
  @NotNull
  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public PurchaseInfo pricingId(String pricingId) {
    this.pricingId = pricingId;
    return this;
  }

  @ApiModelProperty(required = true, value = "additional pricing of the commercialization")
  @NotNull
  public String getPricingId() {
    return pricingId;
  }

  public void setPricingId(String pricingId) {
    this.pricingId = pricingId;
  }

  public PurchaseInfo price(Double price) {
    this.price = price;
    return this;
  }

  @ApiModelProperty(required = true, value = "price of the commercialization")
  @NotNull
  public Double getPrice() {
    return price;
  }

  public void setPrice(Double price) {
    this.price = price;
  }

  public PurchaseInfo type(ArticleType type) {
    this.type = type;
    return this;
  }

  @ApiModelProperty(required = true, value = "")
  @NotNull
  @Valid
  public ArticleType getType() {
    return type;
  }

  public void setType(ArticleType type) {
    this.type = type;
  }
}
以及生成的相应的字段描述符类:

public class OrderInfoFieldDescriptor {
    public static FieldDescriptor[] fdOrderInfo = new FieldDescriptor[] {
        fieldWithPath("purchase").description("coming from commercialization").type(PurchaseInfo.class),
        fieldWithPath("paymentMode").description("").type(PaymentMode.class),
        fieldWithPath("serialNumber").description("The serial number of the registered device").type(java.lang.String.class).optional()    };


    public static FieldDescriptor[] fdOrderInfoList = new FieldDescriptor[] {
        fieldWithPath("[].purchase").description("coming from commercialization").type(PurchaseInfo.class),
        fieldWithPath("[].paymentMode").description("").type(PaymentMode.class),
        fieldWithPath("[].serialNumber").description("The serial number of the registered device").type(java.lang.String.class).optional()    };
}
以及:

调用mockMvc.perform以生成具有OrderInfo.class类型的requestBody和responseBody的HTTP POST时:

mockMvc.perform(postRequest)
                .andDo(document("orderInfoCreate", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()),
                        pathParameters(parameterWithName("username").description("the name of the user")),
                        responseFields(OrderInfoFieldDescriptor.fdOrderInfo),
                        requestFields(OrderInfoFieldDescriptor.fdOrderInfo))).andExpect(status().isCreated())
                .andExpect(content().json(orderInfoAsJson));
验证适用于paymentMode和serialNumber,但在购买时失败,例外情况如下:

org.springframework.restdocs.snippet.SnippetException: The following parts of the payload were not documented:
{
  "purchase" : {
    "id" : "purchaseId",
    "pricingId" : "pricingId",
    "price" : 12.0,
    "type" : "EPISODE"
  },
  "serialNumber" : "serialNumber"
}
即使请求主体和响应主体看起来很好:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/users/myUserName/orders
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Host:"host:posrt", Accept:"application/json;charset=UTF-8", Cookie:"identity=cookieForTest"]
             Body = {"purchase":{"id":"purchaseId","pricingId":"pricingId","price":12.0,"type":"EPISODE"},"paymentMode":"POSTPAID","serialNumber":"serialNumber"}
    Session Attrs = {}
以及:

从Spring Boot 1x迁移到2x后出现此问题

你知道问题是什么吗


谢谢:)

您似乎依靠
purchase
来记录
purchase
及其包含的所有内容,即
purchase.id
purchase.pricingId
purchase.price
purchase.type
。这在1.1之前(包括1.1)的REST文档中起作用,但它会造成一个问题,即人们可能会意外地错过记录嵌套字段的过程,因为他们记录了其父字段。这在中进行了讨论,也在中进行了讨论。该问题在REST Docs 1.2中引入了一项更改,默认情况下,记录字段不再记录其所有子体。您会受到此更改的影响,因为升级到Spring Boot 2意味着您也升级到了REST Docs 2


如果您想保留现有行为,只需使用
purchase
记录它及其所有子体,则应将
fieldWithPath
替换为
subsectionWithPath
。如果您想记录
purchase
下的所有内容,您应该为
purchase.id
purchase.pricingId
purchase.price
purchase.type

添加额外的描述符。您是对的,REST文档已更新为2.0.3。在本例中,我们希望保留现有的行为,并且
subsectionWithPath
选项完成了任务。谢谢你的帮助!
MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /api/users/myUserName/orders
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Host:"host:posrt", Accept:"application/json;charset=UTF-8", Cookie:"identity=cookieForTest"]
             Body = {"purchase":{"id":"purchaseId","pricingId":"pricingId","price":12.0,"type":"EPISODE"},"paymentMode":"POSTPAID","serialNumber":"serialNumber"}
    Session Attrs = {}
MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = [Content-Type:"application/json;charset=UTF-8"]
     Content type = application/json;charset=UTF-8
             Body = {"purchase":{"id":"purchaseId","pricingId":"pricingId","price":12.0,"type":"EPISODE"},"paymentMode":"POSTPAID","serialNumber":"serialNumber"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []