Search code examples
javajsonjacksonjackson-databind

How to process a JSON using Java


I passing a JSON string (inputJson) to my java code (PPProgramAddView) on the server side.

PPProgramAddView:
inputJson: [{"ppl_row":0,"ppl_time":"07:00","ppat_id":"Mw==","ppa_id":"MTI=","ppl_LeadAssist":"Lead"},{"ppl_row":1,"ppl_time":"07:10","ppat_id":"Mg==","ppa_id":"NA==","ppl_LeadAssist":"Assist"}]

When I try to process it I get the following error:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ppl_row" (class client.Profile14), not marked as ignorable (5 known properties: "plTime", "plActivity", "plActivityType", "plRow", "plLeadAssist"])
 at [Source: (String)"[{"ppl_row":0,"ppl_time":"07:00","ppat_id":"Mw==","ppa_id":"MTI=","ppl_LeadAssist":"Lead"},{"ppl_row":1,"ppl_time":"07:10","ppat_id":"Mg==","ppa_id":"NA==","ppl_LeadAssist":"Assist"}]"; line: 1, column: 14] (through reference chain: java.lang.Object[][0]->client.Profile14["ppl_row"])
        at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)

I have done a search and I can not find '"plTime", "plActivity", "plActivityType", "plRow", "plLeadAssist"' anywhere.

My code is:

//Look through the new program lines and add them.
        try {
            ObjectMapper mapper = new ObjectMapper();
            
            Profile14[] profiles14 = mapper.readValue(inputJson, Profile14[].class);
          
            for (final Profile14 programLine : profiles14) {
              
                String ppl_row = programLine.getplRow();
                
                String ppl_time = null;
                if (programLine.getplTime().length() < 1){
                    ppl_time = "00:01";
                }else{
                    ppl_time = programLine.getplTime();
                }
                
                String ppat_id_encoded = programLine.getplActivityType();
                String ppa_id_encoded = programLine.getplActivity();
                String ppl_LeadAssist = programLine.getplLeadAssist().substring(0, Math.min(programLine.getplLeadAssist().length(), 45));
                
                byte[] valueDecoded3 = Base64.decodeBase64(ppat_id_encoded);//decoding part
                String ppat_id = new String(valueDecoded3);
                
                byte[] valueDecoded4 = Base64.decodeBase64(ppa_id_encoded);//decoding part
                String ppa_id = new String(valueDecoded4);
                
                System.out.println("ppID: " + ppID + " ppat_id: " + ppat_id + " ppa_id: " + ppa_id +
                    " ppl_row : " + ppl_row + " ppl_time: " + ppl_time + " ppl_LeadAssist: " + ppl_LeadAssist);

                MySQLConnection.addPPProgramLine(ppID, ppat_id, ppa_id, ppl_row, ppl_time, ppl_LeadAssist);
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Error.");
        }
    }
}

class Profile14 {
    private String ppl_row;
    private String ppl_time;
    private String ppat_id;
    private String ppa_id;
    private String ppl_LeadAssist;
    
    public String getplRow() {
        return ppl_row;
    }
    public void setplRow(String ppl_row) {
        this.ppl_row = ppl_row;
    }
    
    public String getplTime() {
        return ppl_time;
    }
    public void setplTime(String ppl_time) {
        this.ppl_time = ppl_time;
    }
    
    public String getplActivityType() {
        return ppat_id;
    }
    public void setplActivityType (String ppat_id) {
        this.ppat_id = ppat_id;
    }
    
    public String getplActivity() {
        return ppa_id;
    }
    public void setplActivity(String ppa_id) {
        this.ppa_id = ppa_id;
    }
    
    public String getplLeadAssist() {
        return ppl_LeadAssist;
    }
    public void setplLeadAssist(String ppl_LeadAssist) {
        this.ppl_LeadAssist = ppl_LeadAssist;
    }
    
    @Override
    public String toString() {
        return "Profile14 [ppl_row=" + ppl_row + ", ppl_time=" + ppl_time + ", ppat_id=" + ppat_id
                + ", ppa_id=" + ppa_id + ", ppl_LeadAssist=" + ppl_LeadAssist + "]";
    }
}

Solution

  • You aren't following JavaBean standards, and without explicit instructions Jackson doesn't know how to map your class.

    The Java convention is to name properties like pplRow, and your JSON is using the alternate Ruby style of ppl_row. There are three options:

    • Switch the entire Jackson engine to use an alternate style. (Not a great idea since it tends to cause collisions.
    • Tell Jackson to use an alternate style for particular Java classes. (We'll do this.)
    • Annotate each property with @JsonProperty (works, but lots of extra effort).

    Start by using standard Java naming for your properties:

    class Profile14 {
      private String pplRow;
    
      public String getPplRow() {
        return this.pplRow;
      }
    
      public void setPplRow(String s) {
        this.pplRow = s;
      }
    }
    

    Note that the naming of the methods is what defines the properties (since the backing field is private and technically doesn't have to exist). Your existing properties both don't match the names (pl instead of ppl) and don't have the proper capitalization.

    Now add this annotation to your class:

    @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
    

    This tells Jackson to use snake_case for naming all of the properties. This should be enough to get your mapping working.