代码之家  ›  专栏  ›  技术社区  ›  Amit Gawali

如何在POST方法的REST API中发送日期

  •  6
  • Amit Gawali  · 技术社区  · 7 年前

    输入:

    POST    http://localhost:8080/InventoryDemo/item
    

    在JSON负载中:

    {"materialId":"ID02","materialName":"Material_2","materialCategory":"LIQUID","currency":"RUPEES","unitCostInCurrency":2200.0,"quantityLevel":1000,"quantityAtDate":"2016-04-11","warehouseName":"WareHouse_2"}
    

    WARNING: Handler execution resulted in exception: Could not read document: Can not instantiate value of type [simple type, class java.time.LocalDate] from String value ('2016-04-11'); no single-String constructor/factory method
     at [Source: java.io.PushbackInputStream@378ace07; line: 1, column: 146] (through reference chain: com.psl.inventory.model.InventorySystemModel["quantityAtDate"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class java.time.LocalDate] from String value ('2016-04-11'); no single-String constructor/factory method
     at [Source: java.io.PushbackInputStream@378ace07; line: 1, column: 146] (through reference chain: com.psl.inventory.model.InventorySystemModel["quantityAtDate"])
    

    这是我在@RestController的POST方法:

    @RequestMapping(value = "/item", method = RequestMethod.POST)
        public ResponseEntity<Void> createInventorySystemModel(@RequestBody InventorySystemModel inventorySystemModel,  UriComponentsBuilder ucBuilder) {
            System.out.println("Creating InventorySystemModel " + inventorySystemModel.getMaterialName());
    
            if (inventorySystemService.isInventorySystemModelExist(inventorySystemModel)) {
                System.out.println("A InventorySystemModel with name " + inventorySystemModel.getMaterialName() + " already exist");
                return new ResponseEntity<Void>(HttpStatus.CONFLICT);
            }
    
            inventorySystemService.saveInventoryItem(inventorySystemModel);
    
            HttpHeaders headers = new HttpHeaders();
            headers.setLocation(ucBuilder.path("/user/{materialId}").buildAndExpand(inventorySystemModel.getMaterialId()).toUri());
            return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
        }
    

    这是我的POJO课程:

    public class InventorySystemModel {
    
        private String materialId;
        private String materialName;
        private String materialCategory;
        private String currency;
        private double unitCostInCurrency;
        private int quantityLevel;
        private LocalDate quantityAtDate;
        private String warehouseName;
    
        public InventorySystemModel(){
    
        }
        public InventorySystemModel(String materialId, String materialName,
                String materialCategory, String currency,
                double unitCostInCurrency, int quantityLevel, LocalDate quantityAtDate,
                String warehouseName) {
            super();
            this.materialId = materialId;
            this.materialName = materialName;
            this.materialCategory = materialCategory;
            this.currency = currency;
            this.unitCostInCurrency = unitCostInCurrency;
            this.quantityLevel = quantityLevel;
            this.quantityAtDate = quantityAtDate;
            this.warehouseName = warehouseName;
        }
    
        public String getMaterialId() {
            return materialId;
        }
        public void setMaterialId(String materialId) {
            this.materialId = materialId;
        }
        public String getMaterialName() {
            return materialName;
        }
        public void setMaterialName(String materialName) {
            this.materialName = materialName;
        }
        public String getMaterialCategory() {
            return materialCategory;
        }
        public void setMaterialCategory(String materialCategory) {
            this.materialCategory = materialCategory;
        }
        public String getCurrency() {
            return currency;
        }
        public void setCurrency(String currency) {
            this.currency = currency;
        }
        public double getUnitCostInCurrency() {
            return unitCostInCurrency;
        }
        public void setUnitCostInCurrency(double unitCostInCurrency) {
            this.unitCostInCurrency = unitCostInCurrency;
        }
        public int getQuantityLevel() {
            return quantityLevel;
        }
        public void setQuantityLevel(int quantityLevel) {
            this.quantityLevel = quantityLevel;
        }
        public LocalDate getQuantityAtDate() {
            return quantityAtDate;
        }
        public void setQuantityAtDate(LocalDate quantityAtDate) {
            this.quantityAtDate = quantityAtDate;
        }
        public String getWarehouseName() {
            return warehouseName;
        }
        public void setWarehouseName(String warehouseName) {
            this.warehouseName = warehouseName;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result
                    + ((currency == null) ? 0 : currency.hashCode());
            result = prime
                    * result
                    + ((materialCategory == null) ? 0 : materialCategory.hashCode());
            result = prime * result
                    + ((materialId == null) ? 0 : materialId.hashCode());
            result = prime * result
                    + ((materialName == null) ? 0 : materialName.hashCode());
            result = prime * result
                    + ((quantityAtDate == null) ? 0 : quantityAtDate.hashCode());
            result = prime * result + quantityLevel;
            long temp;
            temp = Double.doubleToLongBits(unitCostInCurrency);
            result = prime * result + (int) (temp ^ (temp >>> 32));
            result = prime * result
                    + ((warehouseName == null) ? 0 : warehouseName.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            InventorySystemModel other = (InventorySystemModel) obj;
            if (currency == null) {
                if (other.currency != null)
                    return false;
            } else if (!currency.equals(other.currency))
                return false;
            if (materialCategory == null) {
                if (other.materialCategory != null)
                    return false;
            } else if (!materialCategory.equals(other.materialCategory))
                return false;
            if (materialId == null) {
                if (other.materialId != null)
                    return false;
            } else if (!materialId.equals(other.materialId))
                return false;
            if (materialName == null) {
                if (other.materialName != null)
                    return false;
            } else if (!materialName.equals(other.materialName))
                return false;
            if (quantityAtDate == null) {
                if (other.quantityAtDate != null)
                    return false;
            } else if (!quantityAtDate.equals(other.quantityAtDate))
                return false;
            if (quantityLevel != other.quantityLevel)
                return false;
            if (Double.doubleToLongBits(unitCostInCurrency) != Double
                    .doubleToLongBits(other.unitCostInCurrency))
                return false;
            if (warehouseName == null) {
                if (other.warehouseName != null)
                    return false;
            } else if (!warehouseName.equals(other.warehouseName))
                return false;
            return true;
        }
        @Override
        public String toString() {
            return "InventorySystemModel [materialId=" + materialId
                    + ", materialName=" + materialName + ", materialCategory="
                    + materialCategory + ", currency=" + currency
                    + ", unitCostInCurrency=" + unitCostInCurrency
                    + ", quantityLevel=" + quantityLevel + ", quantityAtDate="
                    + quantityAtDate + ", warehouseName=" + warehouseName + "]";
        }
    }
    

    this 张贴,但没有得到线索,如我需要做修改确切的地方。

    此外,我想要相同的日期格式时,我会点击获取请求。

    谢谢

    4 回复  |  直到 7 年前
        1
  •  7
  •   SachinSarawgi    7 年前

    你可以定制 LocalDate 反序列化程序。当的setter方法时,将调用此反序列化器 变量被调用。

    步骤如下:

    1. 定义自定义反序列化器

      public class LocalDateDeserializer extends JsonDeserializer<LocalDate>{
      
        @Override
        public LocalDate deserialize(JsonParser p, DeserializationContext ctxt)
              throws IOException, JsonProcessingException {
      
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("required format");
      
            LocalDate localDate = null;
            localDate = LocalDate.parse(p.getText(), formatter);
      
            return localDate;
        }
      }
      

    注:参考 LocalDate.parse

    1. 在变量上方定义@JsonDeserialize注释

      @JsonDeserialize(using=LocalDateDeserializer.class)
      private LocalDate quantityAtDate;
      

    对于使用@JsonDeserialize注释导入,请执行以下操作:

    希望这有帮助。

        2
  •  5
  •   cassiomolin    7 年前

    错误

    JsonMappingException 是Java的JSON解析器Jackson引发的异常。它指出了将JSON映射到Java bean时的致命问题。

    2016-04-11 LocalDate 来自Java 8。

    如何修复它

    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
        <version>${jackson.version}</version>
    </dependency>
    

    然后配置 ObjectMapper

    @Configuration
    public class JacksonConfig {
    
        @Bean
        public ObjectMapper createObjectMapper() {  
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new JavaTimeModule());
            mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            return mapper;
        }
    }
    

    默认情况下,日期将在中序列化 ISO 8601 @JsonFormat

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM")
    private LocalDate date;
    

    不需要自定义(反)序列化程序。

        3
  •  2
  •   Barath    7 年前

    利用 @JsonFormat 定义日期格式

    http://www.baeldung.com/jackson-serialize-dates

    public class InventorySystemModel {
    
         private String materialId;
            private String materialName;
            private String materialCategory;
            private String currency;
            private double unitCostInCurrency;
            private int quantityLevel;
            @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
            private Date quantityAtDate;
            private String warehouseName;
    //getters and setters
    }
    

    {
        "materialId": "ID02",
        "materialName": "Material_2",
        "materialCategory": "LIQUID",
        "currency": "RUPEES",
        "unitCostInCurrency": 2200.0,
        "quantityLevel": 1000,
        "quantityAtDate": "2016-04-11",
        "warehouseName": "WareHouse_2"
    }
    

    答复:

    InventorySystemModel [materialId=ID02, materialName=Material_2, materialCategory=LIQUID, currency=RUPEES, unitCostInCurrency=2200.0, quantityLevel=1000, quantityAtDate=Mon Apr 11 05:30:00 IST 2016, warehouseName=WareHouse_2]
    
        4
  •  0
  •   Arunchunaivendan    6 年前

    使用反序列化器解析LocalDate。

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.8.10</version>
        </dependency>
    

    如果您的restful服务直接解析bean,请添加以下内容

    import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
    import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
    
    @PostMapping(value = "/xyz")
    @JsonDeserialize(using = LocalDateDeserializer.class)
    public  ResponseEntity <String> testMethod (@RequestBody Bean bean){
    }
    

    deserializer 在bean类中。