All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.wicket.protocol.http.WebRequestCycle Maven / Gradle / Ivy

Go to download

Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and unloading of Wicket components and pageSources.

There is a newer version: 5.0.0
Show newest version
/*
 * 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.protocol.http;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.apache.wicket.AbortException;
import org.apache.wicket.IRedirectListener;
import org.apache.wicket.MetaDataKey;
import org.apache.wicket.Page;
import org.apache.wicket.Request;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.Response;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.Session;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.pages.BrowserInfoPage;
import org.apache.wicket.protocol.http.request.WebClientInfo;
import org.apache.wicket.protocol.http.servlet.ServletWebRequest;
import org.apache.wicket.request.ClientInfo;
import org.apache.wicket.request.IRequestCycleProcessor;
import org.apache.wicket.settings.IRequestCycleSettings;
import org.apache.wicket.util.string.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * RequestCycle implementation for HTTP protocol. Holds the application, session, request and
 * response objects for a given HTTP request. Contains methods (urlFor*) which yield a URL for
 * bookmarkable pages as well as non-bookmarkable component interfaces. The protected handleRender
 * method is the internal entrypoint which takes care of the details of rendering a response to an
 * HTTP request.
 * 
 * @see RequestCycle
 * @author Jonathan Locke
 * @author Johan Compagner
 * @author Gili Tzabari
 * @author Eelco Hillenius
 */
public class WebRequestCycle extends RequestCycle
{
	/** Logging object */
	private static final Logger log = LoggerFactory.getLogger(WebRequestCycle.class);

	private static final MetaDataKey BROWSER_WAS_POLLED_KEY = new MetaDataKey()
	{
		private static final long serialVersionUID = 1L;
	};

	/**
	 * Constructor which simply passes arguments to superclass for storage there. This instance will
	 * be set as the current one for this thread.
	 * 
	 * @param application
	 *            The application
	 * @param request
	 *            The request
	 * @param response
	 *            The response
	 */
	public WebRequestCycle(final WebApplication application, final WebRequest request,
		final Response response)
	{
		super(application, request, response);
	}

