将序列化数据发送到 servlet 时出现 java.io.EOFException
我试图从我的 Java 本地应用程序上传一个包含文件到服务器的对象。我的计划是,在 tomcat 上运行的 servlet 将使用 doGet
方法中的 ObjectInputStream
获取对象。但我得到了一个EOFE
xception`。
这是客户端代码
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws IOException {
FileInputStream inputStream = new FileInputStream("c:\\rafi.txt");
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int n = 0;
while (-1 != (n = inputStream.read(buffer))) {
output.write(buffer, 0, n);
}
inputStream.close();
File2 c2 = new File2(buffer);
URL url = new URL("http://localhost:8080/servertest/Server");
URLConnection cnx = url.openConnection();
cnx.setDoInput(true);
cnx.setDoOutput(true);
cnx.setRequestProperty("Content-Type", "application/octet-stream");
InputStream in = cnx.getInputStream();
OutputStream out = cnx.getOutputStream();
cnx.connect();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(c2);
oos.flush();
oos.close();
ObjectInputStream ois = new ObjectInputStream(in);
boolean readBoolean = ois.readBoolean();
System.out.println(readBoolean);
ois.close();
in.close();
out.close();
}
}
,这是服务器的 servlet
import java.io.*;
import javax.servlet.*;
@WebServlet("/Server")
public class Server extends HttpServlet {
private static final long serialVersionUID = 1L;
public Server() {
super();
}
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
InputStream in = req.getInputStream();
OutputStream out = res.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
ObjectInputStream ois = new ObjectInputStream(in);
File2 data_in;
try {
data_in = (File2) ois.readObject();
byte[] a = new byte[data_in.mybytearray.length];
System.arraycopy(data_in.mybytearray, 0, a, 0,data_in.mybytearray.length);
System.out.println(a.toString());
oos.writeBoolean(true);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
oos.writeBoolean(false);
}
finally{
oos.close();
}
res.setContentType("java-internal/" + File2.class.getName());
in.close();
}
}
当我调试服务器端并运行客户端时,我在这一行中得到异常
ObjectOutputStream oos = new ObjectOutputStream(out);
这是我看到的错误
SEVERE: Servlet.service() for servlet [test1.Server] in context with path [/servertest] threw exception
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at test1.Server.doGet(Server.java:38)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
问题,但我没有帮助我。我用的是tomcat 7。
I'm tring to upload from my Java local application an object that will include a file to a server. My plan is that a servlet running on tomcat will get the object using the ObjectInputStream
in the doGet
method. But I get an EOFE
xception`.
Here is the client code
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws IOException {
FileInputStream inputStream = new FileInputStream("c:\\rafi.txt");
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int n = 0;
while (-1 != (n = inputStream.read(buffer))) {
output.write(buffer, 0, n);
}
inputStream.close();
File2 c2 = new File2(buffer);
URL url = new URL("http://localhost:8080/servertest/Server");
URLConnection cnx = url.openConnection();
cnx.setDoInput(true);
cnx.setDoOutput(true);
cnx.setRequestProperty("Content-Type", "application/octet-stream");
InputStream in = cnx.getInputStream();
OutputStream out = cnx.getOutputStream();
cnx.connect();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(c2);
oos.flush();
oos.close();
ObjectInputStream ois = new ObjectInputStream(in);
boolean readBoolean = ois.readBoolean();
System.out.println(readBoolean);
ois.close();
in.close();
out.close();
}
}
here is the server's servlet
import java.io.*;
import javax.servlet.*;
@WebServlet("/Server")
public class Server extends HttpServlet {
private static final long serialVersionUID = 1L;
public Server() {
super();
}
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
InputStream in = req.getInputStream();
OutputStream out = res.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
ObjectInputStream ois = new ObjectInputStream(in);
File2 data_in;
try {
data_in = (File2) ois.readObject();
byte[] a = new byte[data_in.mybytearray.length];
System.arraycopy(data_in.mybytearray, 0, a, 0,data_in.mybytearray.length);
System.out.println(a.toString());
oos.writeBoolean(true);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
oos.writeBoolean(false);
}
finally{
oos.close();
}
res.setContentType("java-internal/" + File2.class.getName());
in.close();
}
}
When I debug the server side and run the client I get the exception in this row
ObjectOutputStream oos = new ObjectOutputStream(out);
This is the error I get
SEVERE: Servlet.service() for servlet [test1.Server] in context with path [/servertest] threw exception
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at test1.Server.doGet(Server.java:38)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I saw this question, but i't didn't help me. I'm using tomcat 7.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
URLConnection#getInputStream()
将立即将 HTTP 请求发送到服务器以检索响应正文。按照您编写代码的方式,这会在您向 HTTP 请求主体写入任何位之前发生。因此,服务器端会出现EOFException
。在将必要的数据写入 HTTP 请求正文之后,您需要通过
URLConnection#getInputStream()
请求 HTTP 响应正文。这里是一个重写:此外,由于您基本上是在发送 HTTP POST 请求,因此您需要在 servlet 的
doPost()
方法而不是doGet()
方法中处理此请求。与具体问题无关:这实际上并不是通过 HTTP 发送文件的最佳方式。虽然它可能有效,但它与 Java 序列化机制紧密耦合。我建议改为发送 HTTP
multipart/form-data
请求。这可以通过客户端的 Apache HttpComponents Client 和 Apache Commons FileUpload 在服务器端。这样,servlet 可重用于其他目的,例如前面带有的 HTML 表单。客户端也可以通过这种方式重用将文件上传到其他 HTTP 网站。
The
URLConnection#getInputStream()
will immediately send the HTTP request to the server in order to retrieve the response body. The way as you've written the code, this thus takes place before you've written any bit to the HTTP request body. Hence theEOFException
on the server side.You need to ask for the HTTP response body by
URLConnection#getInputStream()
after you've written the necessary data to the HTTP request body. Here's a rewrite:Also, since you're basically sending a HTTP POST request, you need to handle this in the servlet's
doPost()
method rather than thedoGet()
method.Unrelated to the concrete problem: this isn't really the best way of sending files over HTTP. While it might work, this is very tight coupled to Java serialization mechanism. I'd suggest to send HTTP
multipart/form-data
requests instead. This can be achieved by Apache HttpComponents Client on the client side and Apache Commons FileUpload on the server side. This way the servlet is reuseable for other purposes, such as a HTML form with<input type="file">
in the front. Also the client can this way be reused to upload files to other HTTP websites.我在客户端解决了这个 pbm :
I solved this pbm with on client side :