What I am trying to do seems to be a quite simple thing, get an InputStream from a Jersey webservice which is returned from a class RestResponse. But I don't get the stream to my client:
public class RestResponse {
private InputStream responseStream;
public RestResponse(InputStream responseBodyStream) throws IOException{
this.responseStream = responseBodyStream;
//here I can get the stream contents from this.responseStream
}
public InputStream getResponseStream() throws IOException {
//here stream content is empty, if called from outside
//only contains content, if called from constructor
return this.responseStream;
}
}
public class HttpURLConnectionClient{
public RestResponse call(){
try{
....
InputStream in = httpURLConnection.getInputStream();
RestResponse rr = new RestResponse(in);
}finally{
in.close(); <- this should be the suspect
}
}
}
RestResponse rr = httpURLConnectionClient.call()//call to some url
rr.getResponseStream(); //-> stream content is empty
Any ideas, what I am missing? Is is not possible to just pipe the stream through?
Certain types of InputStream can only be read once in Java. Based on your comment above, it appears that you are using the InputStream when you pipe it to System.out. Try commenting out the call to System.out and see if you can access your InputStream. Also make sure that the stream is not being consumed anywhere else in the code before the point where you need it.
Update:
It appears that your actual problem was being caused by closing the InputStream before you got a chance to use it. So the solution is to keep the stream open until you need it, and close it afterwards.
Typically, it is not a good design practice to open a stream and keep it open for a long time, because then the underlying resource won't be available to anyone else who needs it. So you should open the stream, and consume it only when you actually need it.
Related
I am trying to read a fileinputstream that then gets passed to a calling function which is then played back in a webserver application viewer. The download works fine but the problem is that if I close the stream (which is recommended) within the same function the calling function receives a null stream for some reason. Someone suggested creating an inputstream wrapper and this will allow me to close the stream, delete the file and still pass the stream to the calling function.
public InputStream exportVideo(Youtube connection, String videoID) {
InputStream is = null;
....//file retrieval code above
is = new FileInputStream(ndirectory + "\\" + this.videoID.toString()
+ ".avi");
return is;
....//trace handling code below
finally{
is.close();
}
}
the calling function:
stream = FetchVideo.exportVideo(econnection, videoID);
what I am thinking the suggestion meant was have some class:
public class StreamConverter extends InputStream {
be the wrapper, but I have no idea how to do this.
Any advice or ideas / links on how to do this effectively. Again the problem is closing the stream but being able to pass it on to the calling function.
You should move the is.close() call out of the method and close it where you get it e.g
try {
stream = FetchVideo.exportVideo(econnection, videoID);
//do something with the stream
}
finally {
if (stream != null) {
stream .close();
}
}
or it's better to use try with resource
try (InputStream stream = FetchVideo.exportVideo(econnection, videoID)) {
//do something with the stream
}
You could use composition to implement this InputStream.
Just override all methods so they call your delegate object.
But I am not sure this is the right way to do what you want. I think the best option here is to add an output stream to the function. The function will then write the content it reads to the output stream and the caller is now in charge of closing the stream. (Easy way to write contents of a Java InputStream to an OutputStream)
This is my client right now:
#Override
public void run()
{
try
{
#SuppressWarnings("resource")
InputStream socketIn = socket.getInputStream();
Scanner in = new Scanner(socketIn);
PrintWriter out = new PrintWriter(socket.getOutputStream());
ObjectInputStream oin = new ObjectInputStream(socketIn);
gui = new GuiController(out);
while (true)
{
System.out.println(socketIn);
if(in.hasNext()){
gui.updateResponse(in.nextLine());
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
As you can see, I have both an ObjectInputStream as well as a Scanner. This is because I am both sending simple Strings from my Server, which should be caught by the string, as well as Hashtable-Objects, which are dealt by the ObjectInputStream.
However, now I need to determine whether my Servers PrintWriter or ObjectOutputStream sent the data, so I can react to it. If I don't make any check, my Scanner will just grab the object and print it as a string, which is obviously very wrong.
I need something like this:
if(socketIn.origin == ObjectOutputStream){
}
else{
}
Note that this is just some pseudo code, but I think you get the idea.
Disclaimer: This is certainly not the recommended way of doing this for that look at EJP's answer.
But what you could do:
Before you send anything through your object stream or string stream, send a string through the string stream telling the client what to expect. After that you send the actual data via either the string stream or the object stream. So in pseudocode this would be:
read string with string input stream
if string==object then
read data with object input stream
handle object
else if string==string
read data with string input stream
handle string
This would work as you first receive what is coming, and then you read the actual data.
For the sake of completeness here's the pseudo code for the sender:
if the data to send==object
print 'object' to the string output stream
print object to the object ouput stream
else if data to send==string
print 'string' to the string output stream
print data string to the string ouput stream
I hope this helps you :)
NOTE: Be very carefull doing this when your socket is used by multiple threads.
NOTE: You could also wrap your string in an object and just send it through the object stream.
No. There is only one data stream. This will never work, for a number of reasons. Use a single stream, or reader/writer pair, or DataInput/OutputStream pair, or ObjectInput/OutputStream pair.
Basically attempting to send video data and trying to understand how this whole process works, not sure whether I've put this together properly. Any help would be greatly appreciated.
public void OutputStream(BufferedOutputStream out) throws MalformedURLException {
URL url = new URL("http://www.android.com//");
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
out = new BufferedOutputStream(urlConnection.getOutputStream());
out = new BufferedOutputStream(new FileOutputStream(String.valueOf(mVideoUri)), 8 * 1024);
} catch (IOException e) {
e.printStackTrace();
} finally {
assert urlConnection != null;
urlConnection.disconnect();
}
}
You aren't technically using the output stream at all in this case, merely reassigning it several times. The input parameter out is being reassigned within the method but never used prior which doesn't seem like what you want to do at all since whatever existing output stream instance reference passed to this method is simply discarded.
You reassign out once more and discard the buffered of the socket connection on this line:
new BufferedOutputStream(urlConnection.getOutputStream());
which is mostly harmless in that there isn't any resource leakage (given that disconnect() is called) but once again doesn't seem like what you want to do.
Your code also has resource leakage on the last out given that it is not closed anywhere within the try-catch-finally block which is a serious flaw. Additionally, the usage of assertions to check for nulls on out needs to be promoted to a if-statement to handle the very real possibility that out is null in case of a failed URL resolution/open. Assertion tests can be turned off, in which you'd get a NPE (and when turned on, you'll get an AssertionError, nether of which is better).
Whilst it's hard to anticipate exactly what your project structure is, the general contract of output stream usage can be seen as follows:
public void foo(){
OutputStream out = null;
byte[] data = ... // Populated from some data source
try{
out = ... // Populated from some source
out.write(data); // Writes the data to the output destination
}catch(IOException ex){
// Handle exception here
}finally{
// Only attempt to close the output stream if it was actually opened successfully
if(out != null){
try{
out.close();
}catch(IOException closeEx){
// Handle, propogate upwards or log it
}
}
}
}
The output stream is used within the try block such that any exceptions will result in the finally block closing the stream as appropriate, removing the resource leakage. Note the sample write() method in the try block, illustrating in the most basic form how OutputStreams can be used to put data into some destination.
Under java 7 (and above), the above example is more compact:
public void foo(){
byte[] data = ... // Populated from some data source
try(OutputStream out = ...){
out.write(data); // Writes the data to the output destination
}catch(IOException ex){
// Handle exception here
}
}
Utilizing try-with-resources, resource safety can be assured thanks to the AutoClosable interface and java 7 (and above's) new syntax. There is one small difference in that exceptions from closing the stream are also bunched into the same catch block instead of being separate as in the first example.
When I use the object OutputSupplier, adding the first line (CharStreams.write) is executed correctly. But then calling CharStreams.write again throws an IOException.
Is this the correct behavior of the object? If so, how can you append a String to the supplier object without closing the inline stream?
...
final Process process = Runtime.getRuntime().exec("su");
OutputSupplier<OutputStreamWriter> writerSupplier = CharStreams.newWriterSupplier(new OutputSupplier<OutputStream>() {
#Override
public OutputStream getOutput() throws IOException {
return process.getOutputStream();
}
}, Charsets.UTF_8);
// ok
CharStreams.write(someCommand, writerSupplier);
...
// IOException
CharStreams.write(otherCommand, writerSupplier);
This is definitely expected behavior.
CharStreams.write with an OutputSupplier opens the output stream, writes, and closes it. That's part of the point. Presumably, Process.getOutputStream() doesn't let you open and close more than once.
Either do all the writes at once, or more likely, don't use CharStreams.write and deal with closing the stream yourself.
I'm pretty new to Java. I'm passing in a file from a Web page form to Java via JaxRS. I then read the file with a FileInputStream (I've also tried a FileReader, I'm not sure which I ought to use) and then shuttle that data in to a StringBuffer to be converted in to a string with StringBuffer.toString().
What I've noticed is that I'm getting the HTTP header information in my String. Stuff like Content-Disposition, filename, and Content-Type. Is there a convenient way to strip out that information prior to calling StringBuffer.toString()?
Here's a sample of my code with the irrelevant bits stripped out:
public Response method(#FormDataParam("fileToUpload") File file)
{
StringBuffer strBuffer=new StringBuffer("");
String fileAsString;
try
{
FileInputStream fileInputStream=new FileInputStream(file);
int characterIndex;
while ((characterIndex = fileInputStream.read()) != -1)
{
strBuffer.append((char)characterIndex);
}
fileInputStream.close();
fileAsString=strBuffer.toString(); //I'd like to have the HTTP header info stripped before getting to this point without having to do some sort of manual string manipulation.
}
catch (FileNotFoundException e){}
catch (IOException e){}
}
Thanks so much for your help!
I solved it. Apparently Jersey wants you to pass in a FormDataContentDisposition as well. You don't need to do anything with the argument. Simply passing it in will separate the header from the message content.