I've read a request for an HTML document from my browser, parsed the file from the request, found the specified file, and now all that's left is to send back the contents of the HTML file to the browser. What I'm currently doing seems like it should work just fine, however, the contents of the HTML file are not received by the browser.
public void sendResponse(File resource){
System.out.println(resource.getAbsolutePath());
Scanner fileReader;
try {
fileReader = new Scanner(resource);
while(fileReader.hasNext()){
socketWriter.println(fileReader.nextLine());
}
} catch (FileNotFoundException e) {
System.out.println("File not found!");
e.printStackTrace();
}
}
What am I doing incorrectly? There is no exception thrown, but the browser just keeps loading and loading.
that suggests your code is stuck in an infinite loop. Check your while loop. nextLine() is not moving the file pointer ahead?
It's hard to tell without knowing what type socketWriter is, but I imagine you'll need to close the connection. Look for a close() method or something similar on socketWriter and call it when you're done.
It is not evident from your code, where socketWriter is going. Low level operations such as socket are best handled by the web server itself. Normally when we have to write a response back to the browser, we make use of HttpServletResponse object which is available in the goGet / doPost method of your servlet. Refer to the javadocs for more details.
Related
Im trying to wrap my head around Java Out/Inputstreams, closing and flushing. I have a situation where I want to create a file using Apache POI with data from a server. I would like the file to start downloading as soon as I retrieve the first record from the DB(Show the file at the bottom of the browser has started to download).
public void createExcelFile(final HttpServletResponse response,
final Long vendorId) {
try {
// setup responses types...
final XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
final XSSFSheet sheet = xssfWorkbook.createSheet("sheets1");
// create file with data
writeExcelOutputData(sheet, xssfWorkbook);
xssfWorkbook.write(response.getOutputStream());
xssfWorkbook.close();
}
catch (final Exception e) {
LOGGER.error("Boom");
}
The above code will perform a file download no problem, but this could be a big file. I go off getting the data(around 20/30s) and then after that the download begins < no good...
Can I achive what I need or whats the best approach, thanks in advance
Cheers :)
Reasons could be as following:
maybe there is a read/write timeout with your http server, then if the process gets lengthy or becasue of low-bandwidth, so the connection will be closed by the server.
make sure the process(the excel work) gets completely done, maybe there would be an error/exception during work.
The solution of Jorge looks very promising. User need once request for a file, then server would do the work in background and then either user check the work process and download the file if ready, or server informs the user by email, web notification, etc...
Also you would keep the file in the server in a temp file for a while, and if the connection gets interrupted, server would respond the generated file partial(omit the bytes sent, like normal file download)
Keeping a connection alive to do a lengthy work is not very logical.
Again, if the file gets ready fast(really fast) for download/stream, and the download interrupts, if could be becasue of read/write timeout by server, or a very bad network.
my project consists of 2 parts: server side and client side. When I start server side everything is OK, but when I start client side from time to time I get this error:
java.io.IOException: stream active
at java.io.ObjectOutputStream.reset(Unknown Source)
at client.side.TcpConnection.sendUpdatedVersion(TcpConnection.java:77)
at client.side.Main.sendCharacter(Main.java:167)
at client.side.Main.start(Main.java:121)
at client.side.Main.main(Main.java:60)
When I tried to run this project on the other pc this error occurred even more frequently. In Java docs I found this bit.
Reset may not be called while objects are being serialized. If called
inappropriately, an IOException is thrown.
And this is the function where error is thrown
void sendUpdatedVersion(CharacterControlData data) {
try {
ServerMessage msg = new ServerMessage(SEND_MAIN_CHARACTER);
msg.setCharacterData(data);
oos.writeObject(msg);
oos.reset();
} catch (IOException e) {
e.printStackTrace();
}
}
I tried to put flush() but that didn't help. Any ideas? Besides, no errors on server side.
I think you're misunderstanding what reset() does. It resets the stream to disregard any object instances previously written to it. This is pretty clearly not what you want in your case, since you're sending an object to the stream and then resetting straight away, which is pointless.
It looks like all you need is a flush(); if that's insufficient then the problem is on the receiving side.
I think you are confusing close() with reset().
use
oos.close();
instead of oos.reset();
calling reset() is a perfectly valid thing to want to do. It is possible that 'data' is reused, or some field in data is reused, and the second time he calls sendUpdatedVersion, that part is not sent. So those who complain that the use is invalid are not accurate. Now as to why you are getting this error message
What the error message is saying is that you are not at the top level of your writeObject call chain. sendUpdatedVersion must be being called from an method that was called from another writeObject.
I'm assuming that some object is implementing a custom writeObject() and that method, is calling this method.
So you have to differentiate when sendUpdatedVersion is being called at the top level of the call chain and only use reset() in those cases.
I have an application that creates a html page from app (I use freemarker). After that, I open the generated webpage from application using Desktop like this:
public void openPage() {
if (Desktop.isDesktopSupported()) {
try {
File file = new File("index.html");
Desktop.getDesktop().open(file);
} catch (IOException ex) {
System.out.println("Error opening a html page.");
ex.printStackTrace();
}
}
}
Now, my question is: Is there a way to refresh the page from my application? I am changing the concent dynamically and I would like to refresh the page in the browser every few seconds.
Or would it be better to just update the page on background and refresh it directly in the html code using javascript?
Thanks for any tips!
EDIT: Note, that I would like to communicate back to my java application from some form on that webpage (for example sending parametres to specify the way my page is updated)
Use AJAX technology (jQuery pretty much fits your needs) to invoke a server side controller in your application. You can then negotiate the need for a data update. A JSON API is recommended for this. You can use Jackson for JSON-related operations in your Java code.
To save bandwidth, you could poll for only a boolean value to determine whether the server has new data since your last update (e.g. provide since=[some_timestamp] as request param) and query for the actual data only if it makes sense (that is, the server returned true).
I am working on a relatively simple packet capture application, and I am using the Jpcap library. Everything has been working until I added in the save feature to my program.
My write function
public void write() {
try {
writer = JpcapWriter.openDumpFile(captor, fileName);
} catch (IOException e) {e.printStackTrace();}
for (Packet packet : this.packets) {
writer.writePacket(packet);
}
writer.close();
}
It correctly gets the captor and filepath, loops through all the packets successfully, but when it tries to write at the end of the code block, the JVM crashes.
My question is, why does my application crash when trying to close the JpcapWriter?
UPDATE: The weird thing I just discovered, is it IS actually writing to the file. It just crashes after the write. I added a print statement after the close, and it never reaches it.
I found several other people with the same issue as me. I'm not sure why but removing the call to close the writer fixed my problem. The file now writes correctly, and has no issues. For now, I am content with it working, but I may come back to this issue at a later date.
UPDATE: It turns out the the file closes when a call is made to stop the capture. When the capture thread is closed it closes the captor, which in turn closes the writer for me. It essence, I was trying to tell it to close the writer, as the writer was already closing, which caused the JVM to crash.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Should one call .close() on HttpServletResponse.getOutputStream()/.getWriter()?
Am I responsible for closing the HttpServletResponse.getOutputStream() (or the getWriter() or even the inputstream)
or should I leave it to the container ?
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
OutputStream o = response.getOutputStream();
...
o.close(); //yes/no ?
}
You indeed don't need to do so.
Thumb rule: if you didn't create/open it yourself using new SomeOutputStream(), then you don't need to close it yourself. If it was for example a new FileOutputStream("c:/foo.txt"), then you obviously need to close it yourself.
Reasons that some people still do it are just to ensure that nothing more will be written to the response body. If it would ever happen, then this will cause an IllegalStateException in the appserver logs, but this wouldn't affect the client, so the client still gets the proper response. This is also an easier debug to spot the potential problems in the request-response chain which you wouldn't see at first glance. For example, something else is appending more data to the response body somewhere further down in the chain.
Another reason which you see among starters is that they just wanted to prevent that more data is written to the response body. You see this often when JSP incorrectly plays a role in the response. They just ignore the IllegalStateExceptions in the logs. Needless to say that this particular purpose is bad.
No you don't need to close it. If you do you basically end the response to the client. After closing the stream you cannot send anything else to the client until the next request. You didn't open the stream, so you don't have to close it.