A
file:// URL references files on the
client computer, not on the server. A webserver is NOT a fileserver.
To resolve image and other static resource object requests on the server side, you have to either place them in places where the default servlet can see them or provide a resource resolution mechanism of your own.
The default servlet is an invisible servlet that's part of your webapp server. Any URL request that can't be routed to a JSP or servlet goes to the default servlet, which figures out how to handle that URL. For things like image, script and css resources, the default servlet will dissect the URL to obtain the core resource path, then look inside the WAR for an object located at the target of that path. Meaning that resource "/images/pic123.jpg" will be retrieved (if possible) from the "images" directory under the WAR's root.
If you want to keep your images inside an archive file or in some external location, that's fine, but you'll have to provide a servlet that knows how to interpret requests, pull the data out, and copy the data to the Response stream just like the default servlet does for resources in the WAR.
Caching isn't done by the server. Caching is done by the client. You can modify the client's caching behavior by supplying appropriate cache headers in the Response stream.