我正在开发具有以下场景的多线程 java sevlet 数据来自不同的块,为此我只需要在最后一个请求中发送响应。数据块转发给其他类以保存数据。
public class RequestController extends HttpServlet implements ResponseHandler {
private ExecutorService pool;
public static ConcurrentHashMap<String, HttpServletResponse> cache;
static {
cache = new ConcurrentHashMap<String, HttpServletResponse>();
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try {
BufferedReader br = request.getReader();
String msg = br.readLine();
br.close();
if (msg == null) {
msg = request.getParameter("request");
//return;
}
String number = msg.substring(msg.indexOf("//") + 2, msg.indexOf(";"));
System.out.println("number = " + number);
cache.put(number, response);
System.out.println("Request received");
msg = URLDecoder.decode(msg, "UTF-8");
System.out.println(msg);
pool.submit(new DuplicaterRequestHandler(msg, this));
} catch (Exception e) {
e.printStackTrace(System.out);
} finally {
}
}
}
这是我的 servlet 代码。缓存是一个静态存储,我在收到所有请求后使用它来发送响应
我也有一个监听器,它告诉 sevlet 请求已完成
public interface ResponseHandler {
public void sendResponse(String number, String data);
}
它在 RequestController 中的实现是
@Override
public void sendResponse(String number, String data) {
System.out.print(number);
System.out.println(cache.containsKey(number));
if (cache.containsKey(number)) {
try {
PrintWriter pr = cache.get(number).getWriter();
pr.println(data);
pr.close();
cache.remove(number);
System.out.println("response sent.");
System.out.println("data:" + data);
} catch (Exception e) {
e.printStackTrace(System.out);
System.out.println(e.getMessage());
}
}
}
一切看起来都很好,但它有时会抛出异常,而不是每次,这对我来说是未知的。
java.lang.NullPointerException
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:240)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:119)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:504)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:383)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:342)
at org.apache.tomcat.util.buf.IntermediateOutputStream.write(C2BConverter.java:278)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:263)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:106)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at org.apache.tomcat.util.buf.WriteConvertor.write(C2BConverter.java:242)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
at java.io.BufferedWriter.write(BufferedWriter.java:212)
at org.apache.tomcat.util.buf.C2BConverter.convert(C2BConverter.java:132)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:497)
at org.apache.catalina.connector.CoyoteWriter.write(CoyoteWriter.java:174)
at org.apache.catalina.connector.CoyoteWriter.write(CoyoteWriter.java:184)
at org.apache.catalina.connector.CoyoteWriter.print(CoyoteWriter.java:242)
at org.apache.catalina.connector.CoyoteWriter.println(CoyoteWriter.java:309)
at duplicateserver.request.cotroller.RequestController.sendResponse(RequestController.java:132)
at duplicateserver.request.manager.CallLogRestoreManager.processRequest(CallLogRestoreManager.java:35)
at duplicateserver.request.handler.DuplicaterRequestHandler.run(DuplicaterRequestHandler.java:46)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
如何解决?提前致谢