java.io.EOFException when sending serialized data to a servlet
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");
rafi wiener
Updated on June 14, 2022Comments
-
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 thedoGet
method. But I get anEOFE
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.
-
rafi wiener almost 13 yearsok 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 almost 13 yearsYou do not need it. You were also firing it too early. The
getInputStream()
will already implicitly run theconnect()
at the right moment. Just use the code exactly as in my answer. In your original client code, you need to replaceURL url
all the way up toout.close()
with this piece. It's all exactly what you need and already in the right order. -
BalusC almost 13 yearsTo learn more about using
URLConnection
, check this post stackoverflow.com/questions/2793150/…