DateConverter无法将java.lang.String转换为java.util.Date。引起:org.modelmapper.MappingException:ModelMapper映射错误:

时间:2018-02-23 12:35:59

标签: java spring api modelmapper

我尝试使用modelmapper将我的Class映射到传入请求。

看起来Date无法在modelmapper中自动转换。

  

转换器org.modelmapper.internal.converter.DateConverter@7595415b   无法将java.lang.String转换为java.util.Date。引起:   org.modelmapper.MappingException:ModelMapper映射错误:

以上是获得的例外。

那么如何单独跳过此Date字段

目前我的代码看起来像是

ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
MyClass obj=mapper.map(anotherObject,MyClass.class);

MyClass的

public class MyClass {

    int id;

    Date updated_at;

}

anotherObject.toString

{id=6,updated_at=2018-02-23T03:01:12}

更新2

在这里误导道歉。实际上,我的 anotherObject 不是类对象。我将在下面解释我的具体情况

我的API响应

{
    "rows": 1,
    "last": null,    
    "results": [
        {
            "id": "1",
            "updated_at;": "2018-01-22T13:00:00",
        },
        {
            "id": "2",
            "updated_at;": "2018-01-22T13:00:00",
        }

                ]
}

MysuperClass

public class MysuperClass {

    int rows;

    String last;

    List<Object> results;

}

使用休息模板获取响应正文

ResponseEntity<MysuperClass > apiResponse = restTemplate.exchange(Url, HttpMethod.GET, entity, MysuperClass .class)

MysuperClass anotherObject=apiResponse.getBody();

实际课程

ModelMapper mapper = new ModelMapper();
    mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
    for (int index = 0; index < anotherObject.getResults().size(); index++) {

    MyClass obj=mapper.map(anotherObject.getResults().get(index),MyClass.class);

    }

3 个答案:

答案 0 :(得分:1)

如果查看model mapper source code for DateConverter,它似乎只支持java.sql.Date,java.sql.Time和java.sql.Timestamp类作为目标类型。即便如此,它在每种情况下仅支持非常特定的源字符串格式。

从模型映射器DateConverter:

Date dateFor(String source, Class<?> destinationType) {
String sourceString = toString().trim();
if (sourceString.length() == 0)
  throw new Errors().errorMapping(source, destinationType).toMappingException();

if (destinationType.equals(java.sql.Date.class)) {
  try {
    return java.sql.Date.valueOf(source);
  } catch (IllegalArgumentException e) {
    throw new Errors().addMessage(
        "String must be in JDBC format [yyyy-MM-dd] to create a java.sql.Date")
        .toMappingException();
  }
}

if (destinationType.equals(Time.class)) {
  try {
    return Time.valueOf(source);
  } catch (IllegalArgumentException e) {
    throw new Errors().addMessage(
        "String must be in JDBC format [HH:mm:ss] to create a java.sql.Time")
        .toMappingException();
  }
}

if (destinationType.equals(Timestamp.class)) {
  try {
    return Timestamp.valueOf(source);
  } catch (IllegalArgumentException e) {
    throw new Errors().addMessage(
        "String must be in JDBC format [yyyy-MM-dd HH:mm:ss.fffffffff] "
            + "to create a java.sql.Timestamp").toMappingException();
  }
}

throw new Errors().errorMapping(source, destinationType).toMappingException();

}

因此,最简单的解决方法是:

(1)改变MyClass使用java.sql.Date而不是java.util.Date;但是,如果时间很重要,那么使用Timestamp

(2)修改JSON中日期的格式,使其符合Timestamp的预期

话虽如此,另一种选择是与模型映射器团队合作,添加对java.util.Date的支持,或者更好的是,更新的LocalDate或LocalDateTime。或者如果您感兴趣,也可以自己添加支持并提交拉取请求。如果我有时间的话,今晚我可以看看。

希望这有帮助。

答案 1 :(得分:0)

您可以尝试以下方法:

创建一个新类Result以将JSON results数组的元素映射到。

class Result {
  int id;
  String updated_at;

  public int getId() {
    return id;
  }

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

  // setter should take a string (as it is in the JSON)
  public void setUpdated_at(String updated_at) {
    this.updated_at = updated_at;
  }

  // the getter should return a Date to map with MyClass
  public Date getUpdated_at() {
    Date d = null;
    try {
      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
      d = format.parse(updated_at);
    } catch(ParseException e) {
      e.printStackTrace();
    }
    return d;
  }
}

更改您的MysuperClass并将results设为结果列表

List<Result> results;

然后尝试以下代码:

ResponseEntity<MysuperClass > apiResponse = restTemplate.exchange(Url, HttpMethod.GET, entity, MysuperClass .class)
MysuperClass anotherObject = apiResponse.getBody(); // I hope that works fine

ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
for(Result result : anotherObject.getResults()) {
  MyClass obj = modelMapper.map(result, MyClass.class);
  System.out.println(obj.getId());
  System.out.println(obj.getUpdated_at());
}

答案 2 :(得分:0)

而不是单独关注模型映射器。我忘了为我的用例了解其他库。

我找到了一个使用ObjectMapper(org.codehaus.jackson.map.ObjectMapper)的简单方法

    List<<Result> results=(List<Result>)(Object)anotherObject.getResults();

    for(Object myObject: results){
        ObjectMapper objectMapper=new ObjectMapper();
        Appointment appointment= objectMapper.convertValue(myObject, MyClass.class);
    }