com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段

Posted

技术标签:

【中文标题】com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段【英文标题】:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field 【发布时间】:2014-06-21 14:18:26 【问题描述】:

我遇到了反序列化问题:

这是我的课:

public class Response 

    private Object ResObj;
    private int ResInt;

    public Object getResObj() 
        return ResObj;
    

    public int getResInt() 
        return ResInt;
     
 

我要反序列化的 JSON 是:

"ResObj":"ClientNum":"12345","ServerNum":"78945","IdNum":"020252","ResInt":0

我得到了这个例外:

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ResObj" , not marked as ignorable (0 known properties: ])
 at [Source: java.io.StringReader@1f758500; line: 1, column: 20] (through reference chain: ["ResObj"])

我不想补充:

@JsonIgnoreProperties(ignoreUnknown = true)

因为我想获得 ResObj...

如果我添加注释,它会通过,但它会将其设置为 null .. 这是我不想要的。

【问题讨论】:

【参考方案1】:

我尝试了上面提到的所有方法,但在我的情况下,这是唯一有效的解决方案 here 解决方案 2。在这里,我在我的 Spring Boot 应用程序中启用了 @EnableWebMvc

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer 
    @Autowired
    private ObjectMapper objectMapper;// created elsewhere
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) 
        // this will add a 2nd MappingJackson2HttpMessageConverter 
        converters.add(new MappingJackson2HttpMessageConverter(this.objectMapper));
    

【讨论】:

【参考方案2】:

如果您不想在 bean 中使用 setter 并且只使用字段和 getter,则可以使用 ObjectMapper 的可见性检查器来允许字段可见性。 类似于以下内容:

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setVisibility(VisibilityChecker.Std.defaultInstance().withFieldVisibility(JsonAutoDetect.Visibility.ANY));

【讨论】:

如果这解决了问题,@user2212726 能否请您批准,以便它对其他人也有用? 你应该给出完整的conf。您如何使自己创建的这个“映射器”对象供 Spring 使用? @Tristan 只需将上面的代码包装在一个方法中,并用 @Bean 注释它,如果你想举例,检查这个 - ***.com/a/32842962/471467 好吧,这可能会失败,因为您可以阅读下面引用的答案。 如果您指的是 Spring Boot,则通过“可能失败”,那么有一条评论说使用不同的名称。有意义吗?【参考方案3】:

我已经使用 Jackson 库对这个问题进行了排序。这是我的代码 sn-p。

**Main Class with JSON String in all lower case:**

 public class MainClass 

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

    String jsonStr = "\r\n" + "    \"resObj\": \r\n" + "      \"clientNum\": 
               \"12345\",\r\n"
            + "     \"serverNum\": \"78945\",\r\n" + "      \"idNum\": 
          \"020252\"\r\n" + "   ,\r\n"
            + " \"resInt\": 0\r\n" + "";

    ObjectMapper mapper = new ObjectMapper();

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

    System.out.println("value of clientNum: " + details.getResObj().getClientNum());
    System.out.println("value of getServerNum: " + 
               details.getResObj().getServerNum());
    System.out.println("value of getIdNum: " + details.getResObj().getIdNum());
    System.out.println("value of getResInt: " + details.getResInt());

 

**MyPojo Class:**

 public class MyPojo 
private ResObj resObj;

private String resInt;

public ResObj getResObj() 
    return resObj;


  public String getResInt() 
       return resInt;    

**ResObj class:**


public class ResObj 
private String serverNum;

private String idNum;

private String clientNum;

public String getServerNum() 
    return serverNum;


public String getIdNum() 
    return idNum;


public String getClientNum() 
    return clientNum;
 

**RESULT**

  value of clientNum: 12345
  value of getServerNum: 78945
  value of getIdNum: 020252
  value of getResInt: 0

NOTE: I have removed Setters in classes & there is no effect on the result.

【讨论】:

【参考方案4】:
public class Response 
    public Object ResObj;
    public int ResInt;

    public Object getResObj() 
        return ResObj;
    

    public int getResInt() 
        return ResInt;
     
 

使用它来解决上述问题。

【讨论】:

【参考方案5】:

我觉得你应该试试这个

public class Response 
    @JsonProperty
    private Object ResObj;
    @JsonProperty
    private int ResInt;

    public Object getResObj() 
        return ResObj;
    

    public int getResInt() 
        return ResInt;
     
 

它将解决您的 UnrecognizedPropertyExceptions 问题

【讨论】:

【参考方案6】:

你需要Setter方法让Jackson设置属性,你需要将json中的字段改为小写字母开头:

public class Response 

    private Object ResObj;
    private int ResInt;

    public Object getResObj() 
        return ResObj;
    

    public void setResObj(Object ResObj) 
        this.ResObj = ResObj;
    

    // ...

和:

"resObj":"clientNum":"12345","serverNum":"78945","idNum":"020252","resInt":0

JSON 更改的原因是 Jackson bean 序列化将反映在类上,当它看到 getXyz() 和 setXyz() 方法时会将它们映射到 Json 文件名“xyz”(而不是“Xyz” )。

我认为有几种方法可以覆盖这种行为,一种是使用 Jackson 注释之一。

【讨论】:

显然你不需要二传手 取决于您如何配置反序列化器。我认为默认情况下,Jackson 将尝试 bean 样式的序列化 - 基于您的类上可用的 getXXX 方法。您是否尝试过添加 set 方法? 是的..它没有影响..仍然是同样的错误 您还需要将 JSON 字段更改为以小写字段开头。 @Ungeheuer 说实话不知道 - 大多数文档似乎都在第 3 方网站上。我对 Jackson 的大部分了解都来自于每次它做一些奇怪的事情时都必须调试实现代码。我已经停止使用它,因为它太特殊了——你总是不得不在任何地方使用注释来尝试让它合作。【参考方案7】:

您需要为 ResObj "ClientNum":"12345","ServerNum":"78945","IdNum":"020252" 中的信息定义另一个类。否则杰克逊无法确定如何反序列化。

【讨论】:

我做得很好,我称它为 ResObj,它有所需的字段,但它仍然不起作用,我的意思是:public class Response private ResObj resObj;公共 ResObj getResObj() 返回 resObj; .... 公共类 ResObj 私有字符串 ClientNum;私有字符串服务器编号;私有字符串 IdNum; public String getClientNum() return ClientNum; public String getServerNum() return ServerNum; public String getIdNum() return IdNum;

以上是关于com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段的主要内容,如果未能解决你的问题,请参考以下文章