fastJson遇到的坑之造轮子实现按优先级将实体类的属性与属性值拼串

文章描述了一位开发者在处理实体类属性拼接时遇到的问题,包括FastJson导致的死循环以及属性值获取的挑战。通过反射获取属性并自定义排序解决了问题,首先排除特定字段,然后将日期字段格式化,并按优先级排序属性。
摘要由CSDN通过智能技术生成

按优先级将实体类的属性与属性值拼串

起因

​ 之前写过一个公共方法,实现对一个表的存储,但是今天报了个测试问题。排查问题的时候发现,如果不把所有字段的值打印出来,不便于问题的定位。但是由于我们的实体类是通过代码生成工具自动生成的,并且没有重写toString。

第一个坑

​ 我们的实体中不光有表中的字段,还有一些别的方法,方法中有查询sql,如果直接用 fastJosn 转json串的话,会死循环,一直会去执行方法中的查询语句。

第二个坑

​ fastJson中可以指定 includes,测试发现指定 includes 可以解决死循环,但是问题又来了,我们的实体的中字段的首字母是大写,fastJson获取不到属性值

        SimplePropertyPreFilter propertyPreFilter = new SimplePropertyPreFilter();
        Set<String> includes = propertyPreFilter.getIncludes();

造轮子

通过反射获取实体的属性和值

代码实现
    /**
     * @description 将实体按照 属性名:值 拼串,并用逗号隔开
     * @author HelloWorld
     * @create 2023/4/5 09:02
     * @param studentSchema
     * @return java.lang.String
     */
    public String getInfo(StudentSchema studentSchema) {
        PropertyDescriptor[] propertyDescriptors;
        try {
            propertyDescriptors = Introspector.getBeanInfo(studentSchema.getClass()).getPropertyDescriptors();
        } catch (IntrospectionException e) {
            log.error("实体解析异常,只打印简单信息", e);
            return getSimpleInfo(studentSchema);
        }

        String resultStr = Stream.iterate(0, n -> n + 1)
                .limit(propertyDescriptors.length - 1)
                .map(index -> {
                    PropertyDescriptor propertyDescriptor = propertyDescriptors[index];
                    String propertyName = propertyDescriptor.getName();
                    Object propertyValue;
                    try {
                        propertyValue = propertyDescriptor.getReadMethod().invoke(studentSchema);
                    } catch (Exception e) {
                        log.error(String.format("获取属性值-%s异常", propertyName), e);
                        propertyValue = null;
                    }
                    return String.format("%s: %s", propertyName, propertyValue);
                }).collect(Collectors.joining(", "));

        return String.format("StudentSchema: {%s}", resultStr);

    }

    /**
     * @description 返回简要信息串
     * @author HelloWorld
     * @create 2023/4/5 09:04
     * @param studentSchema
     * @return java.lang.String
     */
    public String getSimpleInfo(StudentSchema studentSchema) {
        return String.format("StudentSchema: {name: %s, idType: %s, idNo: %s}",
                studentSchema.getName(),
                studentSchema.getIdType(),
                studentSchema.getIdNo());
    }
效果

StudentSchema: {age: 19, birthday: 2001-08-01, class: class com.wy.other.printSchema.StudentSchema, className: null, country: China, happy: null, idNo: 4112991729102121, idType: 00, makeDate: Wed Apr 05 09:05:13 CST 2023, makeTime: 09:05:13, modifyDate: Wed Apr 05 09:05:13 CST 2023, modifyTime: 09:05:13, name: 李白, score: null}

缺陷

拼接的信息有 class字段

第一次优化

  1. 排除掉不想展示的字段
  2. 如果是Date类型的字段, yyyy-MM-dd 格式化
代码
 private static final Set<String> excludes = new HashSet<>(Arrays.asList("class", "modifyDate", "modifyTime"));

    /**
     * @description 将实体按照 属性名:值 拼串,并用逗号隔开
     * @author HelloWorld
     * @create 2023/4/5 09:02
     * @param studentSchema
     * @return java.lang.String
     */
    public String getInfo(StudentSchema studentSchema) {
        PropertyDescriptor[] propertyDescriptors;
        try {
            propertyDescriptors = Introspector.getBeanInfo(studentSchema.getClass()).getPropertyDescriptors();
        } catch (IntrospectionException e) {
            log.error("实体解析异常,只打印简单信息", e);
            return getSimpleInfo(studentSchema);
        }

        String resultStr = Stream.iterate(0, n -> n + 1)
                .limit(propertyDescriptors.length - 1)
                .map(index -> {
                    PropertyDescriptor propertyDescriptor = propertyDescriptors[index];
                    String propertyName = propertyDescriptor.getName();
                    if (excludes.contains(propertyName)) {
                        return null;
                    }
                    Object propertyValue;
                    try {
                        propertyValue = propertyDescriptor.getReadMethod().invoke(studentSchema);
                        propertyValue = propertyValue instanceof Date ? DateUtil.format(DateUtil.parse(propertyValue.toString()), "yyyy-MM-dd") : propertyValue;
                    } catch (Exception e) {
                        log.error(String.format("获取属性值-%s异常", propertyName), e);
                        propertyValue = null;
                    }
                    return String.format("%s: %s", propertyName, propertyValue);
                })
                .filter(StrUtil::isNotBlank)
                .collect(Collectors.joining(", "));

        return String.format("StudentSchema: {%s}", resultStr);

    }

    /**
     * @description 返回简要信息串
     * @author HelloWorld
     * @create 2023/4/5 09:04
     * @param studentSchema
     * @return java.lang.String
     */
    public String getSimpleInfo(StudentSchema studentSchema) {
        return String.format("StudentSchema: {name: %s, idType: %s, idNo: %s}",
                studentSchema.getName(),
                studentSchema.getIdType(),
                studentSchema.getIdNo());
    }

