一、问题描述
最近在重构大一时候写的一个项目,选用了jackson作为json序列化的工具。jackson提供了一个readValue
方法,可以直接读取Socket
获得的InputStream
,但是当我使用了这个方法以后就会报Socket is Closed
异常。
return objectMapper.readValue(inputStream, new TypeReference<JsonResult<User>>(){});
二、问题排查
我首先对代码逻辑进行了审查,发现代码逻辑是没有问题的。那么应该是Socket
因为某些原因提前关闭了。
然年我发现程序在服务器端可以正常的接受客户端发送的消息,但是服务器端无法正常发送消息给客户端。这说明问题应该出在发送消息的方法内。很显然,这个问题极有可能是因为jackson导致的。于是我查看了jackson源码中有关readValue
方法的部分:
它的这个方法具体实现我并没有看太懂,但是我猜想jackson在使用完InputStream
后会自动关闭InputStream
。对于Socket
,当Inputstream
被关闭时,Socket
也会被关闭,所以会出现这个异常。
三、解决思路
最后我的解决思路就是使用最原生的方法自己封装:
InputStream inputStream = socket.getInputStream();
byte [] bytes = new byte[1024];
int len;
StringBuilder stringBuilder = new StringBuilder();
String result;
while((len = inputStream.read(bytes)) != -1){
result = new String(bytes, 0, len, StandardCharsets.UTF_8);
stringBuilder.append(result);
}
result = stringBuilder.toString();