我在使用ObjectMapper
包中的com.fasterxml.jackson.databind
类时遇到了json解析问题,而我得到的错误是:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.graybar.utilities.ups.beans.Address: no String-argument constructor/factory method to deserialize from String value ('')
发生此问题的Web应用程序是使用AngularJS前端的Spring MVC应用程序,但我可以使用更小的全java程序复制该问题。这是我的豆子:
Shipment.java
@JsonIgnoreProperties(ignoreUnknown = true)
public class Shipment {
@JsonProperty("Activity")
private ArrayList<Activity> activity;
public ArrayList<Activity> getActivity() {
return activity;
}
public void setActivity(ArrayList<Activity> activity) {
this.activity = activity;
}
}
Activity.java
@JsonIgnoreProperties(ignoreUnknown = true)
public class Activity {
@JsonProperty("ActivityLocation")
private ArrayList<ActivityLocation> activityLocation;
public ArrayList<ActivityLocation> getActivityLocation() {
return activityLocation;
}
public void setActivityLocation(ArrayList<ActivityLocation> activityLocation) {
this.activityLocation = activityLocation;
}
}
ActivityLocation.java
@JsonIgnoreProperties(ignoreUnknown = true)
public class ActivityLocation {
@JsonProperty("Address")
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Address.java
@JsonIgnoreProperties(ignoreUnknown = true)
public class Address {
@JsonProperty("City")
private String city;
@JsonProperty("StateProvinceCode")
private String stateProvinceCode;
@JsonProperty("CountryCode")
private String countryCode;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String countryCode) {
this.countryCode = countryCode;
}
public String getStateProvinceCode() {
return stateProvinceCode;
}
public void setStateProvinceCode(String stateProvinceCode) {
this.stateProvinceCode = stateProvinceCode;
}
}
以下是我可以正确映射json的代码:
public static void main(String[] args) {
String jsonMessage = "" +
"{" +
" \"Activity\": [{ " +
" \"ActivityLocation\": { " +
" \"Address\": { " +
" \"City\": \"Hana\", " +
" \"StateProvinceCode\": \"Hi\", " +
" \"CountryCode\": \"US\" " +
" } " +
" } " +
" }, " +
" { " +
" \"ActivityLocation\": { " +
" \"Address\": { " +
" \"City\": \"Honolulu\", " +
" \"StateProvinceCode\": \"Hi\", " +
" \"CountryCode\": \"US\" " +
" } " +
" } " +
" }] " +
"} ";
try {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
Shipment shipment = mapper.readValue(jsonMessage, Shipment.class);
System.out.println("shipment.toString = " + shipment.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
调整jsonMessage
var中的数据时,我遇到上面提到的错误:
"{" +
" \"Activity\": [{ " +
" \"ActivityLocation\": { " +
" \"Address\": { " +
" \"City\": \"Hana\", " +
" \"StateProvinceCode\": \"Hi\", " +
" \"CountryCode\": \"US\" " +
" } " +
" } " +
" }, " +
" { " +
" \"ActivityLocation\": { " +
" \"Address\": \"\" " +
" } " +
" } " +
" }] " +
"} ";
因此,从此更改json时会出现问题:
{
"ActivityLocation": {
"Address": {
"City": "Honolulu",
"StateProvinceCode": "Hi",
"CountryCode": "US"
}
}
}]
到此:
{
"ActivityLocation": {
"Address": ""
}
}
我没有为我的Address
bean发送值,而只是一个空字符串。不幸的是,我从第三方接收数据,无法控制收到的数据。
是否需要添加注释才能处理此问题?
答案 0 :(得分:27)
尝试设置mapper.configure(DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
或
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
取决于您的杰克逊版本。
答案 1 :(得分:0)
当我不小心打电话给
mapper.convertValue(...)
代替
mapper.readValue(...)
因此,只需确保调用正确的方法,因为参数相同并且IDE可以找到很多东西
答案 2 :(得分:0)
此异常表明您正在尝试从字符串“ \” \“”反序列化对象“ Address”,而不是诸如“ {…}”之类的对象描述。解串器找不到带有String参数的Address的构造函数。您必须用{}替换“”,以避免出现此错误。
答案 3 :(得分:0)
我找到了另一种方法来处理此错误。 (变量根据原始问题)
JsonNode parsedNodes = mapper.readValue(jsonMessage , JsonNode.class);
Response response = xmlMapper.enable(ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,ACCEPT_SINGLE_VALUE_AS_ARRAY )
.disable(FAIL_ON_UNKNOWN_PROPERTIES, FAIL_ON_IGNORED_PROPERTIES)
.convertValue(parsedNodes, Response.class);
答案 4 :(得分:0)
使用以下代码段对我有用
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"symbol\":\"ABCD\}";
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
Trade trade = objectMapper.readValue(jsonString, new TypeReference<Symbol>() {});
模型类
@JsonIgnoreProperties public class Symbol {
@JsonProperty("symbol")
private String symbol;
}
答案 5 :(得分:-3)
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
我的代码与上面的答案一样运行良好。 原因是来自jackson的json与从控制器发送的json不同。
String test1= mapper.writeValueAsString(result1);
和json一样(可以正常反序列化):
{"code":200,"message":"god","data":[{"nics":null,"status":null,"desktopOperatorType":null,"marker":null,"user_name":null,"user_group":null,"user_email":null,"product_id":null,"image_id":null,"computer_name":"AAAA","desktop_id":null,"created":null,"ip_address":null,"security_groups":null,"root_volume":null,"data_volumes":null,"availability_zone":null,"ou_name":null,"login_status":null,"desktop_ip":null,"ad_id":null},{"nics":null,"status":null,"desktopOperatorType":null,"marker":null,"user_name":null,"user_group":null,"user_email":null,"product_id":null,"image_id":null,"computer_name":"BBBB","desktop_id":null,"created":null,"ip_address":null,"security_groups":null,"root_volume":null,"data_volumes":null,"availability_zone":null,"ou_name":null,"login_status":null,"desktop_ip":null,"ad_id":null}]}
但是json从另一个服务发送,就像:
{"code":200,"message":"查询桌面列表成功","data":[{"nics":"","status":"","metadata":"","desktopOperatorType":"","marker":"","user_name":"csrgzbsjy","user_group":"ADMINISTRATORS","user_email":"","product_id":"","image_id":"","computer_name":"B-jiegou-all-15","desktop_id":"6360ee29-eb82-416b-aab8-18ded887e8ff","created":"2018-11-12T07:45:15.000Z","ip_address":"192.168.2.215","security_groups":"","root_volume":"","data_volumes":"","availability_zone":"","ou_name":"","login_status":"","desktop_ip":"","ad_id":""},{"nics":"","status":"","metadata":"","desktopOperatorType":"","marker":"","user_name":"glory_2147","user_group":"ADMINISTRATORS","user_email":"","product_id":"","image_id":"","computer_name":"H-pkpm-all-357","desktop_id":"709164e4-d3e6-495d-9c1e-a7b82e30bc83","created":"2018-11-09T09:54:09.000Z","ip_address":"192.168.2.235","security_groups":"","root_volume":"","data_volumes":"","availability_zone":"","ou_name":"","login_status":"","desktop_ip":"","ad_id":""}]}
在不启动参数的情况下,您会注意到差异。 小心