Обмен объектами между c ++ и java с использованием json - PullRequest
0 голосов
/ 20 апреля 2020

Я пытаюсь обменяться данными, хранящимися на объектах из проекта c ++ / qt, в java / spring, используя websockets и json. связь через 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();
};

registro.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;
...
}

(для записи некоторые классы, такие как usuario, имеют больше полей в java, чем c ++; другие, такие как registro, имеют те же поля либо на стороне c ++, либо на стороне java.

кто-то может намекнуть мне, что здесь не так? Я знаю, что есть некоторые библиотеки, которые могут сериализовать объект c ++ в json автоматически, но я не знаю, возможно ли это сделать без добавления стороннего компонента в мой проект, просто найдя правильный формат для строки, отправляемой в java socket.

update

Я изменяю метод 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"
}

update 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 для value.getUsuario().getEmail(). Мне действительно нужно отправить класс со стороны C ++ со всеми полями из класса java? Есть ли способ разрешить мне отправлять только класс с полями, необходимыми для этого запроса? Или это не проблема?

1 Ответ

1 голос
/ 20 апреля 2020

json в Usuario::toString недопустимо JSON. QJsonDocument::fromJson возвращает null при сбое синтаксического анализа.

При условии, что email не заключен в кавычки, вам нужно:

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

В качестве альтернативы, более безопасным и простым было бы использование API JSON :

QJsonObject json{
  { "email", email }
};
QJsonDocument document = QJsonDocument::fromJson(json);
QByteArray prettyPrintedJson = document.toJson(QJsonDocument::Indented);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...