Java 使用一个DTO对象处理2次转换

Java 使用一个DTO对象处理2次转换,java,spring,hibernate,jackson,dto,Java,Spring,Hibernate,Jackson,Dto,这是我的第一个春季项目。我试图从API openweathermap获取天气信息,将其映射到dto,并且仅当dto是唯一的数据库插入时 最初的想法是使用两个dto类。一个用于API响应,另一个用于字段较少的数据库实体。它工作得很好,但我听说过类似@JsonIgnorePropertiesignoreUnknown=true和@JsonPropertyname的JSON注释 在对weatherSampleDto进行一些修改后,它适用于API请求,但不适用于实体↔ dto 不再映射了 天气空气污染指

这是我的第一个春季项目。我试图从API openweathermap获取天气信息,将其映射到dto,并且仅当dto是唯一的数据库插入时

最初的想法是使用两个dto类。一个用于API响应,另一个用于字段较少的数据库实体。它工作得很好,但我听说过类似@JsonIgnorePropertiesignoreUnknown=true和@JsonPropertyname的JSON注释

在对weatherSampleDto进行一些修改后,它适用于API请求,但不适用于实体↔ dto 不再映射了

天气空气污染指数回应:

{
  "coord": {
    "lon": 25.61,
    "lat": 49.56
  },
  "weather": [
    {
      "id": 804,
      "main": "Clouds",
      "description": "хмарно",
      "icon": "04n"
      …
    }
  ],
  "base": "model",
  "main": {
    "temp": 1.06,                   <-------------- temperature
    "feels_like": -2.27,            <-------------- feelsLike
    "temp_min": 1.06,
    "temp_max": 1.06,
    "pressure": 1016,               <-------------- pressure
    "humidity": 84,                 <-------------- humidity
    "sea_level": 1016,
    "grnd_level": 974
  },
  "wind": {
    "speed": 1.65,
    "deg": 281
  },
  "clouds": {
    "all": 100                      <-------------- clouds
  },
  "dt": 1580144397,                 <-------------- time
  "sys": {
    "country": "UA",
    "sunrise": 1580104637,
    "sunset": 1580137367
  },
  "timezone": 7200,
  "id": 691650,                     <-------------- cityId
  "name": "Ternopil",               <-------------- cityName
  "cod": 200
}
和样本实体:

它在每个带注释的字段上都失败。 例如com.fasterxml.jackson.databind.exc.MismatchedInputException:无法反序列化'java.util.LinkedHashMap'的实例,该实例超出值\u NUMBER\u INT标记 通过引用链:weather.dto.WeatherSampleDto[clouds]在[Source:UNKNOWN;line:-1,column:-1]处


可以用一个dto类来求解吗?如果是这样的话,如何实现?

常见的实现是创建@Service类,该类从API获取天气数据,响应模型将是它自己的独立类,然后您获取所需的任何数据,并将其填充到@Entity类中,然后存储它。

是的,这正是我的做法。我想也许有更好的解决办法。

@JsonIgnoreProperties(ignoreUnknown = true)
public class WeatherSampleDto implements Serializable {
    @JsonIgnore
    private Long id;
    @JsonProperty("name")
    private String cityName;
    private float temperature;
    private float feelsLike;
    private int pressure;
    private int humidity;
    private int clouds;
    private int cityId;
    @JsonProperty("dt")
    private int time;

    @JsonProperty("main")
    private void unpackMain(Map<String, String> main) {
        temperature = Float.parseFloat(main.get("temp"));
        feelsLike = Float.parseFloat(main.get("feels_like"));
        pressure = Integer.parseInt(main.get("pressure"));
        humidity = Integer.parseInt(main.get("humidity"));

    }
    @JsonProperty("clouds")
    private void unpackClouds(Map<String, Integer> cloudsObj) {
        clouds = cloudsObj.get("all");
    }
    @JsonProperty("id")
    private void unpackId(Integer idObj){
        cityId = idObj;
    }
...
@Entity
public class WeatherSample {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String cityName;
    private float temperature;
    private float feelsLike;
    private int pressure;
    private int humidity;
    private int clouds;
    private int cityId;
    private int time;
...