效果

StudentSchema: {age: 19, birthday: 2001-08-01, className: null, country: China, happy: null, idNo: 4112991729102121, idType: 00, makeDate: 2023-04-05, makeTime: 09:36:36, name: 李白, score: null}

第二次优化

  1. 按照指定的优先级 排练字段
  2. 调整代码结构
代码
private static final Set<String> excludes = new HashSet<>(Arrays.asList("class", "modifyDate", "modifyTime"));
    private static final List<String> priorityList;
    static {
        priorityList = Arrays.asList("Name", "IdNo", "Age", "ClassName").stream()
                .map(str -> str.substring(0, 1).toLowerCase() + str.substring(1))
                .sorted(((o1, o2) -> -1))
                .collect(Collectors.toList());
    }

    /**
     * @description 将实体按照 属性名:值 拼串,并用逗号隔开
     * @author HelloWorld
     * @create 2023/4/5 09:02
     * @param studentSchema
     * @return java.lang.String
     */
    public String getInfo(StudentSchema studentSchema) {
        PropertyDescriptor[] propertyDescriptors;
        try {
            propertyDescriptors = Introspector.getBeanInfo(studentSchema.getClass()).getPropertyDescriptors();
        } catch (IntrospectionException e) {
            log.error("实体解析异常,只打印简单信息", e);
            return getSimpleInfo(studentSchema);
        }
        String resultStr = Arrays.stream(propertyDescriptors)
                .map(PropertyDescriptor::getName)
                .filter(name -> !excludes.contains(name))
                .map(name -> {
                    Object value;
                    try {
                        value = new PropertyDescriptor(name, studentSchema.getClass()).getReadMethod().invoke(studentSchema);
                    } catch (Exception e) {
                        log.error(String.format("获取属性值-%s异常", name), e);
                        return null;
                    }
                    if (value instanceof Date) {
                        value = ((Date) value).toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    }
                    return name + ": " + value;
                })
                .filter(StrUtil::isNotBlank)
                .sorted(((o1, o2) -> {
                    o1 = o1.substring(0, o1.lastIndexOf(":"));
                    o2 = o2.substring(0, o2.lastIndexOf(":"));
                    return priorityList.indexOf(o2) - priorityList.indexOf(o1);
                }))
                .collect(Collectors.joining(", "));
        
        return String.format("StudentSchema: {%s}", resultStr);
    }

    
    /**
     * @description 返回简要信息串
     * @author HelloWorld
     * @create 2023/4/5 09:04
     * @param studentSchema
     * @return java.lang.String
     */
    public String getSimpleInfo(StudentSchema studentSchema) {
        return String.format("StudentSchema: {name: %s, idType: %s, idNo: %s}",
                studentSchema.getName(),
                studentSchema.getIdType(),
                studentSchema.getIdNo());
    }

效果

StudentSchema: {name: 李白, idNo: 4112991729102121, age: 19, className: 六年级, birthday: 2001-08-01, country: China, happy: null, idType: 00, makeDate: 2023-04-05, makeTime: 10:11:28, score: null, sex: null}

全部代码

StudentSchema

package com.wy.other.printSchema;

import java.io.StringReader;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author HelloWorld
 * @create 2023/4/4 22:51
 * @email helloworld.dng@gmail.com
 */

public class StudentSchema {
    private String Name;
    private String IdType;

    private String IdNo;

    private String ClassName;

    private String Country;

    private Integer Age;

    private String Birthday;

    private String Happy;

    private String Sex;

    private BigDecimal Score;

    private Date MakeDate;

    private String MakeTime;

    private Date ModifyDate;

    private String ModifyTime;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public String getIdType() {
        return IdType;
    }

    public void setIdType(String idType) {
        IdType = idType;
    }

