收到的对象与模型不对应

huangapple go评论73阅读模式
英文:

Object received does not correspond to model

问题

我有一个问题,但我发现很难表达出来。我从MQTT接收到一个byte[]类型的消息,然后我将其转换为一个String,然后将结果发送到GSON,GSON会创建一个JenkinsMqttObject对象。

String messageToString = message.getPayload().toString();
JenkinsMqttObject monobjet = gson.fromJson(messageToString, JenkinsMqttObject.class);

在这个示例代码中,JenkinsMqttObject非常简化。我遇到的问题是:

MQTT 给我发送一个对象,可能是这样的:
> "{"value1":20,"value2":40}

但也可能是这样的:
> "{"value1":20,"value2":40,"value3":60}

所以根据情况,我收到一个包含2个或3个属性的对象。问题是,我创建了一个Java模型,就像这样:

JenkinsMqttObject.class

private String value1;
private String value2;
private String value3;
//getter & setters...

问题是,我告诉GSON接收到的对象是JenkinsMqttObject类型,但这并不总是正确的!

所以我完全不知道如何能够在Java中接收一个可能与模型对应或不对应的对象。

谢谢帮助!

英文:

I have a problem, but I find it hard to express it. I receive from MQTT a message in byte[], I convert it into a String, then the result is sent to GSON which creates me a JenkinsMqttObject.

String messageToString = message.getPayload().toString();
JenkinsMqttObject monobjet = gson.fromJson(messageToString, JenkinsMqttObject.class);

In the example code, JenkinsMqttObject is very simplified. The problem I have is the following:

MQTT sends me an object which can be :
> "{"value1":20,"value2":40}

But that can also be :
> "{"value1":20,"value2":40,"value3":60}

So depending on the case, I receive an object that contains 2 or 3 attributes.
The problem is that I created a java model like this:

JenkinsMqttObject.class

private String value1;
private String value2;
private String value3;
//getter & setters...

The problem is that i say at GSON that the object received is of type JenkinsMqttObject but it's not all time right !

So i don't know at all, how to be able to receive an object in Java that can correspond or not to a model.

Thanks for help !

答案1

得分: 1

你应该在你的 Model 类中使用 MapHashMap。它的结构应该类似于下面的示例代码。

class JenkinsMqttObject{
    HashMap<String, String> values;
    //getters & setters
}

你需要修改主要的代码如下。

String messageToString = message.getPayload().toString();
HashMap<String, String> vmap = new Gson().fromJson(messageToString, new TypeToken<HashMap<String, String>>(){}.getType());
JenkinsMqttObject monobjet = new JenkinsMqttObject();
monobjet.setValues(vmap);

现在,如果你想访问任何值,可以按以下方式访问。

monobjet.getValues().get("value1");
英文:

You should take help of Map or HashMap for your Model class. It should be similar to the class given below.

class JenkinsMqttObject{
    HashMap&lt;String, String&gt; values;
    //getters &amp; setters
}

You have to modify the main code as below.

String messageToString = message.getPayload().toString();
HashMap&lt;String,String&gt; vmap = new Gson().fromJson(messageToString , new TypeToken&lt;HashMap&lt;String, String&gt;&gt;(){}.getType());
JenkinsMqttObject monobjet = new JenkinsMqttObject();
monobjet.setValues(vmap);

Now if you want to access any value, you can access it as below.

monobjet.getValues().get(&quot;value1&quot;);

答案2

得分: 0

按照RLD在StackOverflow上的回答所建议的,Map是合适的方法。

你可以使用TypeToken,但你也可以声明一个特定的类,避免使用前面提到的方式,使解析更简单,直接将其解析到映射中:

public class JenkinsMqttObject extends HashMap<String, Object> {}

另外,我认为如果你使用byte[].toString(),它不会产生有效的JSON,但是从byte[]构造一个新的String对象会起作用:

JenkinsMqttObject monobjet = gson.fromJson(new String(message.getPayload()),
                                               JenkinsMqttObject.class);

然后只需:

monobjet.get("value1");
英文:

As RLD's answer suggests, Map is the way to go.

You can use TypeToken but you can also declare a specific class to avoid using beforementioned and make parsing even simpler so parse it straight into the map:

public class JenkinsMqttObject extends HashMap&lt;String, Object&gt; {}

Also I do not think that if you put byte[].toString() it will produce you valid JSON but costructing a new String objects from a byte[] will work:

JenkinsMqttObject monobjet = gson.fromJson(new String(message.getPayload()),
                                               JenkinsMqttObject.class);

Then it is just to:

monobjet.get(&quot;value1&quot;);

答案3

得分: 0

如评论中所述,当 JSON 中缺少 value3 时,gson 将会在 JenkinsMqttObject 实例中将 value3 设置为 null。根据 gson 文档(我加重了语气):

  • 此实现正确处理了 null 值。

    • 在序列化过程中,null 字段将被省略在输出中。
    • 在反序列化过程中,JSON 中缺少的条目将导致将对象中对应的字段设置为其默认值:对于对象类型为 null,对于数值类型为零,对于布尔类型为 false。
英文:

as already stated in the comments, when value3 is missing in the json, gson will set value3 to null in the JenkinsMqttObject instance. from gson documentation (emphasis mine):

> - This implementation handles nulls correctly.
>
> - While serializing, a null field is omitted from the output.
> - While deserializing, a missing entry in JSON results in setting the corresponding field in the object to its default value: null for object types, zero for numeric types, and false for booleans.

huangapple
  • 本文由 发表于 2020年9月5日 21:38:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/63754527.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定