Memory mapped classpath HttpServlet I have a single page application where the resources sit on the classpath. Any request for a resource that doesn't exist should redirect to the index.html page. Resources should be mapped to memory on first request and then all subsequent requests should load from memory.

Have I made any mistakes with how I should be using direct ByteBuffers, it feels overly laborious, but that could just be the API?

class MemoryMappedClasspathHttpServlet extends HttpServlet {

    private final ConcurrentMap&lt;String, ByteBuffer&gt; mappedResources = new ConcurrentHashMap&lt;&gt;();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String requestPath = req.getPathInfo();

        if (requestPath.equals("/")) {
            requestPath = "/web/index.html";
        } else {
            requestPath = "/web" + requestPath;

            if (MemoryMappedClasspathHttpServlet.class.getResource(requestPath) == null) {
                requestPath = "/web/index.html";
            }
        }

        ByteBuffer buffer = mappedResources.computeIfAbsent(requestPath, MemoryMappedClasspathHttpServlet::loadResourceFromClasspath);

        Channels.newChannel(resp.getOutputStream())
            .write(buffer.duplicate());
    }

    private static ByteBuffer loadResourceFromClasspath(String classpathItem) {
        try (ByteArrayOutputStream os = new ByteArrayOutputStream();
             InputStream is = MemoryMappedClasspathHttpServlet.class.getResourceAsStream(classpathItem)) {

            byte[] buffer = new byte[8092];

            for (int len; (len = is.read(buffer)) != -1; ) {
                os.write(buffer, 0, len);
            }

            os.flush();

            byte[] bytes = os.toByteArray();

            ByteBuffer directBuffer = ByteBuffer.allocateDirect(bytes.length);
            directBuffer.put(bytes);
            directBuffer.flip();

            return directBuffer;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}
Possible improvement:

return directBuffer;


with:

return directBuffer.asReadOnlyBuffer();


Wanted to find a one-liner to help https://code.google.com/p/guava-libraries/wiki/IOExplained but ByteBuffer, streams nontrivial. Notice defining mutable ByteBuffer references in the method, placing each into an instance collection, one never flushed or refreshed...Servlet web container would need a restart in order to reflect changes to the files or other resources.