java.io.EOFException when sending serialized data to a servlet

11,693

Solution 1

InputStream in = cnx.getInputStream();
OutputStream out = cnx.getOutputStream();

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 the EOFException 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:

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);

Also, since you're basically sending a HTTP POST request, you need to handle this in the servlet's doPost() method rather than the doGet() 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.

Solution 2

I solved this pbm with on client side :

HttpURLConnection cnx = (HttpURLConnection) new URL("http://localhost:8080/web").openConnection();
cnx.setRequestMethod("PUT");
Share:
11,693
rafi wiener
Author by

rafi wiener

Updated on June 14, 2022

Comments

  • rafi wiener
    rafi wiener almost 2 years

    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 EOFException`.

    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.

  • rafi wiener
    rafi wiener almost 13 years
    ok i'l check those apache packs. btw where did the connect command disappeared? i tried adding it in a few places and i got at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
  • BalusC
    BalusC almost 13 years
    You do not need it. You were also firing it too early. The getInputStream() will already implicitly run the connect() at the right moment. Just use the code exactly as in my answer. In your original client code, you need to replace URL url all the way up to out.close() with this piece. It's all exactly what you need and already in the right order.
  • BalusC
    BalusC almost 13 years
    To learn more about using URLConnection, check this post stackoverflow.com/questions/2793150/…