it-swarm.com.de

Instanz von Java.lang.String kann nicht aus dem START_OBJECT-Token deserialisiert werden

Ich habe ein Problem, bei dem mein bereitstellbares Glas eine Ausnahme trifft, die nicht auftritt, wenn ich dies lokal in IntelliJ ausführen kann. 

Ausnahme:

Receiving an event {id=2, socket=0c317829-69bf-43d6-b598-7c0c550635bb, type=getDashboard, data={workstationUuid=ddec1caa-a97f-4922-833f-632da07ffc11}, reply=true}
Firing getDashboard event to Socket#0c317829-69bf-43d6-b598-7c0c550635bb
Failed invoking AtmosphereFramework.doCometSupport()
Java.lang.IllegalArgumentException: Can not deserialize instance of Java.lang.String out of START_OBJECT token
 at [Source: N/A; line: -1, column: -1]
        at org.codehaus.jackson.map.ObjectMapper._convert(ObjectMapper.Java:2502)
        at org.codehaus.jackson.map.ObjectMapper.convertValue(ObjectMapper.Java:2468)
        at com.github.flowersinthesand.portal.support.DefaultDispatcher$DefaultHandler$DataParam.resolve(DefaultDispatcher.Java:270)
        at com.github.flowersinthesand.portal.support.DefaultDispatcher$DefaultHandler.handle(DefaultDispatcher.Java:204)
        at com.github.flowersinthesand.portal.support.DefaultDispatcher.fire(DefaultDispatcher.Java:107)
        at com.github.flowersinthesand.portal.support.AbstractSocketFactory.fire(AbstractSocketFactory.Java:73)
        at com.github.flowersinthesand.portal.atmosphere.AtmosphereSocketFactory.onRequest(AtmosphereSocketFactory.Java:75)
        at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.Java:256)
        at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.Java:166)
        at org.atmosphere.container.Grizzly2WebSocketSupport.service(Grizzly2WebSocketSupport.Java:75)
        at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.Java:1342)
        at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.Java:219)
        at org.atmosphere.websocket.DefaultWebSocketProcessor$2.run(DefaultWebSocketProcessor.Java:183)
        at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.Java:101)
        at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.Java:178)
        at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.Java:167)
        at org.atmosphere.container.Grizzly2WebSocketSupport$Grizzly2WebSocketApplication.onMessage(Grizzly2WebSocketSupport.Java:171)
        at org.glassfish.grizzly.websockets.DefaultWebSocket.onMessage(DefaultWebSocket.Java:164)
        at org.glassfish.grizzly.websockets.frametypes.TextFrameType.respond(TextFrameType.Java:70)
        at org.glassfish.grizzly.websockets.DataFrame.respond(DataFrame.Java:104)
        at org.glassfish.grizzly.websockets.WebSocketFilter.handleRead(WebSocketFilter.Java:221)
        at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.Java:119)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.Java:265)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.Java:200)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.Java:134)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.Java:112)
        at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.Java:78)
        at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.Java:770)
        at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.Java:112)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.Java:115)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.Java:55)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.Java:135)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.Java:551)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.Java:531)
        at Java.lang.Thread.run(Thread.Java:781)
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of Java.lang.String out of START_OBJECT token
 at [Source: N/A; line: -1, column: -1]
        at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.Java:163)
        at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.Java:219)
        at org.codehaus.jackson.map.deser.std.StringDeserializer.deserialize(StringDeserializer.Java:44)
        at org.codehaus.jackson.map.deser.std.StringDeserializer.deserialize(StringDeserializer.Java:13)
        at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.Java:2704)
        at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.Java:1315)
        at org.codehaus.jackson.map.ObjectMapper._convert(ObjectMapper.Java:2498)
        ... 34 more
Java.lang.IllegalArgumentException: Can not deserialize instance of Java.lang.String out of START_OBJECT token
 at [Source: N/A; line: -1, column: -1] Status 500 Message Server Error

Socket-Handler

Ich glaube, die Ausnahme tritt auf, wenn der JSON-Code aufgrund des folgenden Elements in ein WorkstationRequest-Objekt analysiert wird. Dies ist der Socket-Handler:

@On
@Reply
@JsonView({Views.WorkstationView.class})
public WorkstationDashboard getDashboard(@Data WorkstationRequest request) {
    return new WorkstationDashboard(request.getWorkstation());
}

Das Objekt, dem der Socket-Handler zugeordnet ist:

public class WorkstationRequest {

    /* Class to instantiate if this workstation does not already exist */
    private Class<? extends Workstation> workstationClass;

    private WorkflowProcess workflowProcess;

    private PhysicalWorkstation workstation;

    WorkstationService workstationService;

