簡體   English   中英

使用 Gson 反序列化 Java 泛型

[英]Deserializing Java Generics with Gson

我正在我的網絡服務器上為我的 WebSocket (STOMP) 編寫一個庫。 我正在嘗試使庫返回泛型中指定的對象。

添加 stomp 客戶端

public <T> void addStompClient(T t, String url, String subscription, StompMessageListener<T> listener) {
    StompClient<T> sc = new StompClient<T>(t, URI.create(url));
    StompConnectionListener scl = new StompConnectionListener() {
        public void onConnecting() {}
        public void onConnected() {
            sc.subscribe(subscription, listener);
        }
        public void onDisconnected() {}
        
    };
    sc.setStompConnectionListener(scl);
    sc.connect();
    clients.add(sc);
}

StompMessageListener

@FunctionalInterface
public interface StompMessageListener<T> {

    void onMessage(T test);

}

StompClient 類方法和變量

@Getter
private T t;

protected StompClient(T tclass, URI serverUri) {
    super(serverUri);
    t = tclass;
}

@SuppressWarnings("unchecked")
@Override
public void onMessage(String message) {
    StompFrame stompFrame = StompFrame.fromString(message);
    
    switch (stompFrame.getCommand()) {
    case CONNECTED:
        stompConnected = true;
        if (stompConnectionListener != null) {
            stompConnectionListener.onConnected();
        }
        break;
    case MESSAGE:
        Integer subscriptionId = Integer.valueOf(stompFrame.getHeaders().get(StompHeader.SUBSCRIPTION.toString()));
        
        Class<T> tclass = (Class<T>) t.getClass();
        T test = (T) new Gson().fromJson(stompFrame.getBody(), tclass);
        
        StompSubscription<T> listener = (StompSubscription<T>) subscriptions.get(subscriptionId);
        listener.getListener().onMessage(test);
        break;
    case DISCONNECT:
        stompConnected = false;
        if (stompConnectionListener != null) {
            stompConnectionListener.onDisconnected();
        }
        break;
    default:
        break;
    }
}

來電:

clientManager.addStompClient(Category.class, "ws://localhost:8080/stomp-api/v1/hub", "/stomp-api/v1/listener/category/create", (category) -> {
        Bukkit.getConsoleSender().sendMessage(category.getName());
    });

但在這樣做時,我得到:

java.lang.UnsupportedOperationException:試圖反序列化 java.lang.Class。 忘記注冊類型適配器?

有人知道怎么修這個東西嗎? 我嘗試添加類型適配器,但不知道如何正確執行

如果有人遇到這個問題,這就是我使用來自的評論解決這個問題的方法

或者,您可以使用 Jackson,它可以從類中反序列化。 這是一個例子。 ——克里斯托弗·施耐德

@Override
public void onMessage(String message) {
    StompFrame stompFrame = StompFrame.fromString(message);
    
    switch (stompFrame.getCommand()) {
    case CONNECTED:
        stompConnected = true;
        if (stompConnectionListener != null) {
            stompConnectionListener.onConnected();
        }
        break;
    case MESSAGE:
        Integer subscriptionId = Integer.valueOf(stompFrame.getHeaders().get(StompHeader.SUBSCRIPTION.toString()));
        
        ObjectMapper objectMapper = new ObjectMapper(new Gson());
        T t = objectMapper.readValue(stompFrame.getBody(), tclass);
        
        StompSubscription<T> listener = (StompSubscription<T>) subscriptions.get(subscriptionId);
        listener.getListener().onMessage(t);
        break;
    case DISCONNECT:
        stompConnected = false;
        if (stompConnectionListener != null) {
            stompConnectionListener.onDisconnected();
        }
        break;
    default:
        break;
    }
}

ObjectMapper 就位。 tclass = 類。 這允許我使用 Jackson 和 Generics 來提供將從 stomp 監聽器返回的對象

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM