org.apache.wicket.request.http.WebResponse.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.wicket.request.http.WebResponse.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.wicket.request.http;

import java.io.IOException;

import javax.servlet.http.Cookie;

import org.apache.wicket.request.Response;
import org.apache.wicket.util.encoding.UrlEncoder;
import org.apache.wicket.util.lang.Args;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.time.Duration;
import org.apache.wicket.util.time.Time;

/**
 * Base class for web-related responses.
 * 
 * @author Matej Knopp
 */
public abstract class WebResponse extends Response {
    /** Recommended value for cache duration */
    // one year, maximum recommended cache duration in RFC-2616
    public static final Duration MAX_CACHE_DURATION = Duration.days(365);

    /**
     * Add a cookie to the web response
     * 
     * @param cookie
     */
    public abstract void addCookie(final Cookie cookie);

    /**
     * Convenience method for clearing a cookie.
     * 
     * @param cookie
     *            The cookie to set
     * @see WebResponse#addCookie(Cookie)
     */
    public abstract void clearCookie(final Cookie cookie);

    /**
     * Set a header to the string value in the servlet response stream.
     * 
     * @param name
     * @param value
     */
    public abstract void setHeader(String name, String value);

    /**
     * Add a value to the servlet response stream.
     * 
     * @param name
     * @param value
     */
    public abstract void addHeader(String name, String value);

    /**
     * Set a header to the date value in the servlet response stream.
     * 
     * @param name
     * @param date
     */
    public abstract void setDateHeader(String name, Time date);

    /**
     * Set the content length on the response, if appropriate in the subclass. This default
     * implementation does nothing.
     * 
     * @param length
     *            The length of the content
     */
    public abstract void setContentLength(final long length);

    /**
     * Set the content type on the response, if appropriate in the subclass. This default
     * implementation does nothing.
     * 
     * @param mimeType
     *            The mime type
     */
    public abstract void setContentType(final String mimeType);

    /**
     * Sets the content range of the response. If no content range is set the client assumes the
     * whole content. Please note that if the content range is set, the content length, the status
     * code and the accept range must be set right, too.
     *
     * @param contentRange
     *            the content range
     */
    public void setContentRange(final String contentRange) {
        setHeader("Content-Range", contentRange);
    }

    /**
     * Sets the accept range (e.g. bytes)
     *
     * @param acceptRange
     *            the accept range header information
     */
    public void setAcceptRange(final String acceptRange) {
        setHeader("Accept-Range", acceptRange);

    }

    /**
     * Set the contents last modified time, if appropriate in the subclass.
     * 
     * @param time
     *            The last modified time
     */
    public void setLastModifiedTime(final Time time) {
        setDateHeader("Last-Modified", time);
    }

    /**
     * Convenience method for setting the content-disposition:attachment header. This header is used
     * if the response should prompt the user to download it as a file instead of opening in a
     * browser.
     * <p>
     * The file name will be <a href="http://greenbytes.de/tech/tc2231/">encoded</a>
     *
     * @param filename
     *            file name of the attachment
     */
    public void setAttachmentHeader(final String filename) {
        setHeader("Content-Disposition", "attachment" + encodeDispositionHeaderValue(filename));
    }

    /**
     * Convenience method for setting the content-disposition:inline header. This header is used if
     * the response should be shown embedded in browser window while having custom file name when
     * user saves the response. browser.
     * <p>
     * The file name will be <a href="http://greenbytes.de/tech/tc2231/">encoded</a>
     *
     * @param filename
     *            file name of the attachment
     */
    public void setInlineHeader(final String filename) {
        setHeader("Content-Disposition", "inline" + encodeDispositionHeaderValue(filename));
    }

    /**
     * <a href="http://greenbytes.de/tech/tc2231/">Encodes</a> the value of the filename used in
     * "Content-Disposition" response header
     *
     * @param filename
     *            the non-encoded file name
     * @return encoded filename
     */
    private String encodeDispositionHeaderValue(final String filename) {
        return (Strings.isEmpty(filename) ? ""
                : String.format("; filename=\"%1$s\"; filename*=UTF-8''%1$s",
                        UrlEncoder.HEADER_INSTANCE.encode(filename, "UTF-8")));
    }