    /**
     * @param workstationClass Required so when jackson maps the UUID we can auto fetch the class
     */
    public WorkstationRequest(Class<? extends Workstation> workstationClass) {
        this.workstationClass = workstationClass;
        workstationService = (WorkstationService) ApplicationContextProvider.getApplicationContext().getBean("workstationService");
    }

    /* Set the workstation based on UUID.  Will register the workstation if it's new */
    @JsonProperty("workstationUuid")
    public void setWorkstation(String workstationUUID) {
        workstation = (PhysicalWorkstation)WorkstationService.getWorkstation(workstationUUID);

        //setup new workstation
        if (workstation == null) {
            WorkstationEntity workstationEntity = workstationService.findByUUID(workstationUUID);
            workstation = (PhysicalWorkstation)Workstation.factory(workstationEntity, workstationClass);

            //register with queue
            WorkflowProcessService.getWorkflowProcess(workstation).registerWorkstation(workstation);
        }
    }

    public PhysicalWorkstation getWorkstation() {
        return workstation;
    }
}

Die JSON wird zugeordnet:

{"id":2,"socket":"0c317829-69bf-43d6-b598-7c0c550635bb","type":"getDashboard","data":{"workstationUuid":"ddec1caa-a97f-4922-833f-632da07ffc11"},"reply":true}

WorkstationDashboard.Java

public class WorkstationDashboard {
    private HashMap<String, Object> queue = new HashMap<String, Object>();

    private LinkedBlockingDeque<JobSetEntity> currentWork;

    public WorkstationDashboard() {
        queue.put("size", 0);
    }

    public WorkstationDashboard(Workstation workstation) {
        fromWorkstation(workstation);
    }

    /* Populate dashboard data from a workstation */
    public void fromWorkstation(Workstation workstation) {
        WorkflowProcess workflowProcess = WorkflowProcessService.getWorkflowProcess(workstation);

        setCurrentWork(workstation.getCurrentWork());
        setQueueSize(workflowProcess.getQueue().size());
    }

    public void setQueueSize(Integer queueSize) {
        queue.put("size", queueSize);
    }

    public HashMap<String, Object> getQueue() {
        return queue;
    }

    public LinkedBlockingDeque<JobSetEntity> getCurrentWork() {
        return currentWork;
    }

    public void setCurrentWork(LinkedBlockingDeque<JobSetEntity> currentWork) {
        this.currentWork = currentWork;
    }
}

Ich bin ziemlich ratlos, wie man mit dem Debuggen beginnen kann. Der Stack-Trace berührt meine Anwendung nie. Ich verwende Maven -> Package, um meine .jar bereitzustellen und mit Java -jar /path-to-jar.jar auszuführen.

Update: Damit diese Frage nicht zu lange dauert, habe ich meine pom.xml hier eingefügt: http://Pastebin.com/1ZUtKCfE . Ich glaube, dass dies ein Abhängigkeitsproblem ist, da der Fehler nur auf meinem bereitstellbaren Glas und nicht auf meinem lokalen PC auftritt.

42
Webnet

Sie mappen diese JSON 

{
    "id": 2,
    "socket": "0c317829-69bf-43d6-b598-7c0c550635bb",
    "type": "getDashboard",
    "data": {
        "workstationUuid": "ddec1caa-a97f-4922-833f-632da07ffc11"
    },
    "reply": true
}

das enthält ein Element mit dem Namen data, das als Wert ein JSON-Objekt hat. Sie versuchen, das Element mit dem Namen workstationUuid von diesem JSON-Objekt in diesen Setter zu deserialisieren.

