Java 如何更改Jersey EventInput使用的分隔符
我需要订阅SSE(服务器发送事件)。我知道标准规定事件之间的分隔符应该是“\r\n\r\n”-检查语法中的“行尾”: 但我应该使用的流不符合标准,并用“\n”分隔 我决定对Jersey EventInput类进行替代实现,您可以在这里看到: 因此,我的实现将复制EventInput,唯一的区别是指定的分隔符。它看起来像:Java 如何更改Jersey EventInput使用的分隔符,java,jersey,server-sent-events,eventsource,Java,Jersey,Server Sent Events,Eventsource,我需要订阅SSE(服务器发送事件)。我知道标准规定事件之间的分隔符应该是“\r\n\r\n”-检查语法中的“行尾”: 但我应该使用的流不符合标准,并用“\n”分隔 我决定对Jersey EventInput类进行替代实现,您可以在这里看到: 因此,我的实现将复制EventInput,唯一的区别是指定的分隔符。它看起来像: public class MyEventInput extends ChunkedInput<InboundEvent> { /** * SSE event
public class MyEventInput extends ChunkedInput<InboundEvent> {
/**
* SSE event chunk parser - SSE chunks are delimited with a fixed "\n" and "\r\n\r\n" delimiter in the response stream.
*/
private static final ChunkParser SSE_EVENT_PARSER = ChunkedInput.createMultiParser("\n", "\r\n\r\n");
如果我执行以下操作,它将毫无问题地工作:
final EventInput eventInput = target.register(SseFeature.class)
.request().get(EventInput.class);
我开始调试,发现Jersey使用了一个名为MessageBodyFactory的类,该类进行如下检查:
if (isCompatible(model, c, mediaType))
及
if(model.isReadable(c,t,as,mediaType))
他们会检查您的类是否是有效的读取器。有效的读卡器是通过以下方式获得的(至少在我看来是这样,在调试时…):
final Set customMbrs=Providers.getCustomProviders(injectionManager,MessageBodyReader.class);
最终设置mbrs=Providers.getProviders(injectionManager,MessageBodyReader.class);
所以我的问题是。。。如何将MyEventInput注册为有效读取器,以便使用它订阅使用自定义分隔符分隔的SSE流?好的,因为我没有找到其他解决方案,我只是使用反射“破解”Jersey库,并为EventInput类指定了不同的解析器。我是这样做的(在实例化EventInput之前,必须重新定义SSE_EVENT_PARSER字段…):
if (isCompatible(model, c, mediaType))
final Set<MessageBodyReader> customMbrs = Providers.getCustomProviders(injectionManager, MessageBodyReader.class);
final Set<MessageBodyReader> mbrs = Providers.getProviders(injectionManager, MessageBodyReader.class);
Field f = EventInput.class.getDeclaredField("SSE_EVENT_PARSER");
f.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
f.set(null, ChunkedInput.createMultiParser("\n", "\r\n\r\n"));
final EventInput eventInput = target.request().get(EventInput.class);