向servlet发送序列化数据时的java.io.EOFException

向servlet发送序列化数据时的java.io.EOFException,java,servlets,urlconnection,Java,Servlets,Urlconnection,我试图从Java本地应用程序上传一个对象,该对象将包含一个文件到服务器。我的计划是,在tomcat上运行的servlet将使用doGet方法中的ObjectInputStream获取对象。但是我得到了一个EOFEexception` 这是客户端代码 import java.io.*; import java.net.*; public class Client { public static void main(String[] args) throws IOException {

我试图从Java本地应用程序上传一个对象,该对象将包含一个文件到服务器。我的计划是,在tomcat上运行的servlet将使用
doGet
方法中的
ObjectInputStream
获取对象。但是我得到了一个
EOFE
exception`

这是客户端代码

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)
SEVERE:Servlet[test1.Server]在路径为[/servertest]的上下文中的Servlet.service()引发异常
java.io.EOFException
在java.io.ObjectInputStream$PeekInputStream.readFully处(未知源)
位于java.io.ObjectInputStream$BlockDataInputStream.readShort(未知源)
位于java.io.ObjectInputStream.readStreamHeader(未知源)
位于java.io.ObjectInputStream。(未知源)
位于test1.Server.doGet(Server.java:38)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
位于org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
位于org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
位于org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
位于org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
位于org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
位于org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
位于org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
位于org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
位于org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
位于org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
位于org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
位于org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
位于org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
位于org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(未知源)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(未知源)
位于java.lang.Thread.run(未知源)
我看到了,但我没有帮我。我正在使用Tomcat7

InputStream in = cnx.getInputStream();
OutputStream out = cnx.getOutputStream();
URLConnection#getInputStream()
将立即向服务器发送HTTP请求以检索响应正文。按照您编写代码的方式,这将在您将任何位写入HTTP请求体之前发生。因此,服务器端出现了
EOFException

将必要的数据写入HTTP请求正文后,需要通过
URLConnection#getInputStream()
请求HTTP响应正文。这里有一个重写:

URLConnection connection = new URL("http://localhost:8080/servertest/Server").openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/octet-stream");

ObjectOutputStream oos = new ObjectOutputStream(connection.getOutputStream());
oos.writeObject(c2);
oos.close();

ObjectInputStream ois = new ObjectInputStream(connection.getInputStream());
boolean readBoolean = ois.readBoolean();
ois.close();

System.out.println(readBoolean);
另外,由于基本上是发送HTTP POST请求,因此需要在servlet的
doPost()
方法中处理此问题,而不是
doGet()
方法



与具体问题无关:这并不是通过HTTP发送文件的最佳方式。虽然它可能会工作,但它与Java序列化机制紧密耦合。我建议改为发送HTTP
multipart/formdata
请求。这可以通过在客户机端和服务器端实现。这样,servlet就可以用于其他用途,例如前面有
的HTML表单。此外,客户端可以通过这种方式重新使用,以将文件上载到其他HTTP网站。

我在客户端使用以下方法解决了此pbm:

HttpURLConnection cnx = (HttpURLConnection) new URL("http://localhost:8080/web").openConnection();
cnx.setRequestMethod("PUT");

好的,我去看看那些apache软件包。顺便问一下,connect命令在哪里消失了?我试着在几个地方添加它,我得到了java.io.ObjectInputStream$PeekInputStream.readFully(未知源代码),您不需要它。你发射的时间也太早了。
getInputStream()
将在适当的时候隐式运行
connect()
。只需按照我的答案使用代码。在原始客户端代码中,您需要将
URL
一直替换到
out.close()
。这正是您所需要的,并且已经按正确的顺序排列。要了解有关使用
URLConnection
的更多信息,请查看此帖子