简体   繁体   English

使用 json 在 c++ 和 java 之间交换对象

[英]Exchange objects between c++ and java using json

I am trying exchange data stored on objects from a c++/qt project to java/spring using websockets and json.我正在尝试使用 websockets 和 json 将存储在对象上的数据从 c++/qt 项目交换到 java/spring。 the communication via websockets are working fine, but in the java/spring the data arrives as null .通过 websockets 的通信工作正常,但在 java/spring 中,数据以null的形式到达。

in the c++ class, i have something like that:在 c++ class 中,我有类似的东西:

QString Usuario::toString() {
    QString json = "{'email': "+email+"}";
    QJsonDocument document = QJsonDocument::fromJson(json.toUtf8());
    QByteArray prettyPrintedJson = document.toJson(QJsonDocument::Indented);
    return prettyPrintedJson;
}

for classes like that:对于这样的课程:

usuario.h usuario.h

class Usuario
{
private:
    QString email;
public:
    Usuario();
    Usuario(QString email);

    QString getEmail();
    void setEmail(QString email);

    QString toString();
};

registro.h注册机.h

class Registro
{
private:
    QString token;
    Usuario usuario;
    Produto produto;
    Maquina maquina;
public:
    Registro();
    Registro(QString token, Usuario usuario, Produto produto, Maquina maquina);
    Registro(Usuario usuario, Produto produto, Maquina maquina);

    QString getToken();
    void setToken(QString token);

    Usuario getUsuario();
    void setUsuario(Usuario usuario);

    Produto getProduto();
    void setProduto(Produto produto);

    Maquina getMaquina();
    void setMaquina(Maquina maquina);

    QString toString();
};

in the java project, I have something like this:在 java 项目中,我有这样的事情:

@Component
public class CheckRegistro extends TextWebSocketHandler {
...
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws InterruptedException, IOException {
    Registro value = new Gson().fromJson(message.getPayload(), Registro.class);
    System.out.println("registro -> " + value);

    String email_usuario = value.getUsuario().getEmail();
    Usuario usuario = usuarioServ.findBy("email", email_usuario);

    String nome_produto = value.getProduto().getNome();
    Produto produto = produtoServ.findBy("nome", nome_produto);

    Cliente cliente = clienteServ.findBy("usuario", usuario);
    if(cliente.produtosComprados().contains(produto))
      value = registroServ.findBy("produto", produto);

    String result = new Gson().toJson(value);
        session.sendMessage(new TextMessage(result));
    }
...
}

and classes like that:和这样的课程:

usuario.java usuario.java

@Entity
public class Usuario extends Model implements UserDetails {
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Integer id;

  @Column
  private String username;

  @Column
  private String password;

  @Column
  private String firstName;

  @Column
  private String lastName;

  @Column
  private String email;
...
}

registro.java registro.java

@Entity
public class Registro extends Model{
  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Integer id;

  @Column
  private String token;

  @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  private Usuario usuario;

  @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  private Produto produto;

  @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  private Maquina maquina;
...
}

(for the record, some classes, like usuario have more fields in java than c++; others, like registro have the same fields either on the c++ side or in the java side). (for the record, some classes, like usuario have more fields in java than c++; others, like registro have the same fields either on the c++ side or in the java side).

someone can hint me what's wrong here?有人可以提示我这里有什么问题吗? I know there is some libraries that can serialize the c++ object into json automatically, but I dunno if it's possible do that without add a third-party component to my project, just finding the right format for the string sent to the java socket. I know there is some libraries that can serialize the c++ object into json automatically, but I dunno if it's possible do that without add a third-party component to my project, just finding the right format for the string sent to the java socket.

update更新

I change the toString method in the c++ side to something like that:我将 c++ 端的toString方法更改为:

QString Registro::toString() {
    QJsonObject json{
      { "token", token },
      { "usuario", usuario.toString() },
      { "produto", produto.toString() },
      { "maquina", maquina.toString() }
    };
    QJsonDocument jsonDoc;
    jsonDoc.setObject(json);
    QByteArray prettyPrintedJson = jsonDoc.toJson(QJsonDocument::Indented);
    return prettyPrintedJson;
}

and now, in the java side, the json string is printed like that:现在,在 java 一侧, json 字符串打印如下:

"registro": "{\n    \"maquina\": \"{\\n    \\\"cpuArch\\\": \\\"x86_64\\\",\\n    \\\"hostName\\\": \\\"DESKTOP-7GAPC4K\\\",\\n    \\\"kernelType\\\": \\\"windows\\\",\\n    \\\"kernelVersion\\\": \\\"10\\\",\\n    \\\"productName\\\": \\\"Windows 10 Version 1909\\\",\\n    \\\"ram\\\": \\\"RAM: 16030 MB\\\",\\n    \\\"uniqueId\\\": \\\"c69d8cc7-8e66-4ea3-964a-792b2c2a6f80\\\"\\n}\\n\",\n    \"produto\": \"{\\n    \\\"nome\\\": \\\"prod1\\\"\\n}\\n\",\n    \"token\": \"\",\n    \"usuario\": \"{\\n    \\\"email\\\": \\\"klebermo@gmail.com\\\"\\n}\\n\"\n}\n"
}

update 2更新 2

I change the method toString in the c++ side to something like that:我将 c++ 端的toString方法更改为:

QString Registro::toString() {
    return "{ \"token\": \""+token+"\", \"usuario\": "+usuario.toString()+", \"produto\": "+produto.toString()+", \"maquina\": "+maquina.toString()+" }";
}

and now in the java side I get a valid json, but here:现在在 java 方面,我得到了一个有效的 json,但在这里:

Registro value = new Gson().fromJson(message.getPayload(), Registro.class);

String email_usuario = value.getUsuario().getEmail();
Usuario usuario = usuarioServ.findBy("email", email_usuario);

String nome_produto = value.getProduto().getNome();
Produto produto = produtoServ.findBy("nome", nome_produto);

I am geting a NullPointerException for value.getUsuario().getEmail() .value.getUsuario().getEmail()NullPointerException I really need send a class from the c++ side with all the fields from the java class?我真的需要从 c++ 端发送一个 class 以及来自 java ZA2F2ED4F8EBC2CBB4C21A29DC4 的所有字段? Is there any way to allow me send only the class with fields needed for this query?有什么方法可以让我只发送带有此查询所需字段的 class 吗? Or this is not the problem?或者这不是问题?

json in Usuario::toString is not valid JSON. Usuario Usuario::toString json JSON。 QJsonDocument::fromJson returns null when parsing fails.解析失败时, QJsonDocument::fromJson返回null

Assuming email is not quoted you need:假设email没有被引用,你需要:

QString json = "{\"email\": \""+email+"\"}";

Alternatively, safer and simpler would be to use the JSON API:或者,更安全、更简单的是使用 JSON API:

QJsonObject json{
  { "email", email }
};
QJsonDocument document = QJsonDocument::fromJson(json);
QByteArray prettyPrintedJson = document.toJson(QJsonDocument::Indented);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM