Example usage for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED

List of usage examples for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED

Introduction

In this page you can find the example usage for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED.

Prototype

int SC_NOT_MODIFIED

To view the source code for javax.servlet.http HttpServletResponse SC_NOT_MODIFIED.

Click Source Link

Document

Status code (304) indicating that a conditional GET operation found that the resource was available and not modified.

Usage

From source file:org.jasig.portlet.calendar.mvc.controller.AjaxCalendarController.java

@ResourceMapping
public ModelAndView getEventList(ResourceRequest request, ResourceResponse response) throws Exception {

    // Pull parameters out of the resourceId
    final String resourceId = request.getResourceID();
    final String[] resourceIdTokens = resourceId.split("-");
    final String startDate = resourceIdTokens[0];
    final int days = Integer.parseInt(resourceIdTokens[1]);
    final boolean refresh = resourceIdTokens.length > 2 ? Boolean.valueOf(resourceIdTokens[2]) : false;

    final long startTime = System.currentTimeMillis();
    final List<String> errors = new ArrayList<String>();
    final Map<String, Object> model = new HashMap<String, Object>();
    final PortletSession session = request.getPortletSession();
    // get the user's configured time zone
    final String timezone = (String) session.getAttribute("timezone");
    final DateTimeZone tz = DateTimeZone.forID(timezone);

    // get the period for this request
    final Interval interval = DateUtil.getInterval(startDate, days, request);

    final Set<CalendarDisplayEvent> calendarEvents = helper.getEventList(errors, interval, request);

    int index = 0;
    final Set<JsonCalendarEventWrapper> events = new TreeSet<JsonCalendarEventWrapper>();
    for (CalendarDisplayEvent e : calendarEvents) {
        events.add(new JsonCalendarEventWrapper(e, index++));
    }/*w w  w.  ja v  a2 s  . co  m*/

    /*
     * Transform the event set into a map keyed by day.  This code is 
     * designed to separate events by day according to the user's configured
     * time zone.  This ensures that we keep complicated time-zone handling
     * logic out of the JavaScript.
     * 
     * Events are keyed by a string uniquely representing the date that is 
     * still orderable.  So that we can display a more user-friendly date
     * name, we also create a map representing date display names for each
     * date keyed in this response.
     */

    // define a DateFormat object that uniquely identifies dates in a way 
    // that can easily be ordered 
    DateTimeFormatter orderableDf = new DateTimeFormatterBuilder().appendYear(4, 4).appendLiteral("-")
            .appendMonthOfYear(2).appendLiteral("-").appendDayOfMonth(2).toFormatter().withZone(tz);

    // define a DateFormat object that can produce user-facing display 
    // names for dates
    DateTimeFormatter displayDf = new DateTimeFormatterBuilder().appendDayOfWeekText().appendLiteral(" ")
            .appendMonthOfYearText().appendLiteral(" ").appendDayOfMonth(1).toFormatter().withZone(tz);

    // define "today" and "tomorrow" so we can display these specially in the
    // user interface
    DateMidnight now = new DateMidnight(tz);
    String today = orderableDf.print(now);
    String tomorrow = orderableDf.print(now.plusDays(1));

    Map<String, String> dateDisplayNames = new HashMap<String, String>();
    Map<String, List<JsonCalendarEventWrapper>> eventsByDay = new LinkedHashMap<String, List<JsonCalendarEventWrapper>>();
    for (JsonCalendarEventWrapper event : events) {
        String day = orderableDf.print(event.getEvent().getDayStart());

        // if we haven't seen this day before, add entries to the event
        // and date name maps
        if (!eventsByDay.containsKey(day)) {

            // add a list for this day to the eventsByDay map
            eventsByDay.put(day, new ArrayList<JsonCalendarEventWrapper>());

            // Add an appropriate day name for this date to the date names
            // map.  If the day appears to be today or tomorrow display a 
            // special string value.  Otherwise, use the user-facing date
            // format object
            if (today.equals(day)) {
                dateDisplayNames.put(day, "Today");
            } else if (tomorrow.equals(day)) {
                dateDisplayNames.put(day, "Tomorrow");
            } else {
                dateDisplayNames.put(day, displayDf.print(event.getEvent().getDayStart()));
            }
        }

        // add the event to the by-day map
        eventsByDay.get(day).add(event);
    }

    if (log.isTraceEnabled()) {
        log.trace("Prepared the following eventsByDay collection for user '" + request.getRemoteUser() + "':"
                + eventsByDay);
    }

    model.put("dateMap", eventsByDay);
    model.put("dateNames", dateDisplayNames);
    model.put("viewName", "jsonView");
    model.put("errors", errors);

    String etag = String.valueOf(model.hashCode());
    String requestEtag = request.getETag();

    // if the request ETag matches the hash for this response, send back
    // an empty response indicating that cached content should be used
    if (!refresh && request.getETag() != null && etag.equals(requestEtag)) {
        if (log.isTraceEnabled()) {
            log.trace("Sending an empty response (due to matched ETag and " + "refresh=false) for user '"
                    + request.getRemoteUser() + "'");
        }
        response.getCacheControl().setExpirationTime(1);
        response.getCacheControl().setETag(etag);
        response.getCacheControl().setUseCachedContent(true);
        response.setProperty(ResourceResponse.HTTP_STATUS_CODE,
                Integer.toString(HttpServletResponse.SC_NOT_MODIFIED));
        // returning null appears to cause the response to be committed
        // before returning to the portal, so just use an empty view
        return new ModelAndView("empty", Collections.<String, String>emptyMap());
    }

    if (log.isTraceEnabled()) {
        log.trace("Sending a full response for user '" + request.getRemoteUser() + "' and refresh=" + refresh);
    }

    // create new content with new validation tag
    response.getCacheControl().setETag(etag);
    response.getCacheControl().setExpirationTime(1);

    long overallTime = System.currentTimeMillis() - startTime;
    log.debug("AjaxCalendarController took " + overallTime + " ms to produce JSON model");

    return new ModelAndView("json", model);
}

