fastjson 自定义类型转换 对象转换

Posted bohu83

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了fastjson 自定义类型转换 对象转换相关的知识,希望对你有一定的参考价值。

一 背景

有个项目从dubbo接口改为http接口,测试的时候发现大部分接口正常,个别接口报错。

post传的类里面有自定义类型:SHORTDATE。其实不是标准date类型,只有”YYYY-MM-DD“

报错信息如下:

Caused by: com.alibaba.fastjson.JSONException: syntax error, expect , actual string, pos 116, fieldName birthday, fastjson-version 1.2.83
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:506)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:291)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:287)
	at com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer.parseField(DefaultFieldDeserializer.java:88)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseField(JavaBeanDeserializer.java:1278)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:893)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.parseRest(JavaBeanDeserializer.java:1624)
	at com.alibaba.fastjson.parser.deserializer.FastjsonASMDeserializer_19_HealthProblem.deserialze(Unknown Source)
	at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.deserialze(JavaBeanDeserializer.java:287)
	at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:705)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:394)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:476)
	at com.alibaba.fastjson.JSON.parseObject(JSON.java:584)
	at com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter.readType(FastJsonHttpMessageConverter.java:265)
	... 68 common frames omitted

解决:

问题毕叫明显,处在自定义类型上了,网上我看有两种办法,一种是

@JSONField(serializeUsing = XXSerializerSerializer.class)

这个类是在API里面的,我试了下,不起作用。

1 开发自定义序列方式。ObjectSerializer和ObjectDeserializer分别是fastjson的序列化、反序列化方式。

看下接口

package com.alibaba.fastjson.serializer;

import java.io.IOException;
import java.lang.reflect.Type;

public interface ObjectSerializer 
    void write(JSONSerializer var1, Object var2, Object var3, Type var4, int var5) throws IOException;

package com.alibaba.fastjson.parser.deserializer;

import com.alibaba.fastjson.parser.DefaultJSONParser;
import java.lang.reflect.Type;

public interface ObjectDeserializer 
    <T> T deserialze(DefaultJSONParser var1, Type var2, Object var3);

    int getFastMatchToken();

常见类型能别正常解析,就是有对应的Codec

所以我们也有参照这个来实现, 为了简单,就都写一起了

public class XXTimeDeSerializer implements ObjectSerializer, ObjectDeserializer 

    @Override
    public  <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) 
        String str = parser.lexer.stringVal();
        if (str == null || str.trim().equals("")) 
            return null;
         else 
            return new MDateTime(str);
        
    

    @Override
    public int getFastMatchToken() 
        return 0;
    

    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException 
        SerializeWriter out = serializer.getWriter();
        if (object == null) 
            return;
         else if (object.toString().trim().equals("")) 
            return;
        
        out.writeString(object.toString());
    

这个名字可以自定义。

这是个springboot 项目,所以有两种办法,一种是通过SerializeConfig静态全局设置

static 
   SerializeConfig.globalInstance.put(XXTime.class, XXTimeDeSerializer);
   ParserConfig.global.putDeserializer(XXTime.class, XXTimeDeSerializer);

还可以用注解

@Configuration//1个配置文件
public class MassageConverConfiguration 

    @Autowired
    private XXTimeDeSerializer shortDateSerializer;
    
    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() 
 FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        
        fastJsonHttpMessageConverter.getFastJsonConfig().getSerializeConfig().put(ShortDate.class, shortDateSerializer);
        fastJsonHttpMessageConverter.getFastJsonConfig().getParserConfig().putDeserializer(ShortDate.class, shortDateSerializer);
        return new HttpMessageConverters(fastJsonHttpMessageConverter);
    

还有一些类似的枚举类,enum 是跟这个一个逻辑。

以上是关于fastjson 自定义类型转换 对象转换的主要内容,如果未能解决你的问题,请参考以下文章

FastJson转换自定义枚举类

用fastjson 的json String格式转换成bean对象的Date类型的时候出错??

fastjson使用泛型转换对象

fastjson中对象转换中看到的一些现象

fastjson中对象转换中看到的一些现象

我们可以在 javascript 中将通用对象转换为自定义对象类型吗?