Question

New to Java. I am building a Java HTTP server (no special libraries allowed). There are certain files I need to serve (templates is what I call them) and I was serving them up using this piece of code:

this.getClass().getResourceAsStream("/http/templates/404.html")

And including them in my .jar. This was working. (I realize I was reading them as an input stream.)

Now I want to store all of my files (as File type) for templates, regular files, redirects in a hashmap that looks like this: url -> file. The I have a Response class that serves up the files.

This works for everything except my templates. If I try to insert the getResource code in the hashmap, I get an error in my Response class.

This is my code that I am using to build my hashmap:

new File(this.getClass().getResource("/http/templates/404.html").getFile())

This is the error I'm getting:

Exception in thread "main" java.io.FileNotFoundException: file:/Users/Kelly/Desktop/Java_HTTP_Server/build/jar/server.jar!/http/templates/404.html (No such file or directory)

I ran this command and can see the templates in my jar:

jar tf server.jar

Where is my thinking going wrong? I think I'm missing a piece to the puzzle.

UPDATE: Here's a slice of what I get when I run the last command above...so I think I have the path to the file correctly?

http/server/serverSocket/SystemServerSocket.class
http/server/serverSocket/WebServerSocket.class
http/server/ServerTest.class
http/templates/
http/templates/404.html
http/templates/file_directory.html
http/templates/form.html
Était-ce utile?

La solution

The FileNotFoundException error you are getting is not from this line:

new File(this.getClass().getResource("/http/templates/404.html").getFile())

It appears that after you are storing these File objects in hash map, you are trying to read the file (or serve the file by reading using FileInputStream or related APIs). It would have been more useful if you had given the stack trace and the code which is actually throwing this exception.

But the point is that files present within the JAR files are not the same as files on disk. In particular, a File object represents an abstract path name on disk and all standard libraries using File object assume that it is accessible. So /a/path/like/this is a valid abstract path name, but file:/Users/Kelly/Desktop/Java_HTTP_Server/build/jar/server.jar!/http/templates/404.html is not. This is exactly what you get when you call getResource("/http/templates/404.html").getFile(). It just returns a string representing something that doesn't exist as a file on disk.

There are two ways you can serve resources from class path directly:

  • Directly return the stream as a response to the request. this.getClass().getResourceAsStream() will return you the InputStream object which you can then return to the caller. This will require you to store an InputStream object in your hash map instead of a file. You can have two hash maps one for files from class path and one for files on disk.
  • Extract all the templates (possibly on first access) to a temporary location say /tmp and then store the File object representing the newly extracted file.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top