java - 使用 json 在 c++ 和 java 之间交换对象
问题描述
我正在尝试使用 websockets 和 json 将存储在对象上的数据从 c++/qt 项目交换到 java/spring。通过 websockets 的通信工作正常,但在 java/spring 中,数据以null
.
在 c++ 类中,我有类似的东西:
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;
...
}
注册器.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;
...
}
(作为记录,一些类,比如usuario
在 java 中的字段比 c++ 多;其他类,比如registro
在 c++ 端或 java 端具有相同的字段)。
有人可以提示我这里有什么问题吗?我知道有一些库可以自动将 c++ 对象序列化为 json,但我不知道是否可以在不向我的项目中添加第三方组件的情况下做到这一点,只需为发送到 java 套接字的字符串找到正确的格式。
更新
我toString
将 c++ 端的方法更改为:
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
我toString
将 c++ 端的方法更改为:
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);
我得到一个NullPointerException
for value.getUsuario().getEmail()
。我真的需要从 c++ 端发送一个包含 java 类的所有字段的类吗?有什么方法可以让我只发送带有此查询所需字段的类?或者这不是问题?
解决方案
json
inUsuario::toString
不是有效的 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);
推荐阅读
- java - android 在 SurfaceView 的文件中记录 RTSP 流
- opengl - OpenGL - GLSL - 提取金属粗糙度贴图到金属贴图和粗糙度贴图?
- java - 当元素出现 Selenium+Java 时,如何在每次测试中每次调用方法?
- ios - 在所有 iCloud 设备上安排提醒(提醒)
- regex - Azure 资源密钥正则表达式
- python - 使用 xls 文件作为请求中数据的 python 的 PUT 模式请求
- java - 将构造函数与 Lambda 表达式一起使用(设置比较器)
- entity-framework - 通过访问来编辑记录
- r - 使用 R 中的键的 data.table 子集
- python - 如何在 Django 表单中指定字段的顺序?