Если я использую Resteasy, я могу использовать Resteasy-ДЖЕКСОН-провайдер, который обрабатывает сортировочным свои объекты в JSON и обратно для моих остальных конечных точек, например:Generic кодеры и декодеры с Jetty WebSockets
@GET
@Path("/")
@Produces({MediaType.APPLICATION_JSON})
public MyThing getSingle() {
return new MyThing();
}
Это хорошо, поскольку это означает, что мне не нужно указывать кодировщик для каждого типа - Джексон просто справляется с этим.
Я сейчас обучения WebSockets, и я считаю, что я должен предоставить кодеры:
@ServerEndpoint(value = "/websocket", encoders = {MyThingEncoder.class}, decoders = {MyThingDecoder.class})
public class Websocket {
@OnOpen
public void onOpen(Session session) {
session.getBasicRemote().sendObject(new MyThing());
}
}
Это расстраивает, так как я не хочу, чтобы обеспечить кодер/декодер для каждого отдельного типа объекта , особенно если они просто используют Джексона. Прямо сейчас, мои кодер/декодеры выглядеть следующим образом:
public class MyThingEncoder implements Encoder.Text<MyThing> {
private static final ObjectMapper MAPPER = new ObjectMapper();
@Override
public void init(EndpointConfig endpointConfig) {
}
@Override
public void destroy() {
}
@Override
public String encode(MyThing t) throws EncodeException {
try {
return MAPPER.writeValueAsString(t);
} catch (IOException e) {
throw new EncodeException(t, "Could not encode.", e);
}
}
}
Я попытался с помощью дженериков, изменив определение класса на MyThingEncoder (ниже), но он бросил исключение (и ниже):
package com.jetnuts.serv.encoders;
import org.codehaus.jackson.map.ObjectMapper;
import org.jboss.resteasy.util.Encode;
import javax.websocket.*;
import java.io.IOException;
public class MyThingEncoder<T> implements Encoder.Text<T> {
private static final ObjectMapper MAPPER = new ObjectMapper();
Class<T> typeOf;
@Override
public void init(EndpointConfig endpointConfig) {
}
@Override
public void destroy() {
}
@Override
public String encode(T t) throws EncodeException {
try {
return MAPPER.writeValueAsString(t);
} catch (IOException e) {
throw new EncodeException(t, "Could not encode.", e);
}
}
}
исключение:
org.eclipse.jetty.websocket.api.InvalidWebSocketException: Invalid type declared for interface javax.websocket.Encoder$Text on class class com.jetnuts.serv.encoders.MyThingEncoder
at org.eclipse.jetty.websocket.jsr356.metadata.EncoderMetadataSet.getEncoderType(EncoderMetadataSet.java:82)
at org.eclipse.jetty.websocket.jsr356.metadata.EncoderMetadataSet.discover(EncoderMetadataSet.java:50)
at org.eclipse.jetty.websocket.jsr356.metadata.CoderMetadataSet.addAll(CoderMetadataSet.java:78)
at org.eclipse.jetty.websocket.jsr356.server.AnnotatedServerEndpointMetadata.<init>(AnnotatedServerEndpointMetadata.java:51)
at org.eclipse.jetty.websocket.jsr356.server.ServerContainer.getServerEndpointMetadata(ServerContainer.java:162)
at org.eclipse.jetty.websocket.jsr356.server.ServerContainer.addEndpoint(ServerContainer.java:87)
at org.eclipse.jetty.websocket.jsr356.server.ServerContainer.doStart(ServerContainer.java:139)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
at org.eclipse.jetty.server.handler.ScopedHandler.doStart(ScopedHandler.java:120)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:803)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:344)
at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1379)
at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1341)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:772)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:261)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:517)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:41)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:188)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:499)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:147)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180)
at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:458)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392)
at org.eclipse.jetty.util.Scanner$1.run(Scanner.java:329)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
Как я могу избежать необходимости кодера/декодера, который делает ту же самую вещь для каждого типа объекта, я хочу отправить/получить?
Я нашел, что я могу просто использовать «объект» для кодера, но для декодера мне еще нужно указать тип. – ThePerson