【问题标题】:Jackson Json Deserialisation: Unrecognized field "..." , not marked as ignorableJackson Json反序列化:无法识别的字段“...”,未标记为可忽略
【发布时间】:2014-03-04 13:35:02
【问题描述】:

我收到以下错误,但我没有找到解决办法:

无法识别的字段“GaugeDeviceId”(GaugeDevice 类),未标记为可忽略

问题似乎是,服务返回的属性名称以大写字母开头,而类属性以小写字母开头。

我试过了:

  1. 将 propertyNames 更改为第一个大写字母 - 相同的错误
  2. @JsonProperty("SerialNo") 添加到属性实例化 - 同样的错误
  3. @JsonProperty("SerialNo") 添加到相应的getter - 同样的错误
  4. @JsonProperty("SerialNo") 添加到相应的setter - 同样的错误
  5. @JsonProperty("SerialNo") 添加到所有这些(只是为了好玩)- 相同的错误

(注意:@JsonProperty("SerialNo") 只是一个例子)

奇怪的是,注释:@JsonIgnoreProperties(ignoreUnknown = true) 应该完全抑制该错误,但它仍在触发......

这里是类:(注:不完整)

@JsonIgnoreProperties(ignoreUnknown = true)
public class GaugeDevice 
{
    private int gaugeDeviceId;
    private Date utcInstallation;
    private String manufacturer;
    private float valueOffset;
    private String serialNo;
    private String comment;
    private int digitCount;
    private int decimalPlaces;

    @JsonProperty("SerialNo")
    public String getSerialNo() {
        return serialNo;
    }

    public void setSerialNo(String serialNo) {
        this.serialNo = serialNo;
    }

    @JsonProperty("Comment")
    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

这里的出路在哪里?请帮忙。

编辑:

这是客户端类:(只是一个简单的测试客户端)

import ccc.android.meterdata.*;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Invocation;
import org.glassfish.jersey.jackson.JacksonFeature;

public class RestClient
{
    private String connectionUrl;
    private javax.ws.rs.client.Client client;

    public RestClient(String baseUrl) {
         client = ClientBuilder.newClient();;
         connectionUrl = baseUrl;
         client.register(JacksonFeature.class); 
    }

    public GaugeDevice GetGaugeDevice(int id){

        String uri = connectionUrl + "/GetGaugeDevice/" + id;
        Invocation.Builder bldr = client.target(uri).request("application/json");
        return bldr.get(GaugeDevice.class);
    }
}

我希望错误的根源在这里?

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    我遇到了同样的问题,我通过更改注释导入来解决它:

    com.fasterxml.jackson.annotation.JsonIgnoreProperties
    

    org.codehaus.jackson.annotate.JsonIgnoreProperties
    

    不必定义任何 NamingStrategy 或 ObjectMapper。

    【讨论】:

    • 谢谢,我有同样的错误,INTELIJ IDE 不询问选择,自动设置错误。
    【解决方案2】:

    我有同样的问题,并通过更改注释导入来解决它

    com.fasterxml.jackson.annotation.JsonProperty
    

    org.codehaus.jackson.annotate.JsonProperty
    

    【讨论】:

      【解决方案3】:

      要检查的另一件事是PropertyNamingStrategy,这将允许 Jackson 使用“Pascal 命名”并将 JSON 属性与 POJO 属性匹配。在此处查看 f.ex:http://www.javacodegeeks.com/2013/04/how-to-use-propertynamingstrategy-in-jackson.html

      【讨论】:

        【解决方案4】:

        鉴于以下是您的错误:

        无法识别的字段“GaugeDeviceId”(GaugeDevice 类),未标记为可忽略

        我很确定您需要对 GaugeDeviceId 属性执行与对 SerialNo 属性所做的相同的操作。

        @JsonProperty("SerialNo")
        public String getSerialNo() {
            return this.serialNo;
        }
        
        @JsonProperty("GaugeDeviceId")
        public int getGaugeDeviceId() {
            return this.gaugeDeviceId;
        }
        

        这里我有一个不会抛出错误的快速测试类。

        import org.codehaus.jackson.map.ObjectMapper;
        
        public class JsonDeserialization {
            public static void main(final String[] args) {
                final String json = "{ \"SerialNo\":\"123\", \"GaugeDeviceId\":\"456\"}";
        
                final ObjectMapper mapper = new ObjectMapper();
        
                try {
                    final GaugeDevice readValue = mapper.readValue(json, GaugeDevice.class);
                    System.out.println(readValue.getSerialNo());
                    System.out.println(readValue.getGaugeDeviceId());
                } catch (final Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        

        它输出:

        123
        456
        

        编辑:版本信息

        没关系,因为我相信以上都是使用杰克逊的一些非常标准的东西,我使用的是 core-asl1.9.13 版本和 ma​​pper-asl


        编辑:客户提供

        我想知道这是否与this issue有关?我相信解决方案是您正在使用的依赖项的配置。

        我不确定,但我觉得我很接近以下依赖项设置(注意我使用的是 maven)

            <dependency>
                <groupId>javax.ws.rs</groupId>
                <artifactId>javax.ws.rs-api</artifactId>
                <version>2.0</version>
            </dependency>
            <dependency>
                <groupId>org.glassfish.jersey.media</groupId>
                <artifactId>jersey-media-json-jackson</artifactId>
                <version>2.0</version>
            </dependency>
            <dependency>
                <groupId>org.glassfish.jersey.core</groupId>
                <artifactId>jersey-client</artifactId>
                <version>2.0</version>
            </dependency>
            <dependency>
                <groupId>org.glassfish.jersey.media</groupId>
                <artifactId>jersey-media-json-processing</artifactId>
                <version>2.0</version>
            </dependency>
        

        这些链接提供了配置信息:Link 1Link 2

        【讨论】:

        • 是的,它有。我的代码只是一个外卖。我已经尝试过了,但没有成功。
        • @chile 你可以添加反序列化对象的代码吗?如果您的 GaugeDevice 具有正确的注释,那么如果 ObjectMapper 不包含任何自定义(反)序列化器,它应该可以工作。
        • 添加了客户端类...也许我使用了已弃用的东西?
        【解决方案5】:

        您可以在反序列化时忽略未知属性,方法是在类级别使用注释。

        例如:

        @JsonIgnoreProperties(ignoreUnknown=true)
        class Foo{
         ...
        }
        

        上面的 sn-p 将忽略任何未知属性。 (注解导入:org.codehaus.jackson.annotate.JsonIgnoreProperties)

        【讨论】:

          【解决方案6】:

          将所有私有变量和成员设为public。 Jackson 处理公共成员变量。

          public int gaugeDeviceId;
          public Date utcInstallation; 
          ....
          

          或将公共 Getter 添加到私有字段。

          【讨论】:

            【解决方案7】:

            对我有用的解决方案如下

            1. 添加导入

              import org.codehaus.jackson.map.DeserializationConfig;
              
            2. 配置对象映射器

              objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
              
            3. 完整的解决方案

              ObjectMapper objectMapper = new ObjectMapper();      
              objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);     
              String jsonInString = objectMapper.writeValueAsString(eje); 
              Eje newElement = objectMapper.readValue(jsonInString, Eje.class); 
              this.eje = newElement;
              

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-04-19
              • 1970-01-01
              • 2011-05-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-10-11
              相关资源
              最近更新 更多