2013-10-15 105 views
27

我遇到了一個問題,即我的可部署jar遇到了一個在IntelliJ本地運行時沒有發生的異常。無法將START_OBJECT令牌的java.lang.String實例反序列化

例外:

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 

插槽處理器

相信當JSON被解析成一個WorkstationRequest對象,因爲以下項目的例外發生。這是插座處理程序:

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

套接字處理程序映射到對象:

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; 
    } 
} 

的JSON被映射:

{"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; 
    } 
} 

我對於如何開始調試這件事感到茫然。堆棧跟蹤從未觸及我的應用程序。我使用Maven -> Package部署我.jar和與java -jar /path-to-jar.jar

更新執行它:爲了避免這個問題被超長的,我包括我的pom.xml這裏:http://pastebin.com/1ZUtKCfE。我相信這是一個依賴性問題,因爲錯誤只發生在我的可部署jar而不是我的本地PC上。

回答

36

你映射此JSON

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

包含名爲data,有一個JSON對象作爲其值的元素。您正嘗試將名爲workstationUuid的元素從該JSON對象反序列化到此設置器中。

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

因爲傑克遜看到了JSON_OBJECT,而不是字符串這不會直接合作。

嘗試創建一個類Data

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

開關你的方法

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

我沒有說明對此進行了詳細,但套接字庫我m使用'public WorkstationDashboard getDashboard(@Data WorkstationRequest request){'將該數組中的'data'字段映射到我的對象。它調用'getDashboard()',因爲該JSON中的'type',然後映射'data'。 我可能是錯的,因爲我真的不知道發生了什麼。但是,由於這一切都可以在我的PC上本地運行,並且在通過.jar部署我的應用程序時會中斷,這似乎是某種依賴性問題。我的pom在這裏:http://pastebin.com/1ZUtKCfE – Webnet

+1

@Webnet是「@ Data」一種自定義註釋,它綁定JSON中的data數據字段?你必須回溯看看它是如何產生'WorkstationRequest'參數的。 –

+0

@SotiriosDelimanolis,固體答案的人。爲我節省了數小時的時間。 – icfantv

4

數據內容可變的,因此我認爲最好的方式是將其定義爲「ObjectNode」和未來創造他自己的類來分析:

最後:

私人ObjectNode數據;

+1

你爲此保存了我的長時間追逐。我的'data'字段裏面可以有任何JSON,所以我不能將它映射到一些POJO。我正在尋找一些只能保存JSON值的解決方案。非常感謝。只是爲了仔細檢查,是否有使用它的副作用或缺點? – theGamblerRises

2

如果你不想定義嵌套JSON一個單獨的類,定義嵌套的JSON對象JsonNode應該工作,例如:

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

@JsonProperty("data") 
    private JsonNode data; 
相關問題