Press "Enter" to skip to content

JSON序列化导致Long类型被搞成Integer

背景:

昨天在调试接口的时候总是报错,服务的截图错误信息为: java.lang.Integer cannot be cast to java.lang.Long

分析:

我写的是一个通用服务,接受数据的时候,jackson框架将json里面的对象数据用Map<String,Object>来接,我们也知道json是没有long类型的概念的,比如我传入的数据:

{
  "value1": "12345", 
  "value2": 67890
}

尽管我java类原本认为value2是Long类型,但是跑到json里面之后,他就只能变成这种不带引号的数值。

反解析成java对象之后,可能这个Long类型就丢了。

解决:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class CustomDeserializer extends JsonDeserializer<Object> {
    private final UntypedObjectDeserializer delegate;

    public CustomDeserializer() {
        this.delegate = new UntypedObjectDeserializer(null, null);
    }

    @Override
    public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        Object m = delegate.deserialize(p, ctxt);
        return recursivelyProcessValue(m);
    }

    private Object recursivelyProcessValue(Object value) {
        if (value instanceof Map) {
            Map<String, Object> map = (Map<String, Object>) value;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                entry.setValue(recursivelyProcessValue(entry.getValue()));
            }
        } else if (value instanceof List) {
            List<Object> list = (List<Object>) value;
            for (int i = 0; i < list.size(); i++) {
                list.set(i, recursivelyProcessValue(list.get(i)));
            }
        } else if (value instanceof String) {
            String strValue = (String) value;
            if (strValue.startsWith("@JSON_TYPE_LONG:")) {
                Long longValue = Long.parseLong(strValue.substring("@JSON_TYPE_LONG:".length()));
                return longValue;
            }
        }
        return value;
    }
}

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Object.class, new CustomDeserializer ());
        objectMapper.registerModule(module);
        return objectMapper;
    }
}

这样我们只需要将long类型的字段的值写成格式类似:”@JSON_TYPE_LONG:12345″ 的形式就行了。

或者为了稳妥起见,你可以将Jackson框架转换过后的对象根据你的需要将他用recursivelyProcessValue函数处理一下就行了,这个函数会递归找值满足条件的进行修改。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注