    public String getIdNo() {
        return IdNo;
    }

    public void setIdNo(String idNo) {
        IdNo = idNo;
    }

    public String getClassName() {
        return ClassName;
    }

    public void setClassName(String className) {
        ClassName = className;
    }

    public String getCountry() {
        return Country;
    }

    public void setCountry(String country) {
        Country = country;
    }

    public Integer getAge() {
        return Age;
    }

    public void setAge(Integer age) {
        Age = age;
    }

    public String getBirthday() {
        return Birthday;
    }

    public void setBirthday(String birthday) {
        Birthday = birthday;
    }

    public String getHappy() {
        return Happy;
    }

    public void setHappy(String happy) {
        Happy = happy;
    }

    public String getSex() {
        return Sex;
    }

    public void setSex(String sex) {
        Sex = sex;
    }

    public BigDecimal getScore() {
        return Score;
    }

    public void setScore(BigDecimal score) {
        Score = score;
    }

    public Date getMakeDate() {
        return MakeDate;
    }

    public void setMakeDate(Date makeDate) {
        MakeDate = makeDate;
    }

    public String getMakeTime() {
        return MakeTime;
    }

    public void setMakeTime(String makeTime) {
        MakeTime = makeTime;
    }

    public Date getModifyDate() {
        return ModifyDate;
    }

    public void setModifyDate(Date modifyDate) {
        ModifyDate = modifyDate;
    }

    public String getModifyTime() {
        return ModifyTime;
    }

    public void setModifyTime(String modifyTime) {
        ModifyTime = modifyTime;
    }
}

Print

package com.wy.other.printSchema;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author HelloWorld
 * @create 2023/4/4 22:54
 * @email helloworld.dng@gmail.com
 */
@Slf4j
public class Print {
    private static final Set<String> excludes = new HashSet<>(Arrays.asList("class", "modifyDate", "modifyTime"));
    private static final List<String> priorityList;
    static {
        priorityList = Arrays.asList("Name", "IdNo", "Age", "ClassName").stream()
                .map(str -> str.substring(0, 1).toLowerCase() + str.substring(1))
                .sorted(((o1, o2) -> -1))
                .collect(Collectors.toList());
    }

    /**
     * @description 将实体按照 属性名:值 拼串,并用逗号隔开
     * @author HelloWorld
     * @create 2023/4/5 09:02
     * @param studentSchema
     * @return java.lang.String
     */
    public String getInfo(StudentSchema studentSchema) {
        PropertyDescriptor[] propertyDescriptors;
        try {
            propertyDescriptors = Introspector.getBeanInfo(studentSchema.getClass()).getPropertyDescriptors();
        } catch (IntrospectionException e) {
            log.error("实体解析异常,只打印简单信息", e);
            return getSimpleInfo(studentSchema);
        }
        String resultStr = Arrays.stream(propertyDescriptors)
                .map(PropertyDescriptor::getName)
                .filter(name -> !excludes.contains(name))
                .map(name -> {
                    Object value;
                    try {
                        value = new PropertyDescriptor(name, studentSchema.getClass()).getReadMethod().invoke(studentSchema);
                    } catch (Exception e) {
                        log.error(String.format("获取属性值-%s异常", name), e);
                        return null;
                    }
                    if (value instanceof Date) {
                        value = ((Date) value).toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
                    }
                    return name + ": " + value;
                })
                .filter(StrUtil::isNotBlank)
                .sorted(((o1, o2) -> {
                    o1 = o1.substring(0, o1.lastIndexOf(":"));
                    o2 = o2.substring(0, o2.lastIndexOf(":"));
                    return priorityList.indexOf(o2) - priorityList.indexOf(o1);
                }))
                .collect(Collectors.joining(", "));
        return String.format("StudentSchema: {%s}", resultStr);
    }


    /**
     * @description 返回简要信息串
     * @author HelloWorld
     * @create 2023/4/5 09:04
     * @param studentSchema
     * @return java.lang.String
     */
    public String getSimpleInfo(StudentSchema studentSchema) {
        return String.format("StudentSchema: {name: %s, idType: %s, idNo: %s}",
                studentSchema.getName(),
                studentSchema.getIdType(),
                studentSchema.getIdNo());
    }

    public static void main(String[] args) {
        Print print = new Print();
        System.out.println(print.getInfo(getTestData()));
    }


