Ami*_*ali 6 java rest spring json localdate
我正在尝试使用 Spring 支持构建 RESTful Web 服务。当我尝试发送 POST 请求时出现以下异常。
输入:
POST http://localhost:8080/InventoryDemo/item
Run Code Online (Sandbox Code Playgroud)
在 JSON 有效负载中:
{"materialId":"ID02","materialName":"Material_2","materialCategory":"LIQUID","currency":"RUPEES","unitCostInCurrency":2200.0,"quantityLevel":1000,"quantityAtDate":"2016-04-11","warehouseName":"WareHouse_2"}
Run Code Online (Sandbox Code Playgroud)
例外:
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"])
Run Code Online (Sandbox Code Playgroud)
这是我来自@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);
}
Run Code Online (Sandbox Code Playgroud)
这是我的 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 + "]";
}
}
Run Code Online (Sandbox Code Playgroud)
仅供参考:我确实检查了这篇文章,但没有得到像我需要修改的确切位置的线索。
我正在使用 Java 8 和 Spring 4.2
有人可以详细解释一下我需要在这里做什么。 当我点击 GET 请求时,我也想要相同的日期格式。
谢谢。
您可以制作自定义LocalDate反序列化器。当调用LocalDate变量的setter 方法时,将调用此反序列化器。
步骤如下:
定义自定义解串器
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;
}
}
Run Code Online (Sandbox Code Playgroud)注意:LocalDate.parse方法的参考。
在变量上方定义@JsonDeserialize 注解
@JsonDeserialize(using=LocalDateDeserializer.class)
private LocalDate quantityAtDate;
Run Code Online (Sandbox Code Playgroud)使用@JsonDeserialize 注释导入如下:
导入 com.fasterxml.jackson.databind.annotation.JsonDeserialize;
希望这可以帮助。
JsonMappingException是 Jackson 抛出的异常,Jackson 是 Java 的 JSON 解析器。它表示将 JSON 映射到 Java bean 时存在致命问题。
在这种情况下,该字符串似乎2016-04-11无法LocalDate从 Java 8解析为 a 。
Jackson 支持 Java 8 日期类型,但需要以下依赖项:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
然后配置你的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;
}
}
Run Code Online (Sandbox Code Playgroud)
默认情况下,日期将以ISO 8601格式序列化。如果要更改格式,可以使用@JsonFormat:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM")
private LocalDate date;
Run Code Online (Sandbox Code Playgroud)
不需要自定义(反)序列化程序。
| 归档时间: |
|
| 查看次数: |
30088 次 |
| 最近记录: |