001/*
002 * Copyright 2002-2015 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.servlet;
018
019import java.io.IOException;
020import java.util.Map;
021import javax.servlet.ServletException;
022import javax.servlet.http.HttpServlet;
023import javax.servlet.http.HttpServletRequest;
024import javax.servlet.http.HttpServletResponse;
025
026import org.springframework.web.util.NestedServletException;
027
028/**
029 * ViewRendererServlet is a bridge servlet, mainly for the Portlet MVC support.
030 *
031 * <p>For usage with Portlets, this Servlet is necessary to force the portlet container
032 * to convert the PortletRequest to a ServletRequest, which it has to do when
033 * including a resource via the PortletRequestDispatcher. This allows for reuse
034 * of the entire Servlet-based View support even in a Portlet environment.
035 *
036 * <p>The actual mapping of the bridge servlet is configurable in the DispatcherPortlet,
037 * via a "viewRendererUrl" property. The default is "/WEB-INF/servlet/view", which is
038 * just available for internal resource dispatching.
039 *
040 * @author William G. Thompson, Jr.
041 * @author John A. Lewis
042 * @author Juergen Hoeller
043 * @since 2.0
044 */
045@SuppressWarnings("serial")
046public class ViewRendererServlet extends HttpServlet {
047
048        /**
049         * Request attribute to hold current web application context.
050         * Otherwise only the global web app context is obtainable by tags etc.
051         * @see org.springframework.web.servlet.support.RequestContextUtils#findWebApplicationContext
052         */
053        public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE;
054
055        /** Name of request attribute that holds the View object */
056        public static final String VIEW_ATTRIBUTE = ViewRendererServlet.class.getName() + ".VIEW";
057
058        /** Name of request attribute that holds the model Map */
059        public static final String MODEL_ATTRIBUTE = ViewRendererServlet.class.getName() + ".MODEL";
060
061
062        @Override
063        protected final void doGet(HttpServletRequest request, HttpServletResponse response)
064                        throws ServletException, IOException {
065
066                processRequest(request, response);
067        }
068
069        @Override
070        protected final void doPost(HttpServletRequest request, HttpServletResponse response)
071                        throws ServletException, IOException {
072
073                processRequest(request, response);
074        }
075
076        /**
077         * Process this request, handling exceptions.
078         * The actually event handling is performed by the abstract
079         * {@code renderView()} template method.
080         * @see #renderView
081         */
082        protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
083                        throws ServletException, IOException {
084
085                try {
086                        renderView(request, response);
087                }
088                catch (ServletException ex) {
089                        throw ex;
090                }
091                catch (IOException ex) {
092                        throw ex;
093                }
094                catch (Exception ex) {
095                        throw new NestedServletException("View rendering failed", ex);
096                }
097        }
098
099        /**
100         * Retrieve the View instance and model Map to render
101         * and trigger actual rendering.
102         * @param request current HTTP request
103         * @param response current HTTP response
104         * @throws Exception in case of any kind of processing failure
105         * @see org.springframework.web.servlet.View#render
106         */
107        @SuppressWarnings("unchecked")
108        protected void renderView(HttpServletRequest request, HttpServletResponse response) throws Exception {
109                View view = (View) request.getAttribute(VIEW_ATTRIBUTE);
110                if (view == null) {
111                        throw new ServletException("Could not complete render request: View is null");
112                }
113                Map<String, Object> model = (Map<String, Object>) request.getAttribute(MODEL_ATTRIBUTE);
114                view.render(model, request, response);
115        }
116
117}