Java Jackson的套接字上的Json

Java Jackson的套接字上的Json,java,json,sockets,jackson,Java,Json,Sockets,Jackson,我试图让两个应用程序通过TCP和基于JSON的消息进行通信。为此,我使用了杰克逊图书馆(1.9.4)。客户端只需打开一个套接字,然后侦听来自服务器的所有传入消息。看起来是这样的: ObjectMapper mapper = new ObjectMapper().configure( Feature.AUTO_CLOSE_SOURCE, false); final ObjectReader reader = mapper.reader(Message.class); So

我试图让两个应用程序通过TCP和基于JSON的消息进行通信。为此,我使用了杰克逊图书馆(1.9.4)。客户端只需打开一个套接字,然后侦听来自服务器的所有传入消息。看起来是这样的:

ObjectMapper mapper = new ObjectMapper().configure(
            Feature.AUTO_CLOSE_SOURCE, false);
final ObjectReader reader = mapper.reader(Message.class);

Socket s = new Socket("192.168.1.102", 32000);
final Reader in = new InputStreamReader(socket.getInputStream());
while (true) {
    Message message = reader.readValue(in);
    process(message)
}
因此,读取器阻塞并等待消息完成,以解析和处理它。 我的问题是,有时阅读时会跳过一些消息。如果服务器发送
msg1
msg
msg3
,则
msg2
可能丢失,但读取
msg3
没有问题

更奇怪的是,这种情况并不总是发生,但大约有50%。客户机和服务器都是单线程的,所以没有其他人可以访问套接字。我知道消息到达的事实,我试着用
nc
模拟客户端,传入的消息总是正确的,所以我知道是在阅读时

由于它是一个TCP套接字,它们到达的顺序是有保证的,因此我怀疑
ObjectReader
正在默默地丢弃一些东西,而没有抛出任何异常

有人知道会发生什么事吗?欢迎有任何想法!:)

差不多找到了

readValue()
方法只要在参考底图
Reader
上每次调用read时都能得到完整的JSON消息,就可以正常工作

因为我是从套接字读取的,所以有时候
read()
方法返回的消息不完整,而
ObjectReader
无法正确处理。这很奇怪,因为在读取之前,
ReaderBasedParser
类有一个
while()
,所以它应该只在整个消息都在那里时返回


当我有时间的时候,我会仔细看一看。

一个建议:不要做一个读者,按原样传递InputStream。构建阅读器没有任何好处,而且速度稍微慢一点。不确定这是否有助于解决问题本身,但杰克逊肯定会在必要时阻止阅读

然而,最有可能发生的情况是,由于底层的
JsonParser
进行缓冲(出于性能原因),缓冲数据不会返回(因为无法将数据“返回”到输入流或读取器)

JsonParser
确实有访问这些额外缓冲数据的方法,但解决此问题的最简单方法是显式创建
JsonParser
(通过
JsonFactory
),并将其传递给
ObjectReader
,而不是要求
ObjectReader
创建一个。这样,将使用相同的解析器,并使用它缓冲的数据。这也可能稍微快一点,因为没有每个解析器的创建开销


还有一种替代方法:查看
ObjectReader.readValues()
(注意其中的-s),它非常方便,工作方式与手动创建和传递解析器的方式几乎相同。

什么是
reader
,什么是
readValue()
?reader是来自Jackson库的ObjectReader,它应该读取传入的消息并对其进行解析(这是在readValue()方法中完成的)我一直在读废话,直到我意识到你就是StaxMan:D我尝试重用JsonParser,它似乎已经解决了问题,谢谢你,没问题!也许我应该把名字改成
@MrJackson
:-)最终全面解决了这个问题?@Garikai,不能说,又过了一段时间,新版本可能不再适用了,对不起,不用担心,最终解决了我的问题:)