版权声明:本文为【欧阳鹏】原创文章,欢迎转载,转载请注明出处! 【http://blog.csdn.net/ouyang_peng】 https://blog.csdn.net/qq446282412/article/details/82492314
一、问题描述
今天在使用Jackson解析json字符串的时候,报了如下所示的错误
09-07 09:08:11.013 13311-13418/com.xtc.data.demo E/com.xtc.bigdata.common.utils.JSONUtil:
com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type,
class com.xtc.bigdata.collector.config.FilterInfoBean] from String value ('k'); no single-String
constructor/factory method
at [Source: [B@b8ddf88; line: 1, column: 1],
jsonStr:"k":"filter_key","isVisible":true,"description":"功能开关",
"v":[{"functionName":"func_test1","packageName":"packageName1"},
{"functionName":"func_test2","packageName":"packageName2"}]},
classType:com.xtc.bigdata.collector.config.FilterInfoBean
二、分析问题
从什么的提示可以看出来,提示我们
no single-String constructor/factory method
没有 单个字符串构造/工厂方法。
我们先来看看 修改之前的代码
- FilterInfoBean.java
上面解析使用的FilterInfoBean代码如下所示:
package com.xtc.bigdata.collector.config;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;
/**
* 大数据的过滤信息封装实体类
* </p>
* created by OuyangPeng at 2018/9/6 下午 05:24
* @author OuyangPeng
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class FilterInfoBean {
private String k;
private boolean isVisible;
private String description;
private List<FilterFunctionItem> v;
public String getK() {
return k;
}
public void setK(String k) {
this.k = k;
}
public boolean isIsVisible() {
return isVisible;
}
public void setIsVisible(boolean isVisible) {
this.isVisible = isVisible;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<FilterFunctionItem> getV() {
return v;
}
public void setV(List<FilterFunctionItem> v) {
this.v = v;
}
@Override
public String toString() {
return "FilterInfoBean{" +
"k='" + k + '\'' +
", isVisible=" + isVisible +
", description='" + description + '\'' +
", v=" + v +
'}';
}
}
- FilterFunctionItem.java
上面使用到的FilterFunctionItem,代码如下
package com.xtc.bigdata.collector.config;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class FilterFunctionItem {
/**
* 需要过滤的functionName
*/
private String functionName;
/**
* 需要过滤的packageName
*/
private String packageName;
public String getFunctionName() {
return functionName;
}
public void setFunctionName(String functionName) {
this.functionName = functionName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
@Override
public String toString() {
return "FilterFunctionItem{" +
"functionName='" + functionName + '\'' +
", packageName='" + packageName + '\'' +
'}';
}
}
- JSONUtil.java
json使用的Jackson的封装Util类,代码如下:
package com.xtc.bigdata.common.utils;
import android.util.Log;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.xtc.log.LogUtil;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
/**
* JSON转换工具类
*/
public class JSONUtil {
private static String TAG = JSONUtil.class.getName();
private static ObjectMapper mapper = new ObjectMapper();
static {
//对于为null的字段不进行序列化
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
//对于未知属性不进行反序列化
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
//无论对象中的值只有不为null的才进行序列化
mapper.setSerializationInclusion(Include.NON_NULL);
}
/**
* 把对象转化成json字符串
*
* @param obj
* @return
*/
public static String toJSON(Object obj) {
if (obj == null) {
return null;
}
Writer write = new StringWriter();
try {
mapper.writeValue(write, obj);
} catch (JsonGenerationException e) {
Log.e(TAG, e.toString() + obj);
} catch (JsonMappingException e) {
Log.e(TAG, e.toString() + obj);
} catch (IOException e) {
Log.e(TAG, e.toString() + obj);
}
return write.toString();
}
/**
* JSON字符串转成对象
*
* @param jsonStr
* @param classType
* @return
*/
public static <T> T fromJSON(String jsonStr, Class<T> classType) {
if (isEmptyOrNull(jsonStr)) {
return null;
}
T t = null;
try {
t = mapper.readValue(jsonStr.getBytes("utf-8"), classType);
} catch (JsonParseException e) {
Log.e(TAG, e.toString() + ", jsonStr:" + jsonStr + ", classType:" + classType.getName());
} catch (JsonMappingException e) {
Log.e(TAG, e.toString() + ", jsonStr:" + jsonStr + ", classType:" + classType.getName());
} catch (IOException e) {
Log.e(TAG, e.toString() + ", jsonStr:" + jsonStr + ", classType:" + classType.getName());
}
return t;
}
/**
* 判断字符串是否为null或者""
*/
private static boolean isEmptyOrNull(String content) {
return content == null || "".equals(content);
}
/**
* JSON字符串转化成集合
*
* @param jsonStr
* @return
*/
public static <T> T toCollection(String jsonStr, Class<?> collectionClass, Class<?>... elementClasses) {
if (isEmptyOrNull(jsonStr)) {
return null;
}
T t = null;
try {
t = mapper.readValue(jsonStr.getBytes("utf-8")
, mapper.getTypeFactory().constructParametricType(collectionClass, elementClasses));
} catch (JsonParseException e) {
LogUtil.e(e);
Log.e(TAG, e.toString() + ", jsonStr:" + jsonStr);
} catch (JsonMappingException e) {
LogUtil.e(e);
Log.e(TAG, e.toString() + ", jsonStr:" + jsonStr);
} catch (IOException e) {
Log.e(TAG, e.toString() + ", jsonStr:" + jsonStr);
}
return t;
}
public static Object get(String jsonStr, String key) {
Object obj = null;
try {
JSONObject jsonObj = new JSONObject(jsonStr);
obj = jsonObj.get(key);
} catch (JSONException e) {
LogUtil.e(e);
}
return obj;
}
}
三、添加单个字符串构造方法
将上面使用到的FilterInfoBean,添加一个单个字符串构造方法,如下所示
package com.xtc.bigdata.collector.config;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;
/**
* 大数据的过滤信息封装实体类
* </p>
* created by OuyangPeng at 2018/9/6 下午 05:24
* @author OuyangPeng
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class FilterInfoBean {
private String k;
private boolean isVisible;
private String description;
private List<FilterFunctionItem> v;
public FilterInfoBean(String k){
this.k = k;
}
public String getK() {
return k;
}
public void setK(String k) {
this.k = k;
}
public boolean isIsVisible() {
return isVisible;
}
public void setIsVisible(boolean isVisible) {
this.isVisible = isVisible;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<FilterFunctionItem> getV() {
return v;
}
public void setV(List<FilterFunctionItem> v) {
this.v = v;
}
@Override
public String toString() {
return "FilterInfoBean{" +
"k='" + k + '\'' +
", isVisible=" + isVisible +
", description='" + description + '\'' +
", v=" + v +
'}';
}
}
然后重新运行程序,发现又有一个新的错误出现了,如下所示:
09-07 10:00:55.431 4721-4721/com.xtc.data.demo E/com.xtc.bigdata.common.utils.JSONUtil:
com.fasterxml.jackson.databind.JsonMappingException:
No suitable constructor found for type [simple type,
class com.xtc.bigdata.collector.config.FilterInfoBean]:
can not instantiate from JSON object (missing default constructor or creator,
or perhaps need to add/enable type information?)
at [Source: [B@e1fe848; line: 1, column: 2], jsonStr:
{"k":"filter_key","isVisible":true,"description":"功能开关",
"v":[{"functionName":"func_test1","packageName":"packageName1"},
{"functionName":"func_test2","packageName":"packageName2"}]},
classType:com.xtc.bigdata.collector.config.FilterInfoBean
好家伙,居然提示我
can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
不能从JSON对象实例化(缺少默认构造函数或创建者,或者可能需要添加/启用类型信息)
好吧,就按照你的提示,再加一个默认的构造方法,如下所示
package com.xtc.bigdata.collector.config;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;
/**
* 大数据的过滤信息封装实体类
* </p>
* created by OuyangPeng at 2018/9/6 下午 05:24
* @author OuyangPeng
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class FilterInfoBean {
private String k;
private boolean isVisible;
private String description;
private List<FilterFunctionItem> v;
public FilterInfoBean(){
}
public FilterInfoBean(String k){
this.k = k;
}
public String getK() {
return k;
}
public void setK(String k) {
this.k = k;
}
public boolean isIsVisible() {
return isVisible;
}
public void setIsVisible(boolean isVisible) {
this.isVisible = isVisible;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<FilterFunctionItem> getV() {
return v;
}
public void setV(List<FilterFunctionItem> v) {
this.v = v;
}
@Override
public String toString() {
return "FilterInfoBean{" +
"k='" + k + '\'' +
", isVisible=" + isVisible +
", description='" + description + '\'' +
", v=" + v +
'}';
}
}
此时再运行程序,即可正常解析出来了。
运行之后的日志打印
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:https://blog.csdn.net/ouyang_peng/article/details/82426092☞ 本人QQ: 3024665621
☞ QQ交流群: 123133153
☞ github.com/ouyangpeng
☞ [email protected]
如果本文对您有所帮助,欢迎您扫码下图所示的支付宝和微信支付二维码对本文进行打赏。