Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android环境下,JSONB解析报错,com.alibaba.fastjson2.JSONException: set address error, offset 17] #715

Closed
Fish-Bin opened this issue Aug 29, 2022 · 16 comments
Labels
bug Something isn't working fixed
Milestone

Comments

@Fish-Bin
Copy link

问题描述

JSONB.parseObject(bytes, Student.class)报错

环境信息

请填写以下信息:

  • OS信息: [e.g.:CentOS 8.4.2105 4Core 3.10GHz 16 GB]
  • JDK信息: [1.8]
  • 版本信息:[implementation 'com.alibaba.fastjson2:fastjson2:2.0.12.android']

重现步骤

如何操作可以重现该问题:

  1. 使用 JSONB.parseObject(bytes, Student.class) 方法
  2. 输入 Student student = new Student("bin",12,"湖北"); byte[] bytes = JSONB.toBytes(student); Student student2 = JSONB.parseObject(bytes, Student.class); L.INSTANCE.i("Bin", student2.toString()); 数据
  3. 出现 com.alibaba.fastjson2.JSONException: set address error, offset 17 错误
       Student student = new Student("bin",12,"湖北");
        byte[] bytes = JSONB.toBytes(student);
        Student student2 = JSONB.parseObject(bytes, Student.class);
        L.INSTANCE.i("Bin", student2.toString());

public class Student {
    private String name;
    private int sge;
    private String address;

    public Student(String name, int sge, String address) {
        this.name = name;
        this.sge = sge;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public int getSge() {
        return sge;
    }

    public void setSge(int sge) {
        this.sge = sge;
    }

    public String getAddress() {
        return address;
    }

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sge=" + sge +
                ", address='" + address + '\'' +
                '}';
    }

期待的正确结果

对您期望发生的结果进行清晰简洁的描述。

相关日志输出

com.alibaba.fastjson2.JSONException: set address error, offset 17
at com.alibaba.fastjson2.reader.FieldReaderStringMethod.readFieldValue(FieldReaderStringMethod.java:34)
at com.alibaba.fastjson2.reader.ObjectReader3.readJSONBObject(ObjectReader3.java:176)
at com.alibaba.fastjson2.JSONB.parseObject(JSONB.java:328)
at com.bin.jsonb.TestActivity.test1(TestActivity.java:45)
at com.bin.jsonb.TestActivity.access$000(TestActivity.java:16)
at com.bin.jsonb.TestActivity$1.onClick(TestActivity.java:25)
at android.view.View.performClick(View.java:7317)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:967)
at android.view.View.performClickInternal(View.java:7291)
at android.view.View.access$3600(View.java:838)
at android.view.View$PerformClick.run(View.java:28247)
at android.os.Handler.handleCallback(Handler.java:900)
at android.os.Handler.dispatchMessage(Handler.java:103)

附加信息

很好的一个库,最近想用它来优化项目存储,但是感觉对安卓支持力度很小,JSONB的一些基本功能都不能正常跑通

@Fish-Bin Fish-Bin added the bug Something isn't working label Aug 29, 2022
@wenshao wenshao added this to the 2.0.13 milestone Aug 29, 2022
@wenshao
Copy link
Member

wenshao commented Aug 29, 2022

是因为Student类没有缺省构造函数,你可以用FieldBased模式试试看,比如:

Student student = new Student("bin",12,"湖北");
byte[] bytes = JSONB.toBytes(student, JSONWriter.Feature.FieldBased);
Student student2 = JSONB.parseObject(bytes, Student.class, JSONReader.Feature.FieldBased);

Android无法像服务器端那样,是因为在服务器端,是会把Class文件读取出来做分析,识别构造函数中的参数名,调用了一次非缺省的构造函数。Android上做不到,所以就功能对不齐了。

@wenshao wenshao removed this from the 2.0.13 milestone Aug 29, 2022
wenshao added a commit that referenced this issue Aug 30, 2022
@Fish-Bin
Copy link
Author

加上无参构造方法,或者加上JSONWriter.Feature.FieldBased确实可以,但是将Student对象转成kotlin就还是会报错
image

@Fish-Bin
Copy link
Author

这个是kotlin对象
image

@wenshao
Copy link
Member

wenshao commented Aug 30, 2022

https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.13.android-SNAPSHOT/
问题已经修复,请用2.0.13.android-SNAPSHOT帮忙验证,FieldBased启用和关闭场景都已经支持。

需要在gradle中配置依赖:

implementation 'org.jetbrains.kotlin:kotlin-reflect:1.7.10'

@wenshao wenshao added this to the 2.0.13 milestone Aug 30, 2022
@wenshao wenshao added the fixed label Aug 30, 2022
@Fish-Bin
Copy link
Author

Fish-Bin commented Sep 1, 2022

  1. 不引入implementation 'org.jetbrains.kotlin:kotlin-reflect:1.7.10'会报
    image
  2. 引入implementation 'org.jetbrains.kotlin:kotlin-reflect:1.7.10'的话编译会报:
    image
    是我kotlin版本低了吗?我当前版本是 ext.kotlin_version = "1.4.32",已经是比较新的了

@wenshao
Copy link
Member

wenshao commented Sep 1, 2022

引入implementation 'org.jetbrains.kotlin:kotlin-reflect:1.4.32'试试看

@Fish-Bin
Copy link
Author

Fish-Bin commented Sep 2, 2022

  1. 引入implementation 'org.jetbrains.kotlin:kotlin-reflect:1.4.32'可以了
  2. @JSONField(name = "n") 会导致 JSONB.parseObject(bytes, JNote::class.java) 报错

image

  1. @JSONField( serialize= false) 也会导致 JSONB.parseObject(bytes, JNote::class.java) 报错
    image

对象信息:
image

@Fish-Bin
Copy link
Author

Fish-Bin commented Sep 2, 2022

类似的还有@JSONField(serializeFeatures = [JSONWriter.Feature.NotWriteDefaultValue])
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
@JSONField(serializeUsing = TypeSerializer::class)
@jsontype(ignores = ["noteId","firstPageId"])
@jsontype(serializeFeatures = [JSONWriter.Feature.NotWriteDefaultValue])
这些注解不生效的问题,麻烦排查下

@wenshao
Copy link
Member

wenshao commented Sep 2, 2022

@Fish-Bin 发文本,按照图再输入一遍很烦人

@Fish-Bin
Copy link
Author

Fish-Bin commented Sep 2, 2022

data class Note(
var noteId: String = "",

var name: String? = "",
var firstPageID: String = "",

var type: Int = 1,

var maxPageNumber: Int = 9999,

var deleteFlag: Int = 0,

var userid: String = "",

var backgroundUrl: String = ""

var paperParamConfig: String = "",

var lastPageIndex: Int = 0,

var parentId: String = "",

var isImpOutline: Int = 0,

var paperWidth: Float = 1024f,

var paperHeight: Float = 1750f,

var modify: Boolean = false,
var needDown: Boolean = false,
var isClouding: Boolean = false,
var cloudId: String = "",
var progress: Int = 0,
var maxProgress: Int = 0,
var fileSize: Int = 0,
var firstBackgroundUrl: String = "",
var scaleGlobal: String = "",

)

@Fish-Bin
Copy link
Author

Fish-Bin commented Sep 2, 2022

    val note = Note(
        noteId = noteId,
        name = "无名",
        firstPageID = pageId,
        type = 1,
        maxPageNumber = 9999,
        userid = "77800484",
        backgroundUrl = "PageBg/White_Wide_Line_Paper",
        parentId = "",
        firstBackgroundUrl = "/Cover/natural2",
        paperParamConfig = "{\"defaultHorParts\":5.0,\"defaultVerParts\":5.0,\"horParts\":0.0,\"paperBg\":\"PageBg/White_Wide_Line_Paper\",\"verParts\":0.0}",
        lastPageIndex = 1,
        isImpOutline = 1,
        paperWidth = 1240f,
        paperHeight = 1750f,
        scaleGlobal = "bin"
    )

@wenshao
Copy link
Member

wenshao commented Sep 2, 2022

主要是data class不允许为空,使用Feature.FieldBased就好了

@Fish-Bin
Copy link
Author

Fish-Bin commented Sep 2, 2022

主要是data class不允许为空,使用Feature.FieldBased就好了

好的,我验证下

@Fish-Bin
Copy link
Author

Fish-Bin commented Sep 2, 2022

在对象头上也要加上@jsontype(serializeFeatures = [JSONWriter.Feature.FieldBased])这个吧,不然也还是报错

@Fish-Bin
Copy link
Author

Fish-Bin commented Sep 2, 2022

加了Feature.FieldBased 后 @jsontype的大部分注解都生效了,除了JSONWriter.Feature.NotWriteDefaultValue不生效,但是会导致@JSONField的注解都不生效了
image

@wenshao
Copy link
Member

wenshao commented Sep 10, 2022

https://github.com/alibaba/fastjson2/releases/tag/2.0.13
2.0.13版本已经发布,请用帮忙用新版本验证

@wenshao wenshao closed this as completed Sep 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed
Projects
None yet
Development

No branches or pull requests

2 participants