GSON无法还原序列化JSON

vuktfyat  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(235)

我正在尝试使用pusher-websocket-java库订阅一个Presence Pusher通道。当我连接该通道时,出现以下异常:

java.lang.RuntimeException: Unable to invoke no-args constructor for class com.pusher.client.channel.impl.PresenceChannelImpl$Presence. Registering an InstanceCreator with Gson for this type may fix this problem.
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:228)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:212)
at com.google.gson.Gson.fromJson(Gson.java:927)
at com.google.gson.Gson.fromJson(Gson.java:892)
at com.google.gson.Gson.fromJson(Gson.java:841)
at com.google.gson.Gson.fromJson(Gson.java:813)
at com.pusher.client.channel.impl.PresenceChannelImpl.extractPresenceDataFrom(PresenceChannelImpl.java:168)
at com.pusher.client.channel.impl.PresenceChannelImpl.handleSubscriptionSuccessfulMessage(PresenceChannelImpl.java:96)
at com.pusher.client.channel.impl.PresenceChannelImpl.onMessage(PresenceChannelImpl.java:54)
at com.pusher.client.channel.impl.ChannelManager.onMessage(ChannelManager.java:116)
at com.pusher.client.connection.websocket.WebSocketConnection.handleEvent(WebSocketConnection.java:177)
at com.pusher.client.connection.websocket.WebSocketConnection.access$600(WebSocketConnection.java:27)
at com.pusher.client.connection.websocket.WebSocketConnection$6.run(WebSocketConnection.java:261)
at com.pusher.client.util.Factory$1.run(Factory.java:119)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source) 
Caused by: java.lang.UnsupportedOperationException: Cannot allocate class com.pusher.client.channel.impl.PresenceChannelImpl$Presence
at com.google.gson.internal.UnsafeAllocator$4.newInstance(UnsafeAllocator.java:104)
at com.google.gson.internal.ConstructorConstructor$14.construct(ConstructorConstructor.java:225)
... 16 more

我已经尝试过添加一个无参数的构造函数,但似乎不起作用。我仍然得到相同的错误。而且我确保了要反序列化的传入消息是正确的。
在下列函式中执行return陈述式时,会掷回例外状况:

@SuppressWarnings("rawtypes")
private static PresenceData extractPresenceDataFrom(final String message) {
    final String dataString = extractDataStringFrom(message);
    return GSON.fromJson(dataString, Presence.class).presence;
}

这是Presence类:

private class Presence {
    @SerializedName("presence")
    public PresenceData presence;

    public Presence() {
    }
}

这是PresenceData类:

private class PresenceData {
    @SerializedName("count")
    public Integer count;
    @SerializedName("ids")
    public List<String> ids;
    @SerializedName("hash")
    public Map<String, Object> hash;

    public PresenceData() {
    }
}

澄清一下,这段代码不是我自己写的。但是,我可以访问代码来修改它。有人有解决这个错误的线索吗?
Gradle用于构建.jar文件:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.ajoberstar:gradle-git:1.1.0'
    }
}

def getProperty = { property ->
    if (!project.hasProperty(property)) {
        throw new GradleException("${property} property must be set")
    }
    return project.property(property)
}

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'eclipse'
apply plugin: 'org.ajoberstar.github-pages'
apply plugin: 'signing'
apply plugin: 'jacoco'

group = "com.pusher"
version = "2.2.5"
sourceCompatibility = "1.8"
targetCompatibility = "1.8"

ext.sharedManifest = manifest {
    attributes(
        "Created-By"            : 'Pusher',
        'Implementation-Vendor' : 'Pusher',
        'Implementation-Title'  : 'Pusher Java Websocket API Example',
        'Implementation-Version': version,
        'Package'               : 'com.pusher.client.example',
        'Main-Class'            : 'com.pusher.client.example.ExampleApp'
    )
}

repositories {
    mavenLocal()
    jcenter()
}

dependencies {
    compile "com.google.code.gson:gson:2.8.6"
    compile "org.java-websocket:Java-WebSocket:1.5.1"

    testCompile "org.mockito:mockito-all:1.8.5"
    testCompile "org.powermock:powermock-module-junit4:1.4.11"
    testCompile "org.powermock:powermock-api-mockito:1.4.11"

    testImplementation "com.google.truth:truth:1.0.1"
}

processResources {
    filter(org.apache.tools.ant.filters.ReplaceTokens, tokens: [
        version: project.version
    ] )
}

javadoc {
    /* info for JavaDoc options http://docs.oracle.com/javase/6/docs/technotes/tools/windows/javadoc.html#overviewcomment */
    title "Pusher Java Websocket API"
    options.overview = file("src/main/javadoc/overview.html")
    // uncomment this to use the custom javadoc styles
    //options.stylesheetFile = file("src/main/javadoc/css/styles.css")
    exclude "com/pusher/client/channel/impl/*"
    exclude "com/pusher/client/connection/impl/*"
    exclude "com/pusher/client/connection/websocket/*"
    exclude "com/pusher/client/crypto/nacl/*"
    exclude "com/pusher/client/util/internal/*"
    exclude "org/java_websocket/*"
    exclude "com/pusher/client/example/*"
    options.linkSource = true
}

jar {
    manifest = project.manifest {
        from sharedManifest
    }
}

task fatJar(type: Jar, dependsOn:configurations.runtime) {
    manifest = project.manifest {
        from sharedManifest
    }
    baseName = project.name + '-with-dependencies'
    from { configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
    classifier = 'jar-with-dependencies'
}
assemble.dependsOn fatJar

task sourcesJar(type: Jar, dependsOn: classes) {
    classifier = 'sources'
    from sourceSets.main.allSource
}
assemble.dependsOn sourcesJar

task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}
assemble.dependsOn javadocJar

githubPages {
    repoUri = 'https://github.com/pusher/pusher-websocket-java.git'
    pages {
        from javadoc.outputs.files
    }
    commitMessage = "JavaDoc gh-pages for ${version}"
    credentials {
        username = { getProperty("github.username") }
        password = { getProperty("github.password") }
    }
}

signing {
    required { gradle.taskGraph.hasTask("uploadArchives") }
    sign configurations.archives
}

artifacts {
    archives jar, fatJar, sourcesJar, javadocJar
}

task createPublishTarget {
    doLast {
        uploadArchives { repositories { mavenDeployer {
            beforeDeployment {
                MavenDeployment deployment -> signing.signPom(deployment)
            }
            repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
                authentication(
                    userName: getProperty("maven.username"),
                    password: getProperty("maven.password")
                )
            }
            snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
                authentication(
                    userName: getProperty("maven.username"),
                    password: getProperty("maven.password")
                )
            }
            pom.project {
                name 'Pusher Java Client Library'
                packaging 'jar'
                artifactId 'pusher-java-client'
                description 'This is a Java client library for Pusher, targeted at core Java and Android.'
                url 'http://github.com/pusher/pusher-websocket-java'
                scm {
                    connection 'scm:git:git@github.com:pusher/pusher-websocket-java'
                    developerConnection 'scm:git:git@github.com:pusher/pusher-websocket-java'
                    url 'http://github.com/pusher/pusher-websocket-java'
                }
                licenses {
                    license {
                        name 'MIT'
                        url 'https://raw.github.com/pusher/pusher-websocket-java/master/LICENCE.txt'
                        distribution 'https://raw.github.com/pusher/pusher-websocket-java/mvn-repo/'
                    }
                }
                organization {
                    name 'Pusher'
                    url 'http://pusher.com'
                }
                issueManagement {
                    system 'GitHub'
                    url 'https://github.com/pusher/pusher-websocket-java/issues'
                }
                developers {
                    developer {
                        id 'mike'
                        name 'Mike Pye'
                        email 'mike@pusher.com'
                    }
                }
            }
        }}}
    }
}

wrapper {
    gradleVersion = '5.5.1'
}

jacoco {
    toolVersion = "0.8.4"
}

jacocoTestReport {
    reports.xml.enabled = true
    reports.html.enabled = false
    reports.csv.enabled = false
}

// Test Logging - https://stackoverflow.com/a/42425815/2623314
test {
    testLogging {
        showStandardStreams = true
    }
}

我通过点击build-〉Build Artifacts-〉Build int intellij来构建项目。就我所知,这是构建.jar文件的正确方法。如果我错了,请纠正我。
这是由GSON库反序列化的JSON:

{"event":"pusher_internal:subscription_succeeded","data":"
 {\"presence\":
  {\"count\":1,\"ids\":[\"5\"],\"hash\":
   {\"5\": 
    {\"id\":5,\"name\":\"name\",\"email\":\"test@gmail.com\",
     \"type\":\"bot\",\"botpass\":\"qwerty123\",\"server\":1,\"is_mule\":0,
     \"stage\":\"readybot\",\"is_online\":0,\"email_verified_at\":null,
     \"api_token\":\"TkqRrrZDO5CbLr7y85MAr2qK3wbk2crn6A3PscpPXpE1w\",
     \"created_at\":\"2021-01-28T17:14:00.000000Z\",
     \"updated_at\":\"2021-01-28T17:14:00.000000Z\"
    }
   }
  }
 }
 ","channel":"presence-server.0"
}
ttisahbt

ttisahbt1#

您很可能是从没有默认构造函数的pusher-websocket-java库中导入原始Presence类。com/pusher/client/channel/impl/PresenceChannelImpl.java.Presence
导入自定义的Presence类或者给予它一个不同的名字,这样就有区别了。另外,你可以使用Jackson进行反序列化,它不需要默认的构造函数。

相关问题