1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.web.servlet.view;
  17. import java.util.Locale;
  18. import org.springframework.beans.BeanUtils;
  19. import org.springframework.beans.BeansException;
  20. import org.springframework.web.servlet.View;
  21. /**
  22. * Simple implementation of ViewResolver that allows for direct resolution of
  23. * symbolic view names to URLs, without explicit mapping definition. This is
  24. * appropriate if your symbolic names match the names of your view resources
  25. * in a straightforward manner, without the need for arbitrary mappings.
  26. *
  27. * <p>Supports AbstractUrlBasedView subclasses like InternalResourceView and
  28. * VelocityView. The view class for all views generated by this resolver can
  29. * be specified via setViewClass.
  30. *
  31. * <p>View names can either be resource URLs themselves, or get augmented by a
  32. * specified prefix and/or suffix. Exporting an attribute that holds the
  33. * RequestContext to all views is explicitly supported.
  34. *
  35. * <p>Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" ->
  36. * "/WEB-INF/jsp/test.jsp"
  37. *
  38. * <p>Note: This class does not support localized resolution, i.e. resolving
  39. * a symbolic view name to different resources depending on the current locale.
  40. *
  41. * <p>Note: When chaining ViewResolvers, a UrlBasedViewResolver always needs
  42. * to be last, as it will attempt to resolve any view name, no matter whether
  43. * the underlying resource actually exists.
  44. *
  45. * @author Juergen Hoeller
  46. * @since 13.12.2003
  47. * @see #setViewClass
  48. * @see #setPrefix
  49. * @see #setSuffix
  50. * @see #setRequestContextAttribute
  51. * @see AbstractUrlBasedView
  52. */
  53. public class UrlBasedViewResolver extends AbstractCachingViewResolver {
  54. private Class viewClass;
  55. private String prefix = "";
  56. private String suffix = "";
  57. private String contentType;
  58. private String requestContextAttribute;
  59. /**
  60. * Set the view class that should be used to create views.
  61. * @param viewClass class that is assignable to InternalResourceView
  62. */
  63. public void setViewClass(Class viewClass) {
  64. if (viewClass == null || !requiredViewClass().isAssignableFrom(viewClass)) {
  65. throw new IllegalArgumentException("Given View class [" + viewClass.getName() + "] is not of type [" +
  66. requiredViewClass().getName() + "]");
  67. }
  68. this.viewClass = viewClass;
  69. }
  70. /**
  71. * Return the required type of view for this resolver.
  72. * This implementation returns AbstractUrlBasedView.
  73. * @see AbstractUrlBasedView
  74. */
  75. protected Class requiredViewClass() {
  76. return AbstractUrlBasedView.class;
  77. }
  78. /**
  79. * Set the prefix that gets applied to view names when building a URL.
  80. * @param prefix view name prefix
  81. */
  82. public void setPrefix(String prefix) {
  83. this.prefix = prefix;
  84. }
  85. /**
  86. * Set the suffix that gets applied to view names when building a URL.
  87. * @param suffix view name suffix
  88. */
  89. public void setSuffix(String suffix) {
  90. this.suffix = suffix;
  91. }
  92. /**
  93. * Set the content type for all views.
  94. * May be ignored by view classes if the view itself is assumed
  95. * to set the content type, e.g. in case of JSPs.
  96. * @param contentType the content type
  97. */
  98. public void setContentType(String contentType) {
  99. this.contentType = contentType;
  100. }
  101. /**
  102. * Set the name of the RequestContext attribute for all views.
  103. * @param requestContextAttribute name of the RequestContext attribute
  104. */
  105. public void setRequestContextAttribute(String requestContextAttribute) {
  106. this.requestContextAttribute = requestContextAttribute;
  107. }
  108. /**
  109. * This implementation returns just the view name,
  110. * as this ViewResolver doesn't support localized resolution.
  111. */
  112. protected String getCacheKey(String viewName, Locale locale) {
  113. return viewName;
  114. }
  115. protected void initApplicationContext() {
  116. super.initApplicationContext();
  117. if (this.viewClass == null) {
  118. throw new IllegalArgumentException("viewClass is required");
  119. }
  120. }
  121. protected View loadView(String viewName, Locale locale) throws BeansException {
  122. AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(this.viewClass);
  123. view.setBeanName(viewName);
  124. view.setUrl(this.prefix + viewName + this.suffix);
  125. if (this.contentType != null) {
  126. view.setContentType(this.contentType);
  127. }
  128. view.setRequestContextAttribute(this.requestContextAttribute);
  129. return view;
  130. }
  131. }