簡體   English   中英

使用 json 在 c++ 和 java 之間交換對象

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

我正在嘗試使用 websockets 和 json 將存儲在對象上的數據從 c++/qt 項目交換到 java/spring。 通過 websockets 的通信工作正常,但在 java/spring 中,數據以null的形式到達。

在 c++ class 中,我有類似的東西:

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

對於這樣的課程:

usuario.h

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

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

    QString toString();
};

注冊機.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();
};

在 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));
    }
...
}

和這樣的課程:

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

@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).

有人可以提示我這里有什么問題嗎? 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.

更新

我將 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;
}

現在,在 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"
}

更新 2

我將 c++ 端的toString方法更改為:

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

現在在 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);

value.getUsuario().getEmail()NullPointerException 我真的需要從 c++ 端發送一個 class 以及來自 java ZA2F2ED4F8EBC2CBB4C21A29DC4 的所有字段? 有什么方法可以讓我只發送帶有此查詢所需字段的 class 嗎? 或者這不是問題?

Usuario Usuario::toString json JSON。 解析失敗時, QJsonDocument::fromJson返回null

假設email沒有被引用,你需要:

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

或者,更安全、更簡單的是使用 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