阿里fastjson使用笔记,parseObject问题,输出下划线格式,json格式化等,不打印base64等

本文详细介绍了阿里FastJSON库的基本使用方法,包括如何将对象转换为JSON字符串、从JSON字符串转换回对象的过程,以及解决序列化过程中遇到的一些常见问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


json工具中,fastjson是主流中的一种。

maven引入

pom.xml中添加:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.58</version>
</dependency>

代码:

public class JsonTest {
    public static void main(String[] args) {
        Map<Integer, Object> map = new HashMap<Integer,Object>();
        ArrayList<Person> list = new ArrayList<Person>();
        Person person = new JsonTest().new Person();
        Person person2 = new JsonTest().new Person();
        person.setName("张飞");
        person.setAge("28");
        person2.setName("guanyu");
        person2.setAge("30");
        list.add(person);
        list.add(person2);
        map.put(1, "String1");
        map.put(2, "String2");
        map.put(3, list);

        String jsonString = JSON.toJSONString(map);
        System.out.println(jsonString);
        JSONObject jsonObject = JSON.parseObject(jsonString);
        String string1 = jsonObject.getString("1");
        String string2 = jsonObject.getString("2");
        JSONArray list1 = jsonObject.getJSONArray("3");
        System.out.println(list1);
        System.out.println(list1.get(0));
    }

    class Person{
        private String name;
        private String age;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getAge() {
            return age;
        }

        public void setAge(String age) {
            this.age = age;
        }
    }
}

**对象 ==> jsonString **

JSON.toJSONString(map);

**jsonString ==> obj **

JSON.parseObject(jsonString);

当然也可以转换为某个类的对象,代码:

@Data
@Entity
public class Person {
    private static final Logger logger = LoggerFactory.getLogger(Person.class);
    @Id
    private Long id;
    private String name;

    public static void main(String[] args) {
        Person person = new Person();
        person.setId(159L);
        person.setName("chushiyun");
        String s = JSON.toJSONString(person);
        logger.info("json 字符串是:{}",s);
        
        Person person1 = JSON.parseObject(s, Person.class);
        logger.info(person1.toString());
    }
}

如果字段有不一致的时候,那么可以加@JSONField注解,序列化和解析的时候就会按照这个字段来解析,如代码:

@Data
@Entity
public class PersonManage {
    @Id
    private Long id;
    @JSONField(name="name")
    private String manageName;
}

拓展: JSON.parseObject一个空对象会报错吗?

好问题,一起来看一下。
JSON.parseObject一个空对象会报错吗?(null);
不会。
但是要注意,返回的是个null对象,如果继续调用方法,会报错。

用代码验证下:

// 这句不会报错
JSONObject jsonObject = JSON.parseObject(null);
// 这句会报错
// 因为之前返回的JsonObject是null,调用任何方法都会报错
String string = jsonObject.getString("username");

如果是Resource资源,使用Json序列化容易有问题

序列化之后,发现文件变成非正常文件了。
代码:

Path path = Paths.get("d:\\", filename);
Resource resource = resourceLoader.getResource("file:" + path.toString());
logger.info("resource:{}",JSON.toJSONString(resource)); // 都是这句json惹的祸,页面输出不了

目前还不知道原理,总之,在序列化Resource资源的时候要小心。

parseObject遇到的问题

解析复杂对象的时候直接使用parseObject会有问题,要用这种解析方式:

JsonResult<MultiModel> redisJsonResult = JSON.parseObject(jsonString, new TypeReference<JsonResult<MultiModel>>() {});

输出下划线格式

标准产品是下划线格式,日志也打印为下划线格式直接就能复用,否则还需要转您换。

public static void main(String[] args) {
    SerializeConfig serializeConfig=new SerializeConfig();
    serializeConfig.propertyNamingStrategy= PropertyNamingStrategy.SnakeCase;
    User user= new User ();
    user.setUsername("asdfad");
    log.info(JSON.toJSONString(user,serializeConfig));

}

发现果然是下划线格式了。

json打印设置输出空字符串

默认是不打印空字符串的,但是有时需要打印,例如写接口文档,打印出来空值比较方便。

代码:

SerializeConfig config = new SerializeConfig();
UserRequest request= new UserRequest ();
String content = JSON.toJSONString(request, config,
        SerializerFeature.WriteNullNumberAsZero,
        SerializerFeature.WriteNullListAsEmpty,
        SerializerFeature.WriteNullStringAsEmpty,
        SerializerFeature.WriteNullBooleanAsFalse);
log.info(content);

那么list呢?
实际如果list为空,即使做了如上设置,也是打印不出来的
解决方案:
1、list中添加一个有值对象。

实际上写接口文档时,list中的类单独打印出来也是可以的。

其他

controller初始化的时候可以设置本类的json接收?(待办)

不打印base64,file等

base64太长,打印非常影响查日志,而且没什么实际意义。file则是不好打印。
所以打印日志时最好去掉这两种。

json自带这种机制,配置下即可。代码是网上通用的代码:

public static SimplePropertyPreFilter filePropertyPreFilter=null ;
static{
    filePropertyPreFilter=new SimplePropertyPreFilter();
    filePropertyPreFilter.getExcludes().add("file");
    filePropertyPreFilter.getExcludes().add("base64String");
}
    
JSON.toJSONString(request, CustomJsonUtils.filePropertyPreFilter);

这里是根据属性名进行过滤。

报错 JSON parse error: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

报错信息为:
JSON parse error: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

问题原因:
这是因为 userList 是个list,报文写错了,用的大括号。
其实应该是 []。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值