在JavaScript和Java Servlet之间缓存HTTP数据的“正确”方法是什么?

时间:2016-05-11 16:32:09

标签: javascript tomcat servlets http-caching

我正在开发一个客户端 - 服务器应用程序,其中包含一个JavaScript客户端和一个在Apache Tomcat中运行的Java Servlet。我正在发展两端,所以我希望以“正确”的方式做事。

我的JavaScript使用XMLHttpRequest。似乎XMLHttpRequest不为我做缓存,所以我使用IndexedDB来缓存响应。在我需要支持的所有浏览器(iOS,Android,PC,Mac)中,IndexDB正在为我工​​作。

我真的想用ETag值来管理缓存有效性,所以我尝试了这个......

public class MyServlet_Etag extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String etag = myEtag(request);

        String inm = request.getHeader("If-None-Match");
        if (inm != null && inm.equals(etag))
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        else {
            byte[] data = myData(request);
            response.setHeader("ETag", etag);
            response.getOutputStream().write(data);
            response.setContentLength(data.length);
            response.setContentType("application/octet-stream");
            response.setStatus(HttpServletResponse.SC_OK);
        }
    }
}

...但是Tomcat删除了我的“ETag”标题。所以我尝试了这个......

public class MyServlet_LastModified extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        byte[] data = myData(request);
        response.getOutputStream().write(data);
        response.setContentLength(data.length);
        response.setContentType("application/octet-stream");
        response.setStatus(HttpServletResponse.SC_OK);
    }

    @Override
    protected long getLastModified(HttpServletRequest request) {
        return myLastModified(request);
    }
}

上面的Servlet代码很简单,在JavaScript中我可以使用以下代码管理我的IndexedDB缓存:

refreshURI = function(uri,lastModified,onRead) {
    var req = new XMLHttpRequest();
    req.open("GET", uri, true);
    req.responseType = "arraybuffer";
    req.setRequestHeader("If-Modified-Since", lastModified);
    var _this = this;
    req.onreadystatechange = function () {
        if (req.readyState == 4) {
            var hundred = Math.floor(req.status / 100);
            if (hundred == 2) {
                var response = req.response;
                var lastModified = req.getResponseHeader("Last-Modified");
                myIndexedDB.write(uri, req.response, lastModified);// Update our cache
                onRead(response, lastModified);
            } else if (hundred == 3) {
                // No recent change, so skip further processing 
            }
        }
    };

};

所以我的应用程序正在运行。但它每秒只能处理1次更新,因为在HTTP的日期格式中,Last-Modified分辨率为1秒。我希望每秒支持许多更新。我可以使用假的Last-Modified值,每次更新时更新1秒。但这不是“正确的”方式!

Q1。有没有办法阻止Tomcat剥离我的ETag值?

Q2。在我的JavaScript和我的Servlet之间使用伪造的Last-Modified HTTP标头值是否可以接受?

Q3。在JavaScipt客户端和Java Servlet之间缓存HTTP响应的正确方法是什么?

0 个答案:

没有答案