001/* 002 * Copyright 2002-2014 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.mvc; 018 019import javax.servlet.http.HttpServletRequest; 020import javax.servlet.http.HttpServletResponse; 021 022import org.springframework.http.HttpMethod; 023import org.springframework.http.HttpStatus; 024import org.springframework.web.servlet.ModelAndView; 025import org.springframework.web.servlet.View; 026import org.springframework.web.servlet.support.RequestContextUtils; 027 028/** 029 * Trivial controller that always returns a pre-configured view and optionally 030 * sets the response status code. The view and status can be configured using 031 * the provided configuration properties. 032 * 033 * @author Rod Johnson 034 * @author Juergen Hoeller 035 * @author Keith Donald 036 * @author Rossen Stoyanchev 037 */ 038public class ParameterizableViewController extends AbstractController { 039 040 private Object view; 041 042 private HttpStatus statusCode; 043 044 private boolean statusOnly; 045 046 047 public ParameterizableViewController() { 048 super(false); 049 setSupportedMethods(HttpMethod.GET.name(), HttpMethod.HEAD.name()); 050 } 051 052 /** 053 * Set a view name for the ModelAndView to return, to be resolved by the 054 * DispatcherServlet via a ViewResolver. Will override any pre-existing 055 * view name or View. 056 */ 057 public void setViewName(String viewName) { 058 this.view = viewName; 059 } 060 061 /** 062 * Return the name of the view to delegate to, or {@code null} if using a 063 * View instance. 064 */ 065 public String getViewName() { 066 return (this.view instanceof String ? (String) this.view : null); 067 } 068 069 /** 070 * Set a View object for the ModelAndView to return. 071 * Will override any pre-existing view name or View. 072 * @since 4.1 073 */ 074 public void setView(View view) { 075 this.view = view; 076 } 077 078 /** 079 * Return the View object, or {@code null} if we are using a view name 080 * to be resolved by the DispatcherServlet via a ViewResolver. 081 * @since 4.1 082 */ 083 public View getView() { 084 return (this.view instanceof View ? (View) this.view : null); 085 } 086 087 /** 088 * Configure the HTTP status code that this controller should set on the 089 * response. 090 * <p>When a "redirect:" prefixed view name is configured, there is no need 091 * to set this property since RedirectView will do that. However this property 092 * may still be used to override the 3xx status code of {@code RedirectView}. 093 * For full control over redirecting provide a {@code RedirectView} instance. 094 * <p>If the status code is 204 and no view is configured, the request is 095 * fully handled within the controller. 096 * @since 4.1 097 */ 098 public void setStatusCode(HttpStatus statusCode) { 099 this.statusCode = statusCode; 100 } 101 102 /** 103 * Return the configured HTTP status code or {@code null}. 104 * @since 4.1 105 */ 106 public HttpStatus getStatusCode() { 107 return this.statusCode; 108 } 109 110 111 /** 112 * The property can be used to indicate the request is considered fully 113 * handled within the controller and that no view should be used for rendering. 114 * Useful in combination with {@link #setStatusCode}. 115 * <p>By default this is set to {@code false}. 116 * @since 4.1 117 */ 118 public void setStatusOnly(boolean statusOnly) { 119 this.statusOnly = statusOnly; 120 } 121 122 /** 123 * Whether the request is fully handled within the controller. 124 */ 125 public boolean isStatusOnly() { 126 return this.statusOnly; 127 } 128 129 130 /** 131 * Return a ModelAndView object with the specified view name. 132 * <p>The content of the {@link RequestContextUtils#getInputFlashMap 133 * "input" FlashMap} is also added to the model. 134 * @see #getViewName() 135 */ 136 @Override 137 protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) 138 throws Exception { 139 140 String viewName = getViewName(); 141 142 if (getStatusCode() != null) { 143 if (getStatusCode().is3xxRedirection()) { 144 request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, getStatusCode()); 145 viewName = (viewName != null && !viewName.startsWith("redirect:") ? "redirect:" + viewName : viewName); 146 } 147 else { 148 response.setStatus(getStatusCode().value()); 149 if (isStatusOnly() || (getStatusCode().equals(HttpStatus.NO_CONTENT) && getViewName() == null)) { 150 return null; 151 } 152 } 153 } 154 155 ModelAndView modelAndView = new ModelAndView(); 156 modelAndView.addAllObjects(RequestContextUtils.getInputFlashMap(request)); 157 158 if (getViewName() != null) { 159 modelAndView.setViewName(viewName); 160 } 161 else { 162 modelAndView.setView(getView()); 163 } 164 165 return (isStatusOnly() ? null : modelAndView); 166 } 167 168}