[英]How to exchange binary data between c++ and java using protocol buffers and ZeroMQ
[英]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.