From source file:org.apache.struts2.dispatcher.DefaultStaticContentLoader.java

protected void process(InputStream is, String path, HttpServletRequest request, HttpServletResponse response)
        throws IOException {
    if (is != null) {
        Calendar cal = Calendar.getInstance();

        // check for if-modified-since, prior to any other headers
        long ifModifiedSince = 0;
        try {/*from  w w  w  .j a v a  2s .  co m*/
            ifModifiedSince = request.getDateHeader("If-Modified-Since");
        } catch (Exception e) {
            LOG.warn("Invalid If-Modified-Since header value: '{}', ignoring",
                    request.getHeader("If-Modified-Since"));
        }
        long lastModifiedMillis = lastModifiedCal.getTimeInMillis();
        long now = cal.getTimeInMillis();
        cal.add(Calendar.DAY_OF_MONTH, 1);
        long expires = cal.getTimeInMillis();

        if (ifModifiedSince > 0 && ifModifiedSince <= lastModifiedMillis) {
            // not modified, content is not sent - only basic
            // headers and status SC_NOT_MODIFIED
            response.setDateHeader("Expires", expires);
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            is.close();
            return;
        }

        // set the content-type header
        String contentType = getContentType(path);
        if (contentType != null) {
            response.setContentType(contentType);
        }

        if (serveStaticBrowserCache) {
            // set heading information for caching static content
            response.setDateHeader("Date", now);
            response.setDateHeader("Expires", expires);
            response.setDateHeader("Retry-After", expires);
            response.setHeader("Cache-Control", "public");
            response.setDateHeader("Last-Modified", lastModifiedMillis);
        } else {
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Expires", "-1");
        }

        try {
            copy(is, response.getOutputStream());
        } finally {
            is.close();
        }
    }
}

