使用一个 DTO 对象处理 2 个转换
Handle 2 conversions with one DTO object
这是我的第一个 spring 项目。我正在尝试从 API (openweathermap) 获取天气,将其映射到 dto,并且仅当 dto 是唯一的时才插入到数据库中。
起初的想法是使用两个 dto classes。一个用于 API 响应,另一个用于数据库实体(字段较少)。它工作得很好,但我听说过 JSON 注释,例如 @JsonIgnoreProperties(ignoreUnknown = true)
和 @JsonProperty("name")
.
对 weatherSampleDto
进行一些修改后,它适用于 API 请求,但不适用于实体 ↔ dto
映射了。
天气 API 响应:
{
"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
}
这里是修改后的WeatherSampleDto
:
@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;
}
...
和WeatherSample
实体:
@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;
...
它在每个带注释的字段上都失败了。
比如com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap<java.lang.Object,java.lang.Object>`out of VALUE_NUMBER_INT token
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: weather.dto.WeatherSampleDto["clouds"])
是否可以用一个dto来解决class?如果有怎么办?
常见的实现是创建 @Service
class 从 API 获取天气数据,响应模型是它自己的分开 class 然后你拿你需要的任何数据并用它填充 @Entity
class 然后存储它。
这是我的第一个 spring 项目。我正在尝试从 API (openweathermap) 获取天气,将其映射到 dto,并且仅当 dto 是唯一的时才插入到数据库中。
起初的想法是使用两个 dto classes。一个用于 API 响应,另一个用于数据库实体(字段较少)。它工作得很好,但我听说过 JSON 注释,例如 @JsonIgnoreProperties(ignoreUnknown = true)
和 @JsonProperty("name")
.
对 weatherSampleDto
进行一些修改后,它适用于 API 请求,但不适用于实体 ↔ dto
映射了。
天气 API 响应:
{
"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
}
这里是修改后的WeatherSampleDto
:
@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;
}
...
和WeatherSample
实体:
@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;
...
它在每个带注释的字段上都失败了。
比如com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.LinkedHashMap<java.lang.Object,java.lang.Object>`out of VALUE_NUMBER_INT token
at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: weather.dto.WeatherSampleDto["clouds"])
是否可以用一个dto来解决class?如果有怎么办?
常见的实现是创建 @Service
class 从 API 获取天气数据,响应模型是它自己的分开 class 然后你拿你需要的任何数据并用它填充 @Entity
class 然后存储它。