Java HTTP-Server implementation can't send images correctly - java

I am implementing my own HTTP server using sockets. In my java project folder I have a folder /root where all the files are saved which can be downloaded (test.html, test.jpg), so when the user browses to let's say localhost:8080/test.html my server takes the file, reads it and sends the bytes to the client's browser ,setting the right headers. Everything works fine with the .html extension but I have a problem with the images...the browser says that the file cannot be shown properly.
Here is the class which I use to read the bytes from the file:
public class FileRequestHandler {
public FileRequestHandler(){
}
/*
* Method which reads a text-file and turns it into a string
*/
public String readFile(String file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader (file));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
try {
while((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
return stringBuilder.toString();
} finally {
reader.close();
}
}
}
after executing readFile() I get a string(I will call it response).
Now I set the headers and send them to the client:
out.println("HTTP/1.1 200 OK");
out.println("Content-Type: image/jpeg");
out.println("Content-Length: " + response.length());
out.println();
out.println(response);
out.flush();
out is a PrintWriter object.
As I already mentioned, this method works with a html-file and everything is shown. What am I doing wrong? Maybe the encoding of the raw-bytes is incorrect or the headers were set incorrectly?
Thank you for the help!

An image is not a text file. Yet you are apparently reading it as text using a BufferedReader. That will mangle it ... and the use of readLine() and the line reassembly mangles it some more.
Either way, the browser will be unable to decode the mangled image that your server is sending.
You should use InputStream / OutputStream subtypes rather than Reader / Writer subtypes, and you should NOT attempt to convert the image into a string at any point.
(It is also a bad idea to attempt to implement an HTTP server using socket-level I/O ... but that's a different issue.)

BufferedReader reader = new BufferedReader(new FileReader (file));
The problem starts here. Readers and Writers are for text. Images are not text. You should be using an input stream, and writing bytes directly to an output stream, not collecting them in a String.

Related

Call and return the output of a jar to another java program

I am calling jar in a java program. the inner jar returns some output. how should i read and display in following program ?
i am able to call the jar successfully but how to display the output ?
import java.io.InputStream;
public class call_xml_jar {
public static void main(String argv[]) {
try{
// Run a java app in a separate system process
Process proc = Runtime.getRuntime().exec("java -jar xml_validator.jar");
// Then retreive the process output
InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();
System.out.println("Completed...");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Output: Completed...
I want to print jar output as well
With the lines
InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();
you are already on the way.
These streams give you access to the other application's standard output and standard error streams (respectively). By the way: You retrieve the other application's standard output stream by calling getInputStream(), as this is the view of your current application; you are inputting the other application's data.
Just to make it clear: The standard output and th standard error stream are accessed in an application by printing calls to System.out and System.err (respectively).
So, if you have - for example - System.out.println("Hello world") in the other application, you will retrieve the corresponding bytes (see below) in the input stream that you reference with the variable in of the above code snippet.
Normally, you are not interested in the bytes but you want to retrieve the String that you have placed into the output. So you must convert the bytes to a String. For this you normally must provide an encoding (the Java class for that is Charset). In fact, the platform's default encoding works in such cases.
The easiest way is to wrap the input stream in a buffered reader:
BufferedReader outReader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
The above mntioned platform's default encoding is used, when not specifying any character set in the InputStreamReader's constructor.
A BufferedReader knows a method readLine(), which you must use to get all the other application's output.
while(outReader.ready())
System.out.println(outReader.readLine())
One word about flushing: If you write data to the standard output stream, this stream is flushed only, when a newline is also written. This is done by calls to System.out.println(...). And this is the reason, why you must read entire lines from the reader.
Are you now able to assemble some code that reads out the other application's output? If not, you maybe should post another question.
I solved it myself.. Here is my solution...
// Then retreive the process output
InputStream in = proc.getInputStream();
InputStream err = proc.getErrorStream();
System.out.println("Completed...");
InputStreamReader is = new InputStreamReader(in);
StringBuilder sb=new StringBuilder();
BufferedReader br = new BufferedReader(is);
String read = br.readLine();
while(read != null) {
//System.out.println(read);
sb.append(read);
sb.append("\n");
read =br.readLine();
}
System.out.println(sb);

Creating a File using PrintWriter in Java, and Writing to that File

I'm trying to write a program that reads a file (which is a Java source file), makes an Arraylist of certain specified values from that file. and outputs that Arraylist into another resulting file.
I'm using PrintWriter to make the new resulting file. This is a summarised version of my program:
ArrayList<String> exampleArrayList = new ArrayList<String>();
File actualInputFile = new File("C:/Desktop/example.java");
PrintWriter resultingSpreadsheet= new PrintWriter("C:/Desktop/SpreadsheetValues.txt", "UTF-8");
FileReader fr = new FileReader(actualInputFile);
BufferedReader br = new BufferedReader(fr);
String line=null;
while ((line = br.readLine()) != null) {
// code that makes ArrayList
}
for (int i = 0; i < exampleArrayList.size(); i++) {
resultingSpreadsheet.println(exampleArrayList.get(i));
}
resultingSpreadsheet.close();
The problem is that when i run this, nothing gets printed to the resultingSpreadsheet. It's completely empty.
BUT, this program works perfectly (meaning that it prints out everything correctly to the resultingSpreadsheet file) when I replace:
File actualInputFile = new File("C:/Desktop/example.java");
which is the file that I want as my input file, and which has a size of 481 KB,
with:
File smallerInputFile = new File("C:/Desktop/smallerExample.txt");
which is really just a smaller .txt example version of the .java source file, and it has a size of 1.08 KB.
I've tried a few things including flushing the PrintWriter, wrapping it around FileWriter, copy-pasting all the code from the .java file into a text file in case it was an extension problem, but these don't seem to work.
I'm starting to think it must be because of the size of the file that the PrintWriter makes, but it's very possible that that's not the problem. Perhaps I need to put everything in a stream (like it says here: http://docs.oracle.com/javase/6/docs/api/java/io/PrintWriter.html)? If so, how would I do that?
Why is reading the bigger actualInputFile and outputting its data correctly such a problem, when everything works fine for the smallerInputFile?
Can anyone help with this?
Check for exceptions while writing to the the excel sheet , because i really don't think its a problem of size. Below is the sample code that is executing successfully and the file size was approx 1 MB.
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
BufferedReader br = null;
try {
String sCurrentLine;
br = new BufferedReader(new FileReader("D:\\AdminController.java"));
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
This should go as a comment, but I do not have the rep. In the documentation it has both write methods and print methods. Have you tried using write() instead?
I doubt it's the size of the file, it may be between the two files you are testing one is .txt, and the other is .java
EDIT: Probably second suggestion of the two. First is just something I noticed with the docs.
The methods of PrintWriter do not throw Exception. Call the checkError() method which would flush the stream as well as return true if an error occurred. It is quite possible that an error occurred processing the larger file, an encoding error for instance.
Check your program. When the file is empty it means that your program doesn't close the PrintWriter before finishing the program.
For example you may have a return in a part of your program which cause that resultingSpreadsheet.close(); have not being run.

Building Java server and I can't get my page to stop loading (using PrintWriter and Buffered Reader)

I'm building a Java server and everything has been working as expected until now. I can serve up a static html page using two methods I wrote: body and header. Now, I am trying to write a new method called "bodywithQueryString".
Problem:
It almost works, but after the page is loaded, the loading won't stop. It just loads and loads. This is not happening with my static pages.
The only difference between the old method and new bodyWithQueryString() method is that in the new method I am using a buffered reader and print writer. These are new-ish functions for me so I'm guessing I'm not doing it right.
Here's how my new method is supposed to function:
I want to pass my route and querystring (queryarray) to bodyWithQueryString method. I want the method to read the file (from the route) to a byte output stream, do a replaceall on the key/value pair of the querystring while reading and, lastly, return the bytes. The getResponse() main method would then send the html to the browser.
Here's my code:
public void getResponse() throws Exception {
String[] routeParts = parseRoute(route); //break apart route and querystring
File theFile = new File(routeParts[0]);
if (theFile.canRead()) {
out.write(header( twoHundredStatusCode, routeParts[0], contentType(routeParts[0]) ) );
if (routeParts.length > 1) { //there must be a querystring
String[] queryStringArray = parseQueryString(routeParts[1]); //break apart querystring
out.write(bodyWithQueryString(routeParts[0], queryStringArray)); //use new body method
}
else out.write(body(routeParts[0])); //use original body method
out.flush();
private byte[] bodyWithQueryString(String route, String[] queryArray)
throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(route));
ByteArrayOutputStream fileOut = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(fileOut);
String line;
while ((line = reader.readLine()) != null) writer.println(line.replaceAll(queryArray[0] ,queryArray[1]));
writer.flush();
writer.close();
reader.close();
return fileOut.toByteArray();
}
It seems to me that you are not returning Content-Length header. This makes it hard for browser know when to stop loading the response.

How to retrieve InputStream from FTPFile using FTPClient?

I'm making application which needs to read strings from file on FTP Server. I use apache.commons.net.FTPClient for it. I have following code:
Log.e("sizzeee", String.valueOf(mClient.listFiles().length));
InputStream stream=mClient.retrieveFileStream(f.getName());
DataInputStream in=new DataInputStream(stream);
BufferedReader buf=new BufferedReader(new InputStreamReader(in));
List<String> tasks=new ArrayList<String>();
String s;
while ((s=buf.readLine())!=null) {
tasks.add(s.trim());
}
stream.close();
in.close();
buf.close();
Log.e("sizzeee", String.valueOf(mClient.listFiles().length));
That works correctly, but I have some problems: last Log instruction shows "0" files in current directory! But first Log instruction shows "6" files. Therefore I think that I don't close file stream or something else. Please, inform me about my mistake. Thank you

Reading XML file from /res/xml using InputStream reader yields invalid characters / encoded data

I'm having trouble reading in XML data from an XML resource located in /res/xml/testxml.xml. For some reason using examples from my book and online, I'm not able to read the data properly. The following method is simple; read the XML resource and print the lines within it.
public InputStream fetchLocalStream(String file){
InputStream in = null;
try {
//in = Global.gContext.openFileInput("testxml.xml");
in = Global.gContext.getResources().openRawResource(R.xml.testxml);
try {
if (in != null) {
// prepare the file for reading
InputStreamReader inputreader = new InputStreamReader(in);
BufferedReader buffreader = new BufferedReader(inputreader);
String line;
// read every line of the file into the line-variable, on line at the time
while (( line = buffreader.readLine()) != null) {
Log.d(Global.TAG,"-->Line:" + line);
// do something with the settings from the file
}
}
} catch (Exception e){}
return in;
}catch (Exception e){ Log.d(Global.TAG,"--> Failed!!!!" + e); }
return in;
}
Any help would be greatly appreciated.
Line:└Ç└Ç└Ç∩┐╜∩┐╜∩┐╜∩┐╜♥└Ç└Ç└Ç#└Ç└Ç└Ƕ└Ƕ└Ç└Ç└Ç└Ç└Ç└Ç└Ç└Ç└Ç♦☺►└Ç∟└Ç└Ç└Ç
Line:└Ç└Ç└Ç∩┐╜∩┐╜∩┐╜∩┐╜$└Ç└Ç└└Ç└Ç└Ç└Ç└Ç└Ç└Ç♥☺►└Ç↑└Ç└Ç└Ç
Line:└Ç└Ç└Ç∩┐╜∩┐╜∩┐╜∩┐╜♥└Ç└Ç└Ç#└Ç└Ç└Ç☻☺►└Ç$└Ç└Ç└Ç
Line:└Ç└Ç└Ç∩┐╜∩┐╜∩┐╜∩┐╜♥└Ç└Ç└Ç%└Ç└Ç└Ƕ└Ƕ└Ç└Ç└Ç└Ç└Ç└Ç└Ç└Ç└Ç♦☺►└Ç∟└Ç└Ç└Ç
Line:└Ç└Ç└Ç∩┐╜∩┐╜∩┐╜∩┐╜&└Ç└Ç└└Ç└Ç└Ç└Ç└Ç└Ç└Ç♥☺►└Ç↑└Ç└Ç└Ç
Line:└Ç└Ç└Ç∩┐╜∩┐╜∩┐╜∩┐╜♥└Ç└Ç└Ç%└Ç└Ç└Ç☻☺►└ÇL└Ç└Ç└Ç
I had the same problem and found the solution in the thread "Android SAX xml not well-formed" over at anddev.org:
Found out an interesting stuff - when moving xml file from xml folder to raw, everything works smoothly. I guess that's why the function is called openRawResource .
Anyways i think that android adds some stuff to the files stored in non raw folder. But this is just a thinking aloud.
Moving from /res/xml to /res/raw solved the problem for me.
The problem is probably a character encoding issue. Try using the XmlResourceParser, which you can obtain via Resources.getXml. (Most XML parsers are adapt at dealing with character encoding.) Here's an example.
http://developer.android.com/reference/android/content/res/Resources.html

Categories

Resources