When using FastJson parseObject method, JSON string parsed into objects, some attributes missing Problem

The reason for such problems there will be many, this article describes only found one case, not necessarily applicable to all scenarios

 

scene:

  JavaBean no default constructor

 

E.g:

public class Student{


    public static void main(String[] args) {
        String jsonStr = "{\"id\":1,\"name\":\"Ming\",\"age\":18,\"phone\":\"23333333333\",\"address\":\"杭州\"}";
        Student student = JSON.parseObject(jsonStr, Student.class);
        System.out.println(JSON.toJSONString(student));
    }


    private Long id;
    private String name;
    private Integer age;
    private String address;
    private String phone;

    public Student(Long id, String name,String phone) {
        this.id = id;
        this.name = name;
        this.phone = phone;
    }


    public Student(Long id, String name, Integer age, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

运行结果: {"address":"杭州","age":18,"id":1,"name":"Ming"}

In this case parsed into objects, attributes phone is lost. Although there is a structure with a phone field.

 

the reason:

  FastJson create a JavaBean, call

# Will call the constructor
 new new JavaBeanDeserializer ( the this , clazz, of the type); 

# constructor details 
public JavaBeanDeserializer (<?> ParserConfig config, Class clazz, Type of the type) {
         the this (config //
                 , JavaBeanInfo.build (clazz, of the type, config.propertyNamingStrategy, config.fieldBased, config.compatibleWithJavaBean, config.isJacksonCompatible ()) 
        ); 
    } 

#build snippet method determines which constructor is used 
for (the constructor constructor: constructors) { 
                        Class [] the parameterTypes = <?> constructor. getParameterTypes (); 

                        IF (className.equals("org.springframework.security.web.authentication.WebAuthenticationDetails")) {
                            if (parameterTypes.length == 2 && parameterTypes[0] == String.class && parameterTypes[1] == String.class) {
                                creatorConstructor = constructor;
                                creatorConstructor.setAccessible(true);
                                paramNames = ASMUtils.lookupParameterNames(constructor);
                                break;
                            }
                        }

                        if (className.equals("org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken")) {
                            if (parameterTypes.length == 3
                                    && parameterTypes[0] == Object.class
                                    && parameterTypes[1] == Object.class
                                    && parameterTypes[2] == Collection.class) {
                                creatorConstructor = constructor;
                                creatorConstructor.setAccessible(true);
                                paramNames = new String[] {"principal", "credentials", "authorities"};
                                break;
                            }
                        }

                        if (className.equals("org.springframework.security.core.authority.SimpleGrantedAuthority")) {
                            if (parameterTypes.length == 1
                                    && parameterTypes[0] == String.class) {
                                creatorConstructor = constructor;
                                paramNames = new String[] {"authority"};
                                break;
                            }
                        }

                        //


                        boolean is_public = (constructor.getModifiers() & Modifier.PUBLIC) != 0;
                        if (!is_public) {
                            continue;
                        }
                        String[] lookupParameterNames = ASMUtils.lookupParameterNames(constructor);
                        if (lookupParameterNames == null || lookupParameterNames.length == 0) {
                            continue;
                        }

                        if(! creatorConstructor = null 
                                && paramnames =! null && lookupParameterNames.length <= paramNames.length) {
                             Continue ; 
                        } 

                        paramnames = lookupParameterNames; 
                        creatorConstructor = constructor; 
                    } 

# Analyzing the sentence can be seen, all current constructor iterates the JavaBean, and takes the longest to the constructor method that list constructor, as JSON parsing a constructor.

IF (creatorConstructor! = null && paramnames! = null && lookupParameterNames.length <= paramNames.length) {
    continue;
}


 

As can be seen from the above code, why missing phone properties. The method parameter list is not the longest configuration attributes phone

 

Solution:

  1. Add a default constructor

       2. The method of parameter lists longest constructor new attributes phone (if the code has been running for a long time, the proposed new constructors, methods longest parameter list, and includes the phone field)

 

Guess you like

Origin www.cnblogs.com/lzzRye/p/12625800.html