专业的JAVA编程教程与资源

网站首页 > java教程 正文

Json数据格式化问题_json数据格式化问题怎么解决

temp10 2025-08-31 13:48:43 java教程 4 ℃ 0 评论

一 业务背景

需要将已保存的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串数据,返回的格式化对象为空的问题。

Json数据格式化问题_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;
    }
}

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表