From source file:uk.ac.ebi.phenotype.web.proxy.ExternalUrlConfiguratbleProxyServlet.java

private boolean doResponseRedirectOrNotModifiedLogic(HttpServletRequest servletRequest,
        HttpServletResponse servletResponse, HttpResponse proxyResponse, int statusCode)
        throws ServletException, IOException {
    // Check if the proxy response is a redirect
    // The following code is adapted from
    // org.tigris.noodle.filters.CheckForRedirect
    if (statusCode >= HttpServletResponse.SC_MULTIPLE_CHOICES /* 300 */
            && statusCode < HttpServletResponse.SC_NOT_MODIFIED /* 304 */) {
        Header locationHeader = proxyResponse.getLastHeader(HttpHeaders.LOCATION);
        if (locationHeader == null) {
            throw new ServletException("Recieved status code: " + statusCode + " but no " + HttpHeaders.LOCATION
                    + " header was found in the response");
        }/*from ww w . j a  v  a  2 s  . co m*/
        // Modify the redirect to go to this proxy servlet rather that the
        // proxied host
        String locStr = rewriteUrlFromResponse(servletRequest, locationHeader.getValue());

        servletResponse.sendRedirect(locStr);
        return true;
    }
    // 304 needs special handling. See:
    // http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code304
    // We get a 304 whenever passed an 'If-Modified-Since'
    // header and the data on disk has not changed; server
    // responds w/ a 304 saying I'm not going to send the
    // body because the file has not changed.
    if (statusCode == HttpServletResponse.SC_NOT_MODIFIED) {
        servletResponse.setIntHeader(HttpHeaders.CONTENT_LENGTH, 0);
        servletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return true;
    }
    return false;
}

From source file:ch.entwine.weblounge.test.harness.rest.PagesEndpointTest.java

/**
 * Tries to retrieve a page by its id.//from   www.ja v  a 2s . com
 * 
 * @param serverUrl
 *          the server url
 * @param version
 *          the page version
 * @param id
 *          the page identifier
 * @throws Exception
 *           if retrieval failed
 */
private void testGetPageById(String serverUrl, long version, String id) throws Exception {
    String requestUrl = UrlUtils.concat(serverUrl, "system/weblounge/pages", id);
    HttpGet getPageRequest = new HttpGet(requestUrl);
    String[][] params = new String[][] { { "version", Long.toString(version) } };
    HttpClient httpClient = new DefaultHttpClient();
    Document pageXml = null;
    String eTagValue;
    String modifiedValue;
    logger.info("Requesting page at {}", requestUrl);
    try {
        HttpResponse response = TestUtils.request(httpClient, getPageRequest, params);
        assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
        pageXml = TestUtils.parseXMLResponse(response);
        assertEquals(id, XPathHelper.valueOf(pageXml, "/page/@id"));

        // Test ETag header
        Header eTagHeader = response.getFirstHeader("ETag");
        assertNotNull(eTagHeader);
        assertNotNull(eTagHeader.getValue());
        eTagValue = eTagHeader.getValue();

        Header modifiedHeader = response.getFirstHeader("Last-Modified");
        assertNotNull(modifiedHeader);
        assertNotNull(modifiedHeader.getValue());
        modifiedValue = modifiedHeader.getValue();
    } finally {
        httpClient.getConnectionManager().shutdown();
    }

    // Test E-Tag header
    TestSiteUtils.testETagHeader(getPageRequest, eTagValue, logger, params);

    // Test If-Modified-Since header with non-modified page
    httpClient = new DefaultHttpClient();
    try {
        getPageRequest.removeHeaders("If-None-Match");
        getPageRequest.setHeader("If-Modified-Since", modifiedValue);
        logger.info("Sending 'If-Modified-Since' request to {}", requestUrl);
        HttpResponse response = TestUtils.request(httpClient, getPageRequest, params);
        assertEquals(HttpServletResponse.SC_NOT_MODIFIED, response.getStatusLine().getStatusCode());
        assertNull(response.getEntity());
    } finally {
        httpClient.getConnectionManager().shutdown();
    }

    // Test If-Modified-Since header with modified page
    httpClient = new DefaultHttpClient();
    try {
        getPageRequest.removeHeaders("If-None-Match");
        getPageRequest.setHeader("If-Modified-Since", "Wed, 10 Feb 1999 21:06:40 GMT");
        logger.info("Sending 'If-Modified-Since' request to {}", requestUrl);
        HttpResponse response = TestUtils.request(httpClient, getPageRequest, params);
        assertEquals(HttpServletResponse.SC_OK, response.getStatusLine().getStatusCode());
        assertNotNull(response.getEntity());
    } finally {
        httpClient.getConnectionManager().shutdown();
    }
}

