views:

185

answers:

5

I have Java webserver (no standard software ... self written). Everything seems to work fine, but when I try to call a page that contains pictures, those pictures are not displayed. Do I have to send images with the output stream to the client? Am I missing an extra step?

As there is too much code to post it here, here is a little outline what happens or is supposed to happen:

1. client logs in
2. client gets a session id and so on
3. the client is connected with an output stream
4. we built the response with the HTML-Code for a certain 'GET'-request 
5. look what the GET-request is all about
6. send html response || file || image (not working yet)

So much for the basic outline ...

It sends css-files and stuff, but I still have a problem with images! Does anybody have an idea? How can I send images from a server to a browser? Thanks.

I check requests from the client and responses from the server with charles. It sends the files (like css or js) fine, but doesn't with images: though the status is "200 OK" the transfer-encoding is chunked ... I have no idea what that means!? Does anybody know?

EDIT: Here is the file-reading code:

 try{
      File requestedFile = new File( file );
      PrintStream out = new PrintStream( this.getHttpExchange().getResponseBody() );
      // File wird geschickt:
      InputStream in = new FileInputStream( requestedFile );
      byte content[] = new byte[(int)requestedFile.length()];
      in.read( content );

      try{
           // some header stuff
           out.write( content );
      }
      catch( Exception e ){
           e.printStackTrace();
      }

      in.close();

      if(out!=null){
           out.close();
           System.out.println( "FILE " + uri + " SEND!" );
      }
 }
 catch ( /*all exceptions*/ ) {  
      // catch it ...
 }
+3  A: 

Your browser will send separate GET image.png HTTP 1.1 requests to your server, you should handle these file-gets too. There is no good way to embed and image browser-independent in HTML, only the <img src="data:base64codedimage"> protocol handler is available in some browsers.

As you create your HTML response, you can include the contents of the external js/css files directly between <script></script> and <style></style> tags.

Edit: I advise to use Firebug for further diagnostics.

kd304
Thnx, someone mentioned the base64-coding to me before (I will look into that), but will that help me with external files, like a style-sheet (that maybe contains images as well)? Thnx
doro
Hey again, I know about that, but I personally believe external files are so much more elegant *g* ... Javascripts and stylesheets work when I put it into the file directly, but images don't.
doro
My suggestion uses external js/css files and streamlines them into one response. The latest FF3 and IE8 should be able to handle it: have a look at the rfc http://www.ietf.org/rfc/rfc2397.txt
kd304
+1  A: 

Proabably step #4 is where you are going wrong:

// 4. we built the response with the HTML-Code for a certain 'GET'-request

Some of the requests will be a 'GET /css/styles.css' or 'GET /js/main.js' or 'GET /images/header.jpg'. Make sure you stream those files in those circumstances - try loading those URLs directly.

too much php
Thank you, I will try that :)
doro
+1  A: 

Images (and css/js files) are requested by the browser as completely separate GET requests to the page, so there's definitely no need to "send those ... with the output stream". So if you're getting pages served up ok, but images aren't being loaded, my first guess would be that you're not setting your response headers appropriately (for example, setting the Content-Type of the response to text/html), so the browser isn't interpreting it as a proper page & therefore not loading the images.

Some other things to try if that doesn't work:

  • Check if you can access an image directly
  • Use something like firebug or fiddler to check whether the browser is actually requesting the image/css/js files & that all your request/response headers look ok
  • Use an existing web server!
Alconja
"Use an existing web server!" --> yeah, I know Apache/Tomcat or Jetty or or or ... I would love to, though I do think it is interesting to see how it works from the scratch, makes some things a lot clearer!Thnx for your input, makes sense! I will definately check that out. (Also never heard of fiddler, thnx for that hint!)
doro
the content-type was one problem. at least now I get the requests ... So now I am sure, I am handling the requests in a wrong manner :)
doro
+1  A: 

Do I have to send those external files or images with the output stream to the client?

The client will make separate requests for those files, which your server will have to serve. However, those requests can arrive over the same persisten connection (a.k.a. keepalive). The two most likely reasons for your problem:

  1. The client tries to send multiple requests over a persistent connection (which is the default with HTTP 1.1) and your server is not handling this correctly. The easiest way to avoid this is to send a Connection: close header with the response.
  2. The client tries to open a separate connection and your server isn't handling it correctly.

Edit:

There's a problem with this line:

in.read( content );

This method is not guaranteed to fill the array; it will read an arbitrary number of bytes and return that number. You have to use it in a loop to make sure everything is read. Since you have to do a loop anyway, it's a good idea to use a smaller array as a buffer to avoid keeping the whole file in memory and running into an OutOfMemoryError with large files.

Michael Borgwardt
I think browsers tend to send the connection: keep-alive header but don't expect the server to respect that. If the server closes the stream, it's just fine.
kd304
Thank you :) I will check that out!
doro
the thing is (now): i can request multiple files, like a css file and a js file. that works fine, but it doesnt with images :(
doro
"doesnt work" is not a useful error description. How exactly does it "not work"? Files are files to a HTTP server, there is no special treatment for images vs. text files. Unless you try to handle all files as text and mess up binary stuff. Make sure you treat files as a sequence of bytes and don't use a Reader or Writer anywhere.
Michael Borgwardt
I used a PrintStream ... but unfortunately I still dun get it to work with images ... If I am trying the same for images as I do for css-files or js-files, it doesn't work ... see code above
doro
You are right, but I wouldn't expect to fail in this case as the file size is constant and the array size is the same. I thought read() will try to fill in as much as possible but can fill in less when it reaches the EOS.
kd304
Incorrect - it will usually read much less than the file's size with larger files. And no, available() is also not useful in this regard. You have to implement a loop.
Michael Borgwardt
thnx for the hint. i will try that out :) *cross your fingers* whohooo ... :)
doro
it works!!!!!!!!!! THNX!
doro
+2  A: 

Are you certain that you send out the correct MIME type for the files?

If you need a tiny OpenSource webserver to be inspired by, then have a look at http://www.acme.com/java/software/Acme.Serve.Serve.html which serves us well for ad-hoc server needs.

Thorbjørn Ravn Andersen
I changed the type and it works with files (see above), but not with pictures. Thnx for the link!
doro