    private static StudentSchema getTestData() {
        StudentSchema studentSchema = new StudentSchema();
        studentSchema.setName("李白");
        studentSchema.setAge(19);
        studentSchema.setBirthday("2001-08-01");
        studentSchema.setCountry("China");
        studentSchema.setIdNo("4112991729102121");
        studentSchema.setIdType("00");
        studentSchema.setMakeDate(new Date());
        studentSchema.setMakeTime(DateUtil.formatTime(new Date()));
        studentSchema.setModifyDate(new Date());
        studentSchema.setModifyTime(DateUtil.formatTime(new Date()));
        studentSchema.setClassName("六年级");

        return studentSchema;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 将实体类转换为FastJson是在Java中使用FastJson库来实现实体类对象与Json字符串之间的相互转换。下面是一个示例: 首先,首先需要引入FastJson的依赖,以及相关的Jackson库: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> ``` 接下来,假设我们有一个实体类Person: ```java public class Person { private String name; private int age; // 省略getter和setter方法 } ``` 我们可以使用FastJson库将Person对象转换为Json字符串: ```java import com.alibaba.fastjson.JSON; public class Main { public static void main(String[] args) { Person person = new Person(); person.setName("Alice"); person.setAge(20); String jsonString = JSON.toJSONString(person); System.out.println(jsonString); } } ``` 上述代码中,我们使用`JSON.toJSONString()`方法将Person对象转换为Json字符串。输出的结果为`{"age":20,"name":"Alice"}`。 同样地,我们也可以将Json字符串转换为Person对象: ```java import com.alibaba.fastjson.JSON; public class Main { public static void main(String[] args) { String jsonString = "{\"age\":20,\"name\":\"Alice\"}"; Person person = JSON.parseObject(jsonString, Person.class); System.out.println(person.getName()); System.out.println(person.getAge()); } } ``` 上述代码中,我们使用`JSON.parseObject()`方法将Json字符串转换为Person对象。输出的结果为: ``` Alice 20 ``` 总结:通过上述示例,我们可以看到使用FastJson可以很方便地实现实体类对象与Json字符串之间的转换。只需要引入FastJson的依赖以及Jackson库,就可以进行转换操作。 ### 回答2: 在Java中,我们可以使用Fastjson库将实体类转换为JSON字符串。Fastjson是一个高性能的Java JSON处理器,可以快速将Java对象转换为JSON字符串。 要将实体类转换为Fastjson,我们需要按照以下步骤进行操作: 1. 导入Fastjson库。在项目中,我们需要先将Fastjson库添加到项目的依赖中。可以在Maven或Gradle配置文件中添加相关依赖项。 2. 创建一个实体类。假设我们的实体类名为Person,它具有一些属性,如姓名、年龄等。 3. 在代码中创建Person对象,并设置相应的属性。 4. 使用Fastjson将Person对象转换为JSON字符串。可以通过调用Fastjson库提供的相关API,如toJSONString()方法,将Person对象转换为JSON字符串。例如,String jsonString = JSON.toJSONString(person); 5. 打印或处理生成的JSON字符串。可以将生成的JSON字符串打印出来,或者根据需要进行其他处理,如存储到文件中。 通过以上步骤,我们可以将实体类转换为JSON字符串,然后可以根据需要进行后续的操作,如传递给其他系统、存储到数据库等。 需要注意的是,Fastjson默认情况下按照实体类属性顺序来生成JSON字符串,如果需要按照自定义的顺序生成JSON字符串,可以在实体类中使用注解或配置指定属性的顺序。此外,Fastjson还支持将JSON字符串转换回Java对象的功能,可以方便地在Java程序中进行JSON数据的读取和解析操作。 ### 回答3: 将实体类转换为Fastjson可以通过以下步骤实现: 首先,确保已经引入Fastjson库。可以通过在pom.xml文件中添加以下依赖项来引入Fastjson: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>x.x.x</version> </dependency> ``` 其中,x.x.x是Fastjson库的版本号。 接下来,需要将实体类属性和对应的转换为Fastjson的JSONObject对象。可以通过创建一个新的JSONObject对象,并使用put方法将属性添加到JSONObject中: ```java import com.alibaba.fastjson.JSONObject; public class Entity { private String name; private int age; // getter and setter methods public JSONObject toJSON() { JSONObject json = new JSONObject(); json.put("name", this.name); json.put("age", this.age); return json; } } ``` 上述代码中,toJSON方法将实体类属性和对应的添加到JSONObject对象中,并返回该JSONObject对象。 最后,可以通过调用toJSON方法,将实体类转换为Fastjson的JSON对象: ```java public class Main { public static void main(String[] args) { Entity entity = new Entity(); entity.setName("John"); entity.setAge(25); JSONObject json = entity.toJSON(); System.out.println(json.toJSONString()); } } ``` 上述代码中,首先创建一个实体类的实例entity,并设置其属性。然后,调用entity的toJSON方法,将实体类转换为Fastjson的JSONObject对象。最后,通过调用JSON对象的toJSONString方法,将JSON对象转换为字符串,并打印输出。 以上就是将实体类转换为Fastjson的一个简单示例。实际使用中,根据实体类属性情况,可以灵活地使用Fastjson提供的方法来实现转换。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值