From source file:org.eclipse.userstorage.tests.util.USSServer.java

protected void retrieveBlob(HttpServletRequest request, HttpServletResponse response, File blobFile,
        File etagFile, boolean exists) throws IOException {
    if (!exists) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;/*from  ww w .j  a v a  2  s. c o m*/
    }

    String etag = IOUtil.readUTF(etagFile);
    String ifNoneMatch = getETag(request, "If-None-Match");
    if (ifNoneMatch != null && ifNoneMatch.equals(etag)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return;
    }

    response.setStatus(HttpServletResponse.SC_OK);
    response.setContentType("application/json");
    response.setHeader("ETag", "\"" + etag + "\"");

    InputStream body = JSONUtil.build(Collections.singletonMap("value", new FileInputStream(blobFile)));

    try {
        ServletOutputStream out = response.getOutputStream();
        IOUtil.copy(body, out);
        out.flush();
    } finally {
        IOUtil.closeSilent(body);
    }
}

From source file:org.jahia.services.content.files.StaticFileServlet.java

/**
 * Process the actual request.//from  w ww .  j a  v a 2s.  co m
 *
 * @param request  The request to be processed.
 * @param response The response to be created.
 * @param content  Whether the request body should be written (GET) or not (HEAD).
 * @throws IOException If something fails at I/O level.
 */
