001/* 002 * Copyright 2002-2017 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.view; 018 019import org.springframework.lang.Nullable; 020import org.springframework.util.ClassUtils; 021 022/** 023 * Convenient subclass of {@link UrlBasedViewResolver} that supports 024 * {@link InternalResourceView} (i.e. Servlets and JSPs) and subclasses 025 * such as {@link JstlView}. 026 * 027 * <p>The view class for all views generated by this resolver can be specified 028 * via {@link #setViewClass}. See {@link UrlBasedViewResolver}'s javadoc for details. 029 * The default is {@link InternalResourceView}, or {@link JstlView} if the 030 * JSTL API is present. 031 * 032 * <p>BTW, it's good practice to put JSP files that just serve as views under 033 * WEB-INF, to hide them from direct access (e.g. via a manually entered URL). 034 * Only controllers will be able to access them then. 035 * 036 * <p><b>Note:</b> When chaining ViewResolvers, an InternalResourceViewResolver 037 * always needs to be last, as it will attempt to resolve any view name, 038 * no matter whether the underlying resource actually exists. 039 * 040 * @author Juergen Hoeller 041 * @since 17.02.2003 042 * @see #setViewClass 043 * @see #setPrefix 044 * @see #setSuffix 045 * @see #setRequestContextAttribute 046 * @see InternalResourceView 047 * @see JstlView 048 */ 049public class InternalResourceViewResolver extends UrlBasedViewResolver { 050 051 private static final boolean jstlPresent = ClassUtils.isPresent( 052 "javax.servlet.jsp.jstl.core.Config", InternalResourceViewResolver.class.getClassLoader()); 053 054 @Nullable 055 private Boolean alwaysInclude; 056 057 058 /** 059 * Sets the default {@link #setViewClass view class} to {@link #requiredViewClass}: 060 * by default {@link InternalResourceView}, or {@link JstlView} if the JSTL API 061 * is present. 062 */ 063 public InternalResourceViewResolver() { 064 Class<?> viewClass = requiredViewClass(); 065 if (InternalResourceView.class == viewClass && jstlPresent) { 066 viewClass = JstlView.class; 067 } 068 setViewClass(viewClass); 069 } 070 071 /** 072 * A convenience constructor that allows for specifying {@link #setPrefix prefix} 073 * and {@link #setSuffix suffix} as constructor arguments. 074 * @param prefix the prefix that gets prepended to view names when building a URL 075 * @param suffix the suffix that gets appended to view names when building a URL 076 * @since 4.3 077 */ 078 public InternalResourceViewResolver(String prefix, String suffix) { 079 this(); 080 setPrefix(prefix); 081 setSuffix(suffix); 082 } 083 084 085 /** 086 * This resolver requires {@link InternalResourceView}. 087 */ 088 @Override 089 protected Class<?> requiredViewClass() { 090 return InternalResourceView.class; 091 } 092 093 /** 094 * Specify whether to always include the view rather than forward to it. 095 * <p>Default is "false". Switch this flag on to enforce the use of a 096 * Servlet include, even if a forward would be possible. 097 * @see InternalResourceView#setAlwaysInclude 098 */ 099 public void setAlwaysInclude(boolean alwaysInclude) { 100 this.alwaysInclude = alwaysInclude; 101 } 102 103 104 @Override 105 protected AbstractUrlBasedView buildView(String viewName) throws Exception { 106 InternalResourceView view = (InternalResourceView) super.buildView(viewName); 107 if (this.alwaysInclude != null) { 108 view.setAlwaysInclude(this.alwaysInclude); 109 } 110 view.setPreventDispatchLoop(true); 111 return view; 112 } 113 114}