@JsonProperty("workstationUuid")
public void setWorkstation(String workstationUUID) {

Dies funktioniert nicht direkt, da Jackson einen JSON_OBJECT und keinen String sieht.

Erstellen Sie eine Klasse, Data.

public class Data { // the name doesn't matter 
    @JsonProperty("workstationUuid")
    private String workstationUuid;
    // getter and setter
}

die wechseln Sie Ihre Methode

@JsonProperty("data")
public void setWorkstation(Data data) {
    // use getter to retrieve it
49

Der Dateninhalt ist so variabel. Ich denke, die beste Form ist, ihn als "ObjectNode" zu definieren und als Nächstes seine eigene Klasse zum Analysieren zu erstellen:

Endlich: 

private ObjectNode-Daten;

15
richardhell

Wenn Sie keine separate Klasse für verschachtelten Json definieren möchten, sollte das Definieren von verschachtelten Json-Objekten als JsonNode funktionieren. Beispiel:

{"id":2,"socket":"0c317829-69bf-43d6-b598-7c0c550635bb","type":"getDashboard","data":{"workstationUuid":"ddec1caa-a97f-4922-833f-632da07ffc11"},"reply":true}

@JsonProperty("data")
    private JsonNode data;
9
Sindhu

Auf diese Weise habe ich mein Problem gelöst. Hoffe es hilft anderen. In meinem Fall habe ich eine Klasse, ein Feld, deren Getter und Setter erstellt und dann das Objekt anstelle von string angegeben.

Benutze dies

public static class EncryptedData {
    private String encryptedData;

    public String getEncryptedData() {
        return encryptedData;
    }

    public void setEncryptedData(String encryptedData) {
        this.encryptedData = encryptedData;
    }
}

@PutMapping(value = MY_IP_ADDRESS)
public ResponseEntity<RestResponse> updateMyIpAddress(@RequestBody final EncryptedData encryptedData) {
    try {
        Path path = Paths.get(PUBLIC_KEY);
        byte[] bytes = Files.readAllBytes(path);
        PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(base64.decode(bytes));
        PrivateKey privateKey = KeyFactory.getInstance(CRYPTO_ALGO_RSA).generatePrivate(ks);

        Cipher cipher = Cipher.getInstance(CRYPTO_ALGO_RSA);
        cipher.init(Cipher.PRIVATE_KEY, privateKey);
        String decryptedData = new String(cipher.doFinal(encryptedData.getEncryptedData().getBytes()));
        String[] dataArray = decryptedData.split("|");


        Method updateIp = Class.forName("com.cuanet.client.helper").getMethod("methodName", String.class,String.class);
        updateIp.invoke(null, dataArray[0], dataArray[1]);

    } catch (Exception e) {
        LOG.error("Unable to update ip address for encrypted data: "+encryptedData, e);
    }

    return null;

An Stelle von

@PutMapping(value = MY_IP_ADDRESS)
public ResponseEntity<RestResponse> updateMyIpAddress(@RequestBody final EncryptedData encryptedData) {
    try {
        Path path = Paths.get(PUBLIC_KEY);
        byte[] bytes = Files.readAllBytes(path);
        PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(base64.decode(bytes));
        PrivateKey privateKey = KeyFactory.getInstance(CRYPTO_ALGO_RSA).generatePrivate(ks);

        Cipher cipher = Cipher.getInstance(CRYPTO_ALGO_RSA);
        cipher.init(Cipher.PRIVATE_KEY, privateKey);
        String decryptedData = new String(cipher.doFinal(encryptedData.getBytes()));
        String[] dataArray = decryptedData.split("|");


        Method updateIp = Class.forName("com.cuanet.client.helper").getMethod("methodName", String.class,String.class);
        updateIp.invoke(null, dataArray[0], dataArray[1]);

    } catch (Exception e) {
        LOG.error("Unable to update ip address for encrypted data: "+encryptedData, e);
    }

    return null;
}
0
Ajay

Problem mit der Jackson-Bibliothek behoben. Drucke werden aus der Hauptklasse heraus aufgerufen und alle POJO-Klassen werden erstellt. Hier sind die Codeausschnitte.

MainClass.Java

public class MainClass {
  public static void main(String[] args) throws JsonParseException, 
       JsonMappingException, IOException {

String jsonStr = "{\r\n" + "    \"id\": 2,\r\n" + " \"socket\": \"0c317829-69bf- 
             43d6-b598-7c0c550635bb\",\r\n"
            + " \"type\": \"getDashboard\",\r\n" + "    \"data\": {\r\n"
            + "     \"workstationUuid\": \"ddec1caa-a97f-4922-833f- 
            632da07ffc11\"\r\n" + " },\r\n"
            + " \"reply\": true\r\n" + "}";

    ObjectMapper mapper = new ObjectMapper();

    MyPojo details = mapper.readValue(jsonStr, MyPojo.class);

    System.out.println("Value for getFirstName is: " + details.getId());
    System.out.println("Value for getLastName  is: " + details.getSocket());
    System.out.println("Value for getChildren is: " + 
      details.getData().getWorkstationUuid());
    System.out.println("Value for getChildren is: " + details.getReply());

}

MyPojo.Java

public class MyPojo {
    private String id;

    private Data data;

    private String reply;

    private String socket;

    private String type;

    public String getId() {
        return id;
    }

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

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }

    public String getReply() {
        return reply;
    }

    public void setReply(String reply) {
        this.reply = reply;
    }

    public String getSocket() {
        return socket;
    }

    public void setSocket(String socket) {
        this.socket = socket;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    } 
}

Data.Java

public class Data {
    private String workstationUuid;

    public String getWorkstationUuid() {
        return workstationUuid;
    }

    public void setWorkstationUuid(String workstationUuid) {
        this.workstationUuid = workstationUuid;
    }   
}

ERGEBNISSE:

 Wert für getFirstName ist: 2 
 Wert für getLastName ist: 0c317829-69bf-43d6-b598-7c0c550635bb 
 Wert für getChildren: ddec1caa-a97f-4922-833f-632da07ffc11 : wahr
0
Lucky