private void processRequest(HttpServletRequest request, HttpServletResponse response, boolean content)
        throws IOException {

    // Validate the requested file ------------------------------------------------------------

    // Get requested file by path info.
    String requestedFile = request.getPathInfo();

    // Check if file is actually supplied to the request URL.
    if (requestedFile == null) {
        // Do your thing if the file is not supplied to the request URL.
        // Throw an exception, or send 404, or show default/warning page, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // URL-decode the file name (might contain spaces and on) and prepare file object.
    File file = new File(basePath, URLDecoder.decode(requestedFile, "UTF-8"));

    // Check if file actually exists in filesystem.
    if (!file.exists() || !file.isFile()) {
        // Do your thing if the file appears to be non-existing.
        // Throw an exception, or send 404, or show default/warning page, or just ignore it.
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // Verify the file requested is a descendant of the base directory.
    if (!file.getCanonicalPath().startsWith(basePath)) {
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    // Prepare some variables. The ETag is an unique identifier of the file.
    String fileName = file.getName();
    long length = file.length();
    long lastModified = file.lastModified();
    String eTag = fileName + "_" + length + "_" + lastModified;
    long expires = System.currentTimeMillis() + DEFAULT_EXPIRE_TIME;

    // Validate request headers for caching ---------------------------------------------------

    // If-None-Match header should contain "*" or ETag. If so, then return 304.
    String ifNoneMatch = request.getHeader("If-None-Match");
    if (ifNoneMatch != null && matches(ifNoneMatch, eTag)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
        return;
    }

    // If-Modified-Since header should be greater than LastModified. If so, then return 304.
    // This header is ignored if any If-None-Match header is specified.
    long ifModifiedSince = request.getDateHeader("If-Modified-Since");
    if (ifNoneMatch == null && ifModifiedSince != -1 && ifModifiedSince + 1000 > lastModified) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        response.setHeader("ETag", eTag); // Required in 304.
        response.setDateHeader("Expires", expires); // Postpone cache with 1 week.
        return;
    }

    // Validate request headers for resume ----------------------------------------------------

    // If-Match header should contain "*" or ETag. If not, then return 412.
    String ifMatch = request.getHeader("If-Match");
    if (ifMatch != null && !matches(ifMatch, eTag)) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // If-Unmodified-Since header should be greater than LastModified. If not, then return 412.
    long ifUnmodifiedSince = request.getDateHeader("If-Unmodified-Since");
    if (ifUnmodifiedSince != -1 && ifUnmodifiedSince + 1000 <= lastModified) {
        response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
        return;
    }

    // Validate and process range -------------------------------------------------------------

    // Prepare some variables. The full Range represents the complete file.
    Range full = new Range(0, length - 1, length);
    List<Range> ranges = new ArrayList<Range>();

    // Validate and process Range and If-Range headers.
    String range = request.getHeader("Range");
    if (range != null) {

        // Range header should match format "bytes=n-n,n-n,n-n...". If not, then return 416.
        if (!PATTERN_RANGE.matcher(range).matches()) {
            response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
            response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
            return;
        }

        // If-Range header should either match ETag or be greater then LastModified. If not,
        // then return full file.
        String ifRange = request.getHeader("If-Range");
        if (ifRange != null && !ifRange.equals(eTag)) {
            try {
                long ifRangeTime = request.getDateHeader("If-Range"); // Throws IAE if invalid.
                if (ifRangeTime != -1 && ifRangeTime + 1000 < lastModified) {
                    ranges.add(full);
                }
            } catch (IllegalArgumentException ignore) {
                ranges.add(full);
            }
        }

        // If any valid If-Range header, then process each part of byte range.
        if (ranges.isEmpty()) {
            for (String part : Patterns.COMMA.split(range.substring(6))) {
                // Assuming a file with length of 100, the following examples returns bytes at:
                // 50-80 (50 to 80), 40- (40 to length=100), -20 (length-20=80 to length=100).
                long start = sublong(part, 0, part.indexOf("-"));
                long end = sublong(part, part.indexOf("-") + 1, part.length());

                if (start == -1) {
                    start = length - end;
                    end = length - 1;
                } else if (end == -1 || end > length - 1) {
                    end = length - 1;
                }

                // Check if Range is syntactically valid. If not, then return 416.
                if (start > end) {
                    response.setHeader("Content-Range", "bytes */" + length); // Required in 416.
                    response.sendError(HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE);
                    return;
                }

                // Add range.
                ranges.add(new Range(start, end, length));
            }
        }
    }

    // Prepare and initialize response --------------------------------------------------------

    // Get content type by file name and set default GZIP support and content disposition.
    String contentType = getServletContext().getMimeType(fileName);
    boolean acceptsGzip = false;
    String disposition = "inline";

    // If content type is unknown, then set the default value.
    // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
    // To add new content types, add new mime-mapping entry in web.xml.
    if (contentType == null) {
        contentType = "application/octet-stream";
    }

    // If content type is text, then determine whether GZIP content encoding is supported by
    // the browser and expand content type with the one and right character encoding.
    if (contentType.startsWith("text")) {
        String acceptEncoding = request.getHeader("Accept-Encoding");
        acceptsGzip = enableGzip && acceptEncoding != null && accepts(acceptEncoding, "gzip");
        contentType += ";charset=UTF-8";
    }

    // Else, expect for images, determine content disposition. If content type is supported by
    // the browser, then set to inline, else attachment which will pop a 'save as' dialogue.
    else if (!contentType.startsWith("image")) {
        String accept = request.getHeader("Accept");
        disposition = accept != null && accepts(accept, contentType) ? "inline" : "attachment";
    }

    // Initialize response.
    response.reset();
    response.setBufferSize(DEFAULT_BUFFER_SIZE);
    response.setHeader("Content-Disposition", disposition + ";filename=\"" + fileName + "\"");
    response.setHeader("Accept-Ranges", "bytes");
    response.setHeader("ETag", eTag);
    response.setDateHeader("Last-Modified", lastModified);
    response.setDateHeader("Expires", expires);

    // Send requested file (part(s)) to client ------------------------------------------------

    // Prepare streams.
    RandomAccessFile input = null;
    OutputStream output = null;

    try {
        // Open streams.
        input = new RandomAccessFile(file, "r");
        output = response.getOutputStream();

        if (ranges.isEmpty() || ranges.get(0) == full) {

            // Return full file.
            Range r = full;
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);

            if (content) {
                if (acceptsGzip) {
                    // The browser accepts GZIP, so GZIP the content.
                    response.setHeader("Content-Encoding", "gzip");
                    output = new GZIPOutputStream(output, DEFAULT_BUFFER_SIZE);
                } else {
                    // Content length is not directly predictable in case of GZIP.
                    // So only add it if there is no means of GZIP, else browser will hang.
                    response.setHeader("Content-Length", String.valueOf(r.length));
                }

                // Copy full range.
                copy(input, output, r.start, r.length);
            }

        } else if (ranges.size() == 1) {

            // Return single part of file.
            Range r = ranges.get(0);
            response.setContentType(contentType);
            response.setHeader("Content-Range", "bytes " + r.start + "-" + r.end + "/" + r.total);
            response.setHeader("Content-Length", String.valueOf(r.length));
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Copy single part range.
                copy(input, output, r.start, r.length);
            }

        } else {

            // Return multiple parts of file.
            response.setContentType("multipart/byteranges; boundary=" + MULTIPART_BOUNDARY);
            response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); // 206.

            if (content) {
                // Cast back to ServletOutputStream to get the easy println methods.
                ServletOutputStream sos = (ServletOutputStream) output;

                // Copy multi part range.
                for (Range r : ranges) {
                    // Add multipart boundary and header fields for every range.
                    sos.println();
                    sos.println("--" + MULTIPART_BOUNDARY);
                    sos.println("Content-Type: " + contentType);
                    sos.println("Content-Range: bytes " + r.start + "-" + r.end + "/" + r.total);

                    // Copy single part range of multi part range.
                    copy(input, output, r.start, r.length);
                }

                // End with multipart boundary.
                sos.println();
                sos.println("--" + MULTIPART_BOUNDARY + "--");
            }
        }
    } finally {
        // Gently close streams.
        close(output);
        close(input);
    }
}

