Как сериализовать POJO для отправки через Java RSocket?

Я пытаюсь отправить POJO через поток запросов RSocket:

import java.io.Serializable;

class GreetingRequest implements Serializable {
    private String name;

    public GreetingRequest() {}

    public GreetingRequest(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Если бы я отправил строку, я мог бы сделать:

ByteBuf data = ByteBufAllocator.DEFAULT.buffer().writeBytes("Hello".getBytes());

socket.requestStream(DefaultPayload.create(data, metadata))
        .map(Payload::getDataUtf8)
        .toIterable()
        .forEach(System.out::println);

Но как я могу сериализовать свой POJO?

Это моя попытка использовать implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0', которая не работает:

GreetingRequest pojo = new GreetingRequest("Davide");
ByteBuf data = SerializationUtils.serialize(pojo);

socket.requestStream(DefaultPayload.create(data, metadata))
        .map(Payload::getDataUtf8)
        .toIterable()
        .forEach(System.out::println);

person Javide    schedule 28.06.2021    source источник


Ответы (3)


Я рекомендую вам использовать конвертер Gson. Это поможет вам преобразовать класс Java в JSON String. Затем вы можете работать со строкой String так же, как если бы вы работали с простым текстом.

Вы можете импортировать зависимость:

dependencies {
  implementation 'com.google.code.gson:gson:2.8.7'
}

Затем можно использовать jsonschema2pojo для преобразования JSON:

{ "name": "Test" }

к таким классам, как этот:

    package com.example;
    
    import javax.annotation.Generated;
    import com.google.gson.annotations.Expose;
    import com.google.gson.annotations.SerializedName;
    
    public class GreetingRequest {
    
    @SerializedName("name")
    @Expose
    private String name;
    
    public String getName() {
    return name;
    }
    
    public void setName(String name) {
    this.name = name;
    }
    
    }

После того, как все сделано, вы можете сделать что-то вроде этого в Java:

    Gson converter = new Gson();
    GreetingsRequest request = new GreetingRequest();
    request.setName("Test");
    String greetingsJSON = converter.toJson(request);

И тогда вы все еще можете отправить строку JSON следующим образом:

ByteBuf data = ByteBufAllocator.DEFAULT.buffer().writeBytes(greetingsJSON.getBytes());

socket.requestStream(DefaultPayload.create(data, metadata))
        .map(Payload::getDataUtf8)
        .toIterable()
        .forEach(System.out::println);

Преобразования данных:

  • Объект JSON — класс Java
  • Массив - Список‹›

Полезные ссылки:

person César Ferreira    schedule 28.06.2021

Существует собственный механизм сериализации Java, который я бы НЕ рекомендовал, но вы можете прочитать о нем. Прочтите об интерфейсе Serialazable в Java API. Есть 2 варианта, которые я бы рекомендовал:

  1. JSON-JACKSON (также известный как Faster XML)
  2. GSON (упоминается в ответе Сезара Феррейры)

Оба конвертируют классы в JSON и наоборот. Для JSON-JACKSON см. класс ObectMapper. В частности, методы writeValueAsString() или writeValueAsBytes() для сериализации вашего объекта в строку или байты JSON. И чтобы преобразовать его обратно, найдите метод readValue().

Вот артефакты Maven, которые вам понадобятся для его использования:

        <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.12.3</version>        
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.12.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
      <version>2.12.3</version>
    </dependency>
person Michael Gantman    schedule 28.06.2021

Если вы используете такой фреймворк, как Spring Boot, об этом позаботятся за вас. Вы можете захотеть вручную контролировать, и в этом случае другие примеры более актуальны, но есть преимущества в производительности для Spring Boot или rsocket-rpc.

https://github.com/rsocket/rsocket-demo/blob/master/src/main/kotlin/io/rsocket/demo/chat/ChatController.kt

https://spring.io/blog/2020/03/02/начало-с-rsocket-spring-boot-server

или rsocket-rpc-java с использованием protobuf вместо сериализации

https://github.com/rsocket/rsocket-rpc-java/blob/master/docs/get-started.md

person Yuri Schimke    schedule 29.06.2021