[fastjson2.x record] those pits stepped on from upgrading from 1.x to 2.x

This article mainly records some problems after upgrading to fastjson2.x version 

1. The jar package import problem

Description of the problem: From the 2.x version, fastjson seems to have begun to split the code modules, so when adjusting the configuration, you will find that some classes suddenly disappear. In fact, you need to introduce other extension packages.

Starting from version 2.0.22, the following three jar packages need to be imported

    <dependency>
      <groupId>com.alibaba.fastjson2</groupId>
      <artifactId>fastjson2</artifactId>
    </dependency>

    <dependency>
      <groupId>com.alibaba.fastjson2</groupId>
      <artifactId>fastjson2-extension</artifactId>
    </dependency>

    <dependency>
      <groupId>com.alibaba.fastjson2</groupId>
      <artifactId>fastjson2-extension-spring5</artifactId>
    </dependency>

In the original 2.x version, only the first two jar packages need to be introduced, and I want to update the new version later. Good guy, I have created a fastjson2-extension-spring5, which actually separates some related configuration classes of spring.

 The most used should be the serialization class of redis and the message parser of http.

2. Problems with the writeXXX method of the custom serialized ObjectWriter class

Description of the problem: The write method of SerializeWriter in version 1.x is not provided by ObjectWriter in version 2.x. Instead, it provides many different writeXXX methods that match different return types, such as the writeString method, which returns a character type.

Previously, the system used version 1.2.83 and wrote a custom serialization class that serializes LocalDateTime into timestamp milliseconds, using the write method of SerializeWriter.

public class DateJsonSerializer implements ObjectSerializer {

    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
        SerializeWriter out = serializer.getWriter();
        if (object == null) {
            serializer.getWriter().writeNull();
            return;
        }
        if (object instanceof LocalDateTime) {
            LocalDateTime localDateTime = (LocalDateTime) object;
            out.write(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli() + "");
        }
    }
}

The controller test code is as follows

    @GetMapping("/test")
    public DemoTestResponse test() {

        DemoTestResponse response = new DemoTestResponse();

        response.setDateTime(LocalDateTime.now());

        return response;
    }

The return object is as follows

@Data
public class DemoTestResponse {

    @JSONField(name = "date_time", serializeUsing = DateJsonSerializer.class)
    private LocalDateTime dateTime;

}

After running postman, the result is as follows. You can see that the custom serialization has taken effect, and a numeric timestamp is returned.

 After upgrading to version 2.x, this custom serialization class was rewritten as follows

public class DateJsonSerializer implements ObjectWriter {

    @Override
    public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
        if (object == null) {
            jsonWriter.writeNull();
            return;
        }

        if (object instanceof LocalDateTime) {
            LocalDateTime localDateTime = (LocalDateTime) object;
            jsonWriter.writeString(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()+"");
        }
    }
}

The writeString method of JSONWriter is used here, which is also the problem. Still run the above method, the returned result is as follows, and it becomes a string.

Because I didn't pay attention at the time, I thought that writeString meant that the parameter was a string type and used it. In fact, the JSONWriter class provides many writeXXX methods.

 Here we should use the writeMillis method, as shown below

    @Override
    public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
        if (object == null) {
            jsonWriter.writeNull();
            return;
        }

        if (object instanceof LocalDateTime) {
            LocalDateTime localDateTime = (LocalDateTime) object;
            jsonWriter.writeMillis(localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
    }

The running results are as follows, and the problem is solved. 

3. JSONField annotation smart matching fails

Description of the problem: When using version 1.x, the field uses @JSONField(name = "openid"), the field name passed from the front end is open_id, and the interface can operate normally. But when upgrading to version 2.x, it is empty.

This is a deeply hidden bug. It is estimated that it was not noticed when the interface was developed at that time, and the interface has been able to run normally. But when upgrading to version 2.x, something went wrong.

In fact, this is due to the smart matching of fastjson, ignoring case and underscore, and still successfully mapping json. However, after version 2.x, it seems that smart matching is not enabled by default, so the mapping fails.

The author tried to enable smart matching, but it was unsuccessful. The reason is unknown, so I will record it first, and I will have time to look at the source code later. Judging from the Issues on the official website, there are also many serialization and deserialization problems, and the update of the previous version is also more targeted at this situation.

The bean received by the request is as follows, use JSONReader.Feature.SupportSmartMatch , still use the field name openid.

@Data
public class XcUserEquityRequest {


    @JSONField(name = "app_id")
    private String appId;


    @JSONField(name = "openid", deserializeFeatures= JSONReader.Feature.SupportSmartMatch)
    private String openId;
}

When requesting, still use the form of open_id underlined.

 But the openid field of interface mapping is empty.

The official description of SupportSmartMatch is as follows,

Guess you like

Origin blog.csdn.net/lrb0677/article/details/128999685