getLastModified()
method in HttpServlet
class works so i tried playing around with it and this is what i found. These are some of the methods related to getLastModified()
from the default implementation of HttpServlet.java class
protected long getLastModified(HttpServletRequest req) {
return -1;
}
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
private void maybeSetLastModified(HttpServletResponse resp,
long lastModified) {
if (resp.containsHeader(HEADER_LASTMOD))
return;
if (lastModified >= 0)
resp.setDateHeader(HEADER_LASTMOD, lastModified);
}
getLastModified():
The default implementation of this method returns -1 as value, so if you dont override this method then the default implementation wont setLast-Modified
headerservice() :
The default implementation ofservice()
method calls thegetLastModified()
method in two cases one is when it getsGET
request and other is when it getsHEAD
request. In both cases it checks if the value returned is not -1 then it sets theLast-Modified
header with value returned by the method. In case ofGET
method it takes the value returned bygetLastModified()
method and compares it to value of theIf-Modified-Since
, to check if the response is actually changed, if no it wont even call thedoGet()
method of the servlet instead it will returnHTTP 304 Not Modified
response to browsermaybeSetLastModified():
method checks if theLast-Modified
is already set in the response if not it checks if its value is greater than 0 and sets it
Now i changed my
ResourceServingServlet
so that it returns value of getLastModified()
equal to current time - 10 hours like this
package com.webspherenotes.performance;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ResourceServingServlet
*/
public class ResourceServingServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Entering ResourceServingServlet.doGet()");
System.out.println("Request path " + request.getPathInfo());
System.out.println("Query String " + request.getQueryString());
printRequestHeaders(request);
response.setContentType("application/javascript");
getServletContext().getRequestDispatcher("/js/test.js").include(request, response);
System.out.println("Exiting ResourceServingServlet.doGet()");
}
private void printRequestHeaders(HttpServletRequest request){
System.out.println("************** Request Header ****************");
Enumeration headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()){
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
System.out.println(headerName + " = " + headerValue);
}
System.out.println("************** *********** ****************");
}
protected long getLastModified(HttpServletRequest req) {
System.out.println("Inside ResourceServingServlet.getLastModified() ");
long modifiedDate = System.currentTimeMillis() - (3600*1000*1);
System.out.println("Returning long time " + new Date(modifiedDate) );
return modifiedDate;
}
}
If i clean my browser cache and go to the index.jsp page for the first time at say 14th of July 19.27 GMT it will make a request to get test.js file and with value of
Last-Modified
14th of July 18.27 GMT, after that whenever i make request to test.js it will send a If-Modified-Since
header with value equal to July 18.27 GMT, asking ResourceServingServlet
, if its response has changed after 18.27, if no the servlet will return with only headers without body like thisSetting the value of Last-Modified in case when you want to return a large HTML can give you a big performance boost because it wont have to execute the same
doGet()
method logic again and again and calculate and transmit the same response back to client again and again
Thanks for info
ReplyDeleteWeb Design Company in Bangalore
Website development in Bangalore
طراحی فروشگاه اینترنتی حرفه ای با تمام امکانات, کامل ترین پلتفرم نرم افزاری فروش آنلاین در ایران
ReplyDeleteخرید انواع لوازم جانبی موبایل در شیراز با قیمت های مناسب و کیفیت عالی
ReplyDelete