    /**
     * Sets the status code for this response.
     * 
     * @param sc
     *            status code
     */
    public abstract void setStatus(int sc);

    /**
     * Send error status code with optional message.
     * 
     * @param sc
     * @param msg
     * @throws IOException
     */
    public abstract void sendError(int sc, String msg);

    /**
     * Encodes urls used to redirect. Sometimes rules for encoding URLs for redirecting differ from
     * encoding URLs for links, so this method is broken out away form
     * {@link #encodeURL(CharSequence)}.
     * 
     * @param url
     * @return encoded URL
     */
    public abstract String encodeRedirectURL(CharSequence url);

    /**
     * Redirects the response to specified URL. The implementation is responsible for properly
     * encoding the URL. Implementations of this method should run passed in {@code url} parameters
     * through the {@link #encodeRedirectURL(CharSequence)} method.
     * 
     * @param url
     */
    public abstract void sendRedirect(String url);

    /**
     * @return <code>true</code> is {@link #sendRedirect(String)} was called, <code>false</code>
     *         otherwise.
     */
    public abstract boolean isRedirect();

    /**
     * Flushes the response.
     */
    public abstract void flush();

    /**
     * Make this response non-cacheable
     */
    public void disableCaching() {
        setDateHeader("Date", Time.now());
        setDateHeader("Expires", Time.START_OF_UNIX_TIME);
        setHeader("Pragma", "no-cache");
        setHeader("Cache-Control", "no-cache, no-store");
    }

    /**
     * Make this response cacheable
     * <p/>
     * when trying to enable caching for web pages check this out: <a
     * href="https://issues.apache.org/jira/browse/WICKET-4357">WICKET-4357</a>
     * 
     * @param duration
     *            maximum duration before the response must be invalidated by any caches. It should
     *            not exceed one year, based on <a
     *            href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">RFC-2616</a>.
     * @param scope
     *            controls which caches are allowed to cache the response
     *
     * @see WebResponse#MAX_CACHE_DURATION
     */
    public void enableCaching(Duration duration, final WebResponse.CacheScope scope) {
        Args.notNull(duration, "duration");
        Args.notNull(scope, "scope");

        // do not exceed the maximum recommended value from RFC-2616
        if (duration.compareTo(MAX_CACHE_DURATION) > 0) {
            duration = MAX_CACHE_DURATION;
        }

        // Get current time
        Time now = Time.now();

        // Time of message generation
        setDateHeader("Date", now);

        // Time for cache expiry = now + duration
        setDateHeader("Expires", now.add(duration));

        // Set cache scope
        setHeader("Cache-Control", scope.cacheControl);

        // Set maximum age for caching in seconds (rounded)
        addHeader("Cache-Control", "max-age=" + Math.round(duration.seconds()));

        // Though 'cache' is not an official value it will eliminate an eventual 'no-cache' header
        setHeader("Pragma", "cache");
    }

    /**
     * caching scope for data
     * <p/>
     * Unless the data is confidential, session-specific or user-specific the general advice is to
     * prefer value <code>PUBLIC</code> for best network performance.
     * <p/>
     * This value will basically affect the header [Cache-Control]. Details can be found <a
     * href="http://palisade.plynt.com/issues/2008Jul/cache-control-attributes">here</a> or in <a
     * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">RFC-2616</a>.
     */
    public static enum CacheScope {
        /**
         * use all caches (private + public)
         * <p/>
         * Use this value for caching if the data is not confidential or session-specific. It will
         * allow public caches to cache the data. In some versions of Firefox this will enable
         * caching of resources over SSL (details can be found <a
         * href="http://blog.pluron.com/2008/07/why-you-should.html">here</a>).
         */
        PUBLIC("public"),
        /**
         * only use non-public caches
         * <p/>
         * Use this setting if the response is session-specific or confidential and you don't want
         * it to be cached on public caches or proxies. On some versions of Firefox this will
         * disable caching of any resources in over SSL connections.
         */
        PRIVATE("private");

        // value for Cache-Control header
        private final String cacheControl;

        CacheScope(final String cacheControl) {
            this.cacheControl = cacheControl;
        }
    }
}