From source file:org.jasig.portlet.maps.mvc.portlet.MapViewController.java

@ResourceMapping
public ModelAndView getMapData(ResourceRequest request, ResourceResponse response) {

    log.debug("Getting map data during resource request");
    MapData mapData = getMapData(request);
    String etag = String.valueOf(mapData.hashCode());
    String requestEtag = request.getETag();

    // if the request ETag matches the hash for this response, send back
    // an empty response indicating that cached content should be used
    if (request.getETag() != null && etag.equals(requestEtag)) {
        response.getCacheControl().setExpirationTime(360);
        response.getCacheControl().setUseCachedContent(true);
        response.setProperty(ResourceResponse.HTTP_STATUS_CODE,
                Integer.toString(HttpServletResponse.SC_NOT_MODIFIED));
        // returning null appears to cause the response to be committed
        // before returning to the portal, so just use an empty view
        return new ModelAndView("json", Collections.<String, String>emptyMap());
    }//from   w w w . ja  v a 2 s . c o m

    // create new content with new validation tag
    response.getCacheControl().setETag(etag);
    response.getCacheControl().setExpirationTime(360);

    ModelAndView mv = new ModelAndView("json");
    mv.addObject(mapData);
    return mv;
}

From source file:com.sap.dirigible.runtime.registry.RegistryServlet.java