	/**
	 * By default returns the WebApplication's default request cycle processor. Typically, you don't
	 * override this method but instead override {@link WebApplication#newRequestCycleProcessor()}.
	 * 

* if you decide to override this method to provide a custom processor per request * cycle, any mounts done via WebApplication will not work and and * {@link #onRuntimeException(Page, RuntimeException)} is not called unless you deliberately put * effort in it to make it work. *

* * @see org.apache.wicket.RequestCycle#getProcessor() */ @Override public IRequestCycleProcessor getProcessor() { return ((WebApplication)getApplication()).getRequestCycleProcessor(); } @Override protected void onExceptionLoop(RuntimeException e) { super.onExceptionLoop(e); try { getWebResponse().getHttpServletResponse().sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, null); } catch (IOException e1) { // ignore } } /** * Casts {@link Request} to a {@link WebRequest} * * WARNING: Do not override this method. Use {@link #setRequest(Request)} if request * substitution is needed, or override {@link #getRequest()}. * * @return Request as a WebRequest */ public WebRequest getWebRequest() { return (WebRequest)request; } /** * Casts {@link Response} to a {@link WebResponse} * * WARNING: Do not override this method. Use {@link #setResponse(Response)} if response * substitution is needed, or override {@link #getResponse()}. * * @return Response as a WebResponse */ public WebResponse getWebResponse() { return (WebResponse)response; } /** * Casts {@link Session} to a {@link WebSession} * * WARNING: Do not override this method. * * @return Session as a WebSession */ public WebSession getWebSession() { return (WebSession)getSession(); } /** * Redirects browser to the given page. NOTE: Usually, you should never call this method * directly, but work with setResponsePage instead. This method is part of Wicket's internal * behavior and should only be used when you want to circumvent the normal framework behavior * and issue the redirect directly. * * @param page * The page to redirect to */ @Override public final void redirectTo(final Page page) { String redirectUrl = null; // Check if use serverside response for client side redirects IRequestCycleSettings settings = application.getRequestCycleSettings(); if ((settings.getRenderStrategy() == IRequestCycleSettings.REDIRECT_TO_BUFFER) && (application instanceof WebApplication) && !(getWebRequest().isAjax())) { // remember the current response final WebResponse currentResponse = getWebResponse(); try { if (getWebRequest() instanceof ServletWebRequest) { // Get the redirect url and set it in the ServletWebRequest // so that it can be used for relative url calculation. ((ServletWebRequest)getWebRequest()).setWicketRedirectUrl(Strings.replaceAll( page.urlFor(IRedirectListener.INTERFACE).toString(), "../", "").toString()); } // create the redirect response. final BufferedHttpServletResponse servletResponse = new BufferedHttpServletResponse( currentResponse.getHttpServletResponse()); final WebResponse redirectResponse = new WebResponse(servletResponse) { @Override public CharSequence encodeURL(CharSequence url) { return currentResponse.encodeURL(url); } }; redirectResponse.setCharacterEncoding(currentResponse.getCharacterEncoding()); // redirect the response to the buffer setResponse(redirectResponse); // render the page into the buffer page.renderPage(); // re-assign the original response setResponse(currentResponse); final String responseRedirect = servletResponse.getRedirectUrl(); if (responseRedirect != null) { // if the redirectResponse has another redirect url set // then the rendering of this page caused a redirect to // something else. // set this redirect then. redirectUrl = responseRedirect; } else if (servletResponse.getContentLength() > 0) { // call filter() so that any filters can process the // response servletResponse.filter(currentResponse); // Set the final character encoding before calling close servletResponse.setCharacterEncoding(currentResponse.getCharacterEncoding()); // close it so that the response is fixed and encoded from // here on. servletResponse.close(); if (getWebRequest() instanceof ServletWebRequest) { // Get the redirect url and set it in the ServletWebRequest // so that it can be used for relative url calculation. ((ServletWebRequest)getWebRequest()).setWicketRedirectUrl(null); } redirectUrl = page.urlFor(IRedirectListener.INTERFACE).toString(); String stripped = Strings.stripJSessionId(Strings.replaceAll(redirectUrl, "../", "").toString()); int index = stripped.indexOf("?"); String bufferId = stripped.substring(index + 1); String sessionId = getApplication().getSessionStore().getSessionId(request, true); ((WebApplication)application).addBufferedResponse(sessionId, bufferId, servletResponse); } } catch (RuntimeException ex) { // re-assign the original response setResponse(currentResponse); /* * check if the raised exception wraps an abort exception. if so, it is probably * wise to unwrap and rethrow the abort exception */ Throwable cause = ex; while (cause != null) { if (cause instanceof AbortException) { throw ((AbortException)cause); } cause = cause.getCause(); } if (!(ex instanceof PageExpiredException)) { logRuntimeException(ex); } IRequestCycleProcessor processor = getProcessor(); processor.respond(ex, this); return; } } else { redirectUrl = page.urlFor(IRedirectListener.INTERFACE).toString(); // Redirect page can touch its models already (via for example the // constructors) // this can be removed i guess because this page will be detached in // the page target // page.internalDetach(); } if (redirectUrl == null) { redirectUrl = page.urlFor(IRedirectListener.INTERFACE).toString(); } // Always touch the page again so that a redirect listener makes a page // stateful and adds it to the pagemap getSession().touch(page); // Redirect to the url for the page response.redirect(redirectUrl); } /** * {@inheritDoc} * *

* To gather the client information this implementation redirects temporarily to a special page * ({@link BrowserInfoPage}). *

* Note: Do not call this method from your custom {@link Session} constructor * because the temporary page needs a constructed {@link Session} to be able to work. *

* If you need to set a default client info property then better use * {@link Session#setClientInfo(org.apache.wicket.request.ClientInfo)} directly. */ @Override protected ClientInfo newClientInfo() { if (getApplication().getRequestCycleSettings().getGatherExtendedBrowserInfo()) { Session session = getSession(); if (session.getMetaData(BROWSER_WAS_POLLED_KEY) == null) { // we haven't done the redirect yet; record that we will be // doing that now and redirect session.setMetaData(BROWSER_WAS_POLLED_KEY, Boolean.TRUE); String url = "/" + getRequest().getURL(); throw new RestartResponseException(newBrowserInfoPage(url)); } // if we get here, the redirect already has been done; clear // the meta data entry; we don't need it any longer is the client // info object will be cached too session.setMetaData(BROWSER_WAS_POLLED_KEY, (Boolean)null); } return new WebClientInfo(this); } /** * Override this method if you want to use a custom page for gathering the client's browser * information.
* The easiest way is just to extend {@link BrowserInfoPage} and provide your own markup file * * @param url * the url to redirect to when the browser info is handled * @return the {@link WebPage} which should be used while gathering browser info */ protected WebPage newBrowserInfoPage(String url) { return new BrowserInfoPage(url); } /** * If it's an ajax request we always redirect. * * @see org.apache.wicket.RequestCycle#isRedirect() */ @Override public final boolean isRedirect() { if (getWebRequest().isAjax()) { return true; } else { return super.isRedirect(); } } /** * */ void unset() { set(null); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy