Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ServletInputStream error when reading more than once

Status
Not open for further replies.

mluken

Programmer
Dec 31, 2003
54
0
0
US
I have an application which needs to look at fields in a multipart request in several different places of the code. The first time I look at the request, it works just fine, but every time after that it doesn't. Here is a simplified example of what is happening:

Code:
private ServletInputStream in;
private HttpServletRequest request;
private byte[] buff = new byte[100*1024];
public Class class1  {
	public class1(HttpServletRequest req) {
		super();
		request = req;
		in = request.getInputStream();
		String line = readLine();
		System.out.println("Testing line1: " + line);
	}
}

private ServletInputStream in2;
private HttpServletRequest request;
private byte[] buff = new byte[100*1024];
public Class class2  {
	public class2(HttpServletRequest req) {
		super();
		request = req;
		in2 = request.getInputStream();
		String line = readLine();
		System.out.println("Testing line2: " + line);
	}
}

Not sure that it is relevant, but in case it is, my readLine() method looks like this:

Code:
private String readLine() throws IOException {
	int len = 0;
	String line = null;
	len = in.readLine(buff,0,buff.length);
	if(len < 0) return null;
	line = new String(buff,0,len,"ISO-8859-1");
	return line;
}

The request is basically passed around so it is the same request object both times. The first one outputs the first line as expected. In the second one however, line is null.

Interestingly enough, I found the following to be true also:

Code:
private ServletInputStream in;
private ServletInputStream in2;
public Class class3 {
	public class3(HttpServletRequest request){
		super();
		in = request.getInputStream();
		if(in != null) {
			in.close();
		}
		in = null;
		
		in2 = request.getInputStream();
		String line = in2.readLine();
		// IOException OCCURS HERE SAYING: Stream closed
	}
}

The stream was closed on the first "in" but not on the second, so why would I be getting this????

Help!!
 
You cannot read a stream twice - an IO network socket contains data that can only be read once - once the server has sent the stream data to the client, then thats it.

I would parse the stream once, extract any data that you may need from it, and save that data in some kind of class variable for use later as needed. In any case, reading a stream twice (even if you could do it) would be very inefficent way of writing code.

--------------------------------------------------
Free Database Connection Pooling Software
 
The problem I am getting into is that to incorporate this into my servlet, I really can't store the data and use it later. The first time I rad it, I need to know the form elements. This happens in the core of my servlet which is used by many other applications, and those values need to be set. Later, I need to actually upload the file from the multipart request. As I said, this happens much later in the code and I can't really see a way to use the results from when reading it the first time.

However, if I could find a way to get the form elements (minus the upload file) from the multipart request WITHOUT opening up that socket, then I would be able to open it later and extract that file. So is there a way to get the form elements without opening a socket?

Thoughts??
 
Not really sure what you mean by "form elements" - do you mean the request parameters accessed by request.getParameter() methods ?

If I were you, I would rewrite your code so that you store all the data that would be needed to service the request in an object that can be accessed by everything you need, such as the session.

Another way of in effect reading the stream "twice" is to read the stream into a byte[] array, and then when you need to read this data, use a ByteArrayInputStream, created from the byte[] array. But as I said before, reading this data twice is bad style programming, and you should really redesign your service methods rather than relying on this inefficient hack.

--------------------------------------------------
Free Database Connection Pooling Software
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top