private boolean setCacheHeaders(IEntity entity, HttpServletRequest request, HttpServletResponse response)
        throws IOException {

    boolean cached = false;
    IEntityInformation entityInformation = entity.getInformation();
    String modifiedSinceHeader = request.getHeader(IF_MODIFIED_SINCE_HEADER);

    if ((entityInformation != null)) {
        Calendar lastModified = getCalendar(entityInformation.getModifiedAt());

        if ((!StringUtils.isEmpty(modifiedSinceHeader))) {
            Calendar modifiedSince = getCalendar(DateUtils.parseDate(modifiedSinceHeader));

            if (lastModified.compareTo(modifiedSince) <= 0) {

                Calendar expires = getCalendar(lastModified);
                expires.add(Calendar.MONTH, 1);

                response.setDateHeader(EXPIRES_HEADER, expires.getTimeInMillis());
                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);

                cached = true;//from  w ww .java2 s  . co m
            }
        }
        response.setDateHeader(LAST_MODIFIED_HEADER, lastModified.getTimeInMillis());
    }
    return cached;
}

From source file:de.blizzy.documentr.web.page.PageControllerTest.java

@Test
public void getPageMustReturn304IfNotModified() throws IOException {
    when(session.getAttribute("authenticationCreationTime")).thenReturn( //$NON-NLS-1$
            new GregorianCalendar(2012, Calendar.JUNE, 2).getTime().getTime());

    when(request.getDateHeader("If-Modified-Since")).thenReturn( //$NON-NLS-1$
            new GregorianCalendar(2012, Calendar.JUNE, 9).getTimeInMillis());
    when(request.getSession()).thenReturn(session);

    when(pageStore.getPageMetadata(eq(PROJECT), eq(BRANCH), eq("nonexistent"))) //$NON-NLS-1$
            .thenReturn(new PageMetadata("user", new GregorianCalendar(2012, Calendar.JUNE, 1).getTime(), 123, //$NON-NLS-1$
                    "commit")); //$NON-NLS-1$

    TestPageUtil.clearProjectEditTimes();

    SecurityContextHolder.setContext(createSecurityContext(anonymousAuthentication));
    String view = pageController.getPage(PROJECT, BRANCH, "nonexistent", model, request, response); //$NON-NLS-1$
    SecurityContextHolder.clearContext();
    assertTrue(removeViewPrefix(view).startsWith("/error/" + HttpServletResponse.SC_NOT_MODIFIED + "/")); //$NON-NLS-1$ //$NON-NLS-2$
    assertForward(view);/*from  ww w  .  ja  v  a  2 s .  c om*/
}

From source file:password.pwm.http.servlet.resource.ResourceFileServlet.java

protected void processAction(final PwmRequest pwmRequest)
        throws ServletException, IOException, PwmUnrecoverableException {
    if (pwmRequest.getMethod() != HttpMethod.GET) {
        throw new PwmUnrecoverableException(new ErrorInformation(PwmError.ERROR_SERVICE_NOT_AVAILABLE,
                "unable to process resource request for request method " + pwmRequest.getMethod()));
    }//from  w  w  w. ja  va 2  s . c om

    final PwmApplication pwmApplication = pwmRequest.getPwmApplication();
    final ResourceServletService resourceService = pwmApplication.getResourceServletService();
    final ResourceServletConfiguration resourceConfiguration = resourceService
            .getResourceServletConfiguration();

    final String requestURI = stripNonceFromURI(resourceConfiguration,
            figureRequestPathMinusContext(pwmRequest.getHttpServletRequest()));

    try {
        if (handleEmbeddedURIs(pwmApplication, requestURI, pwmRequest.getPwmResponse().getHttpServletResponse(),
                resourceConfiguration)) {
            return;
        }
    } catch (Exception e) {
        LOGGER.error(pwmRequest, "unexpected error detecting/handling special request uri: " + e.getMessage());
    }

    final FileResource file;
    try {
        file = resolveRequestedFile(this.getServletContext(), requestURI, resourceConfiguration);
    } catch (PwmUnrecoverableException e) {
        pwmRequest.getPwmResponse().getHttpServletResponse()
                .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
        try {
            pwmRequest.debugHttpRequestToLog("returning HTTP 500 status");
        } catch (PwmUnrecoverableException e2) {
            /* noop */ }
        return;
    }

    if (file == null || !file.exists()) {
        pwmRequest.getPwmResponse().getHttpServletResponse().sendError(HttpServletResponse.SC_NOT_FOUND);
        try {
            pwmRequest.debugHttpRequestToLog("returning HTTP 404 status");
        } catch (PwmUnrecoverableException e) {
            /* noop */ }
        return;
    }

    // Get content type by file name and set default GZIP support and content disposition.
    String contentType = getMimeType(file.getName());
    boolean acceptsGzip = false;

    // If content type is unknown, then set the default value.
    // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
    // To add new content types, add new mime-mapping entry in web.xml.
    if (contentType == null) {
        contentType = "application/octet-stream";
    }

    // If content type is text, then determine whether GZIP content encoding is supported by
    // the browser and expand content type with the one and right character encoding.
    if (resourceConfiguration.isEnableGzip()) {
        if (contentType.startsWith("text") || contentType.contains("javascript")) {
            final String acceptEncoding = pwmRequest.readHeaderValueAsString(HttpHeader.Accept_Encoding);
            acceptsGzip = acceptEncoding != null && accepts(acceptEncoding, "gzip");
            contentType += ";charset=UTF-8";
        }
    }

    final HttpServletResponse response = pwmRequest.getPwmResponse().getHttpServletResponse();
    final String eTagValue = resourceConfiguration.getNonceValue();

    { // reply back with etag.
        final String ifNoneMatchValue = pwmRequest.readHeaderValueAsString(HttpHeader.If_None_Match);
        if (ifNoneMatchValue != null && ifNoneMatchValue.equals(eTagValue)) {
            response.reset();
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            try {
                pwmRequest.debugHttpRequestToLog("returning HTTP 304 status");
            } catch (PwmUnrecoverableException e2) {
                /* noop */ }
            return;
        }
    }

    // Initialize response.
    addExpirationHeaders(resourceConfiguration, response);
    response.setHeader("ETag", resourceConfiguration.getNonceValue());
    response.setContentType(contentType);

    try {
        boolean fromCache = false;
        StringBuilder debugText = new StringBuilder();
        try {
            fromCache = handleCacheableResponse(resourceConfiguration, response, file, acceptsGzip,
                    resourceService.getCacheMap());
            if (fromCache || acceptsGzip) {
                debugText.append("(");
                if (fromCache) {
                    debugText.append("cached");
                }
                if (fromCache && acceptsGzip) {
                    debugText.append(", ");
                }
                if (acceptsGzip) {
                    debugText.append("gzip");
                }
                debugText.append(")");
            } else {
                debugText = new StringBuilder("(not cached)");
            }
            StatisticsManager.incrementStat(pwmApplication, Statistic.HTTP_RESOURCE_REQUESTS);
        } catch (UncacheableResourceException e) {
            handleUncachedResponse(response, file, acceptsGzip);
            debugText = new StringBuilder();
            debugText.append("(uncacheable");
            if (acceptsGzip) {
                debugText.append(", gzip");
            }
            debugText.append(")");
        }
        try {
            pwmRequest.debugHttpRequestToLog(debugText.toString());
        } catch (PwmUnrecoverableException e) {
            /* noop */
        }

        final EventRateMeter.MovingAverage cacheHitRatio = resourceService.getCacheHitRatio();
        cacheHitRatio.update(fromCache ? 1 : 0);
    } catch (Exception e) {
        LOGGER.error(pwmRequest,
                "error fulfilling response for url '" + requestURI + "', error: " + e.getMessage());
    }
}