网站首页 > java教程 正文
一 业务背景
需要将已保存的json字符串获取,并提取其中的某个字段按“,”拼接为字符串。
二 代码
2.1 实体
public class LangDataLimitDTO implements Serializable {
/** 一级限制类别id */
private Integer typeId;
/** 一级限制类别名称 */
private String typeName;
public LangDataLimitDTO(Integer typeId, String typeName){
this.typeId = typeId;
this.typeName = typeName;
}
2.2 格式转化代码
public String getLangLimitStr(){
if(StringUtils.isEmpty(languageLimitJson)){
return null;
}
List<LangDataLimitDTO> langDataLimitList = JsonUtils.fromJSON(languageLimitJson, new TypeReference<List<LangDataLimitDTO>>(){});
if(CollectionUtils.isEmpty(langDataLimitList)){
return null;
}
StringBuilder sb = new StringBuilder();
for(LangDataLimitDTO langDataLimitDTO : langDataLimitList){
sb.append(langDataLimitDTO.getTypeName()).append(",");
}
return StringUtils.removeEnd(sb.toString(), ",");
}
2.3 工具
/**
*
* 描述:将json字符串转成指定T类型的对象
* 示例:formJSON(jsonString,new MyTypeReference()<List<Map<String,Object>>>)
* @created 2014-4-7 上午10:04:20
* @since v1.0.0
* @param jsonString
* @param typeRef
* @return T
*/
@SuppressWarnings("unchecked")
public static final <T> T fromJSON(String jsonString, TypeReference<T> typeRef) {
if (null == jsonString)
return null;
ByteArrayInputStream bais = new ByteArrayInputStream(jsonString.getBytes());
try {
ObjectInput in = serialization.deserialize(bais);
return (T) in.readObject(typeRef);
} catch (Exception e) {
throw new RuntimeException("Json deserial error.", e);
} finally {
try {
if (null != bais) {
bais.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.4 序列化方式
private static final Serialization serialization = new JacksonSerialization();
三 问题
当使用getLangLimitStr()转化数据时,传入的合法的json串数据,返回的格式化对象为空的问题。
3.1 TypeReference分析
TypeReference为jackson包提供的用于处理泛型类型信息的工具,主要用于反序列化时明确指定目标类型,确保数据转换的准确性。
3.2 原因
1、反射实例化需求
Jackson默认通过反射调用无参构造器创建对象实例,再通过setter方法或字段注入填充属性。若类中仅存在有参构造器而无无参构造器,反射将无法实例化对象,导致反序列化失败。
2、框架设计约束
Jackson的ObjectMapper在反序列化时遵循标准JavaBean规范,要求目标类具备无参构造器以实现通用化处理。这种设计简化了反序列化流程,使其无需预知具体构造逻辑即可重建对象。
3、兼容性考量
无参构造器是Java序列化机制(如java.io.Serializable)和多数ORM框架(如Hibernate)的共同要求。Jackson保持这一约束可确保与其他技术栈的兼容性。
3.3 默认生成问题
默认无参构造方法的行为规则
1、自动生成条件
当类中未显式定义任何构造方法时,Java编译器会自动生成一个默认的无参构造方法(访问修饰符与类相同)。
public class User {} // 编译器会自动添加 public User() {}
2、手动定义覆盖
若类中已定义任意构造方法(包括有参构造),编译器不再自动生成无参构造方法。此时若需无参构造,必须显式声明
public class User {
private String name;
public User(String name) { this.name = name; }
public User() {} // 必须手动添加
}
四 解决
4.1 添加无参构造
public class LangDataLimitDTO implements Serializable {
/** 一级限制类别id */
private Integer typeId;
/** 一级限制类别名称 */
private String typeName;
public LangDataLimitDTO(){
}
public LangDataLimitDTO(Integer typeId, String typeName){
this.typeId = typeId;
this.typeName = typeName;
}
4.2 实现反序列化器
public class ResponseDeserializer extends JsonDeserializer<Response> {
@Override
public Response deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
Map<String, Map<String, String>> map = jsonParser.readValueAs(Map.class);
Map<String, String> headerMap = map.get("headerMap");
Map<String, String> apiMap = map.get("apiMap");
return new Response(headerMap, apiMap);
}
}
将反序列化器注册到 ObjectMapper 中:
public class ObjectMapperUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
static {
SimpleModule simpleModule = new SimpleModule("custom");
simpleModule.addDeserializer(Response.class, new ResponseDeserializer());
objectMapper.registerModule(simpleModule);
}
public static ObjectMapper getObjectMapper() {
return objectMapper;
}
/**
*
* @param object
* @return
*/
public static String writeAsPrettyString(Object object) {
try {
return getObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
猜你喜欢
- 2025-08-31 学会用Go解析复杂JSON的思路_gson解析复杂json
- 2025-08-31 JWT(JSON Web Token) 快速入门_json web token原理
- 2025-08-31 接口自动化测试之JSON Schema模式该如何使用?
- 2025-08-31 Spring Boot程序中@JsonIgnoreProperties与@JsonIgnore基本使用
- 2025-08-31 fastjson自定义序列化竟然有这么多姿势?
- 2025-08-31 图解 Redis String 底层数据结构 SDS 与计数器实战
- 2025-08-31 完全零基础入门Fastjson系列漏洞_fastjson反序列化漏洞 工具
- 2025-08-31 爆肝整理!Python JSON 模块实战手册:从入门到性能封神
- 2025-08-31 JSON.stringify()的使用_json.stringify用法
- 2025-08-31 Hutool JSONUtil巧妙过滤null值:JSON转Map数据清洗的终极方案
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)