Can not deserialize instance of java.lang.String out of START_OBJECT token

前端 未结 5 718
野的像风
野的像风 2020-12-08 12:42

I\'m running into an issue where my deployable jar hits an exception that doesn\'t happen when I run this locally in IntelliJ.

Exception:

相关标签:
5条回答
  • 2020-12-08 13:11

    You're mapping this JSON

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

    that contains an element named data that has a JSON object as its value. You are trying to deserialize the element named workstationUuid from that JSON object into this setter.

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

    This won't work directly because Jackson sees a JSON_OBJECT, not a String.

    Try creating a class Data

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

    the switch up your method

    @JsonProperty("data")
    public void setWorkstation(Data data) {
        // use getter to retrieve it
    
    0 讨论(0)
  • 2020-12-08 13:15

    If you do not want to define a separate class for nested json , Defining nested json object as JsonNode should work ,for example :

    {"id":2,"socket":"0c317829-69bf-43d6-b598-7c0c550635bb","type":"getDashboard","data":{"workstationUuid":"ddec1caa-a97f-4922-833f-632da07ffc11"},"reply":true}
    
    @JsonProperty("data")
        private JsonNode data;
    
    0 讨论(0)
  • 2020-12-08 13:17

    Resolved the problem using Jackson library. Prints are called out of Main class and all POJO classes are created. Here is the code snippets.

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

    RESULTS:

    Value for getFirstName is: 2
    Value for getLastName  is: 0c317829-69bf-43d6-b598-7c0c550635bb
    Value for getChildren is: ddec1caa-a97f-4922-833f-632da07ffc11
    Value for getChildren is: true
    
    0 讨论(0)
  • 2020-12-08 13:18

    This way I solved my problem. Hope it helps others. In my case I created a class, a field, their getter & setter and then provide the object instead of string.

    Use this

    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;
    

    Instead of this

    @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 讨论(0)
  • 2020-12-08 13:28

    Data content is so variable, I think the best form is to define it as "ObjectNode" and next create his own class to parse:

    Finally:

    private ObjectNode data;

    0 讨论(0)
提交回复
热议问题