赞
踩
Controller是控制器接口,此处只有一个方法handleRequest,
用于进行请求的功能处理,处理完请求后返回ModelAndView(Model模型数据部分 和 View视图部分)。
如果想直接在处理器/控制器里使用response向客户端写回数据,
可以通过返回null来告诉DispatcherServlet我们已经写出响应了,
不需要它进行视图解析
- 例:
-
- package com.briup.web.controller;
-
- import java.io.PrintWriter;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.springframework.web.servlet.ModelAndView;
- import org.springframework.web.servlet.mvc.Controller;
-
- public class SecondController
- implements Controller{
-
- @Override
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
- // PrintWriter pw=
- // response.getWriter();
- // pw.println("test...ok");
- // pw.flush();
- //request.getSession(false);
- //false:有session返回session对象,没有session返回null
- //true:有session返回session对象,没有session对象创建session
- request.getSession();
- //可以服务器内部页面跳转,不能重定向
- //因为浏览器拿不到WEB-INF下的jsp文件
- request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp")
- .forward(request, response);
- //返回null 前端控制器不会调用
- //视图解析器处理
- return null;
- }
-
- }
-
-
-
- 2.spring.xml配置
-
- <bean name="/second"
- class="com.briup.web.controller.SecondController"></bean>
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Spring默认提供了一些Controller接口的实现类以方便我们使用,在Eclipse中选择Controller接口然后右
键open type Hierarchy即可查看改接口的实现类,每个实现类都有自己特殊的功能,这里以实现类AbstractController为例简单介绍下。
查看AbstractController类中代码可知,我们写一个Controller的时候可以继承AbstractController然后实现handleRequestInternal方法即可。
AbstractController类中private boolean synchronizeOnSession = false;锁属性定义了会话串行。
WebContentGenerator类中private Set<String> supportedMethods;属性设置了请求方式。
WebContentGenerator类中private boolean requireSession = false;属性判断了是否有session对象,没有报错。
WebContentGenerator类中private int cacheSeconds = -1;属性设置了是否缓存上次内容。
(AbstractController类,WebContentGenerator类可在jar包查看源码:spring-webmvc-5.0.10.RELEASE-sources.jar)
(注:RELEASE测试jar包)
都可以通过继承利用见下例:ThirdController.java类的配置。
提供了【可选】的会话的串行化访问功能,例如:
- //即同一会话,线程同步
- public class HelloWorldController extends AbstractController{
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
- throws Exception {
-
- String name = request.getParameter("name");
-
- //ModelAndView对象中包括了要返回的逻辑视图,以及数据模型
- ModelAndView mv = new ModelAndView();
- //设置视图名称,可以是字符串 也可以是视图对象
- mv.setViewName("hello");
- //设置数据模型
- mv.addObject("name", name);
-
- return mv;
- }
-
-
- }
- <!--synchronizeOnSession,统一浏览器访问串行-->
- <bean name="/hello" class="com.briup.web.controller.HelloWorldController">
- <property name="synchronizeOnSession" value="test"></property>
- </bean>
-
-
-
- 直接通过response写响应,例如:
- public class HelloWorldController extends AbstractController{
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
- throws Exception {
-
- response.getWriter().write("Hello World!!");
- //如果想直接在该处理器/控制器写响应 可以通过返回null告诉DispatcherServlet自己已经写出响应了,不需要它进行视图解析
-
- return null;
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
强制请求方法类型,例如:
- //只支持post和get方法
- <bean name="/hello" class="com.briup.web.controller.HelloWorldController">
- <property name="supportedMethods" value="POST,GET"></property>
- </bean>
-
-
- 当前请求的session前置条件检查,如果当前请求无session将抛出HttpSessionRequiredException异常,例如:
- //在进入该控制器时,一定要有session存在,否则抛出HttpSessionRequiredException异常。
-
- <bean name="/hello" class="com.briup.web.controller.HelloWorldController">
- <property name="requireSession" value="true"/>
- </bean>
ThirdController类:
- 例:避免重复刷新造成线程不安全
-
- package com.briup.web.controller;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.springframework.web.servlet.ModelAndView;
- import org.springframework.web.servlet.mvc.AbstractController;
-
- /*
- * 实现特定的功能用特定类
- *
- *同一个个浏览器。发出多个请求
- *请求相同的资源的时候,会话级别的
- *对访问的资源加锁
- *注意:浏览器每次发出一个请求服务器
- *都会启动一个线程去处理(多次请求
- *用同一个线程,也可能多个请求用的
- *不同的线程)
- */
- public class ThirdController
- extends AbstractController{
- @Override
- protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
- throws Exception {
- ModelAndView mv=
- new ModelAndView();
- mv.setViewName("hello");
- return mv;
- }
-
- }
-
-
-
-
- spring.xml配置:
-
- <bean name="/third"
- class="com.briup.web.controller.ThirdController">
- <!-- <property name="synchronizeOnSession"
- value="true"></property> -->
- <!--本次请求支持提交的方式 WebControllerGenerator类中supportedMethods属性 -->
- <!--value中没有请求提交的方式会报405错误-->
- <!-- <property name="supportedMethods" value="POST,GET">
- </property> -->
- <!-- 本次请求,服务器必须给当前浏览器
- 构建过session 会话,没有session直接报错
- -->
- <!-- <property name="requireSession"
- value="true"></property> -->
- <!-- (-1)表示默认,缓存上次的内容
- 0 表示直接不缓存
- 正数,表示缓存,缓存时间的设置
- -->
- <property name="cacheSeconds" value="0"></property>
- </bean>
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- 注:Controller抽象类Spring给了很多,方法很多,扩展性很强。
-
- AbstractController类
-
- /*
- * Copyright 2002-2016 the original author or authors.
- *
- * Licensed 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.springframework.web.servlet.mvc;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
-
- import org.springframework.http.HttpMethod;
- import org.springframework.lang.Nullable;
- import org.springframework.web.servlet.ModelAndView;
- import org.springframework.web.servlet.support.WebContentGenerator;
- import org.springframework.web.util.WebUtils;
-
- /**
- * Convenient superclass for controller implementations, using the Template Method
- * design pattern.
- *
- * <p><b><a name="workflow">Workflow
- * (<a href="Controller.html#workflow">and that defined by interface</a>):</b><br>
- * <ol>
- * <li>{@link #handleRequest(HttpServletRequest, HttpServletResponse) handleRequest()}
- * will be called by the DispatcherServlet</li>
- * <li>Inspection of supported methods (ServletException if request method
- * is not support)</li>
- * <li>If session is required, try to get it (ServletException if not found)</li>
- * <li>Set caching headers if needed according to the cacheSeconds property</li>
- * <li>Call abstract method
- * {@link #handleRequestInternal(HttpServletRequest, HttpServletResponse) handleRequestInternal()}
- * (optionally synchronizing around the call on the HttpSession),
- * which should be implemented by extending classes to provide actual
- * functionality to return {@link org.springframework.web.servlet.ModelAndView ModelAndView} objects.</li>
- * </ol>
- *
- * <p><b><a name="config">Exposed configuration properties</a>
- * (<a href="Controller.html#config">and those defined by interface</a>):</b><br>
- * <table border="1">
- * <tr>
- * <td><b>name</b></th>
- * <td><b>default</b></td>
- * <td><b>description</b></td>
- * </tr>
- * <tr>
- * <td>supportedMethods</td>
- * <td>GET,POST</td>
- * <td>comma-separated (CSV) list of methods supported by this controller,
- * such as GET, POST and PUT</td>
- * </tr>
- * <tr>
- * <td>requireSession</td>
- * <td>false</td>
- * <td>whether a session should be required for requests to be able to
- * be handled by this controller. This ensures that derived controller
- * can - without fear of null pointers - call request.getSession() to
- * retrieve a session. If no session can be found while processing
- * the request, a ServletException will be thrown</td>
- * </tr>
- * <tr>
- * <td>cacheSeconds</td>
- * <td>-1</td>
- * <td>indicates the amount of seconds to include in the cache header
- * for the response following on this request. 0 (zero) will include
- * headers for no caching at all, -1 (the default) will not generate
- * <i>any headers</i> and any positive number will generate headers
- * that state the amount indicated as seconds to cache the content</td>
- * </tr>
- * <tr>
- * <td>synchronizeOnSession</td>
- * <td>false</td>
- * <td>whether the call to {@code handleRequestInternal} should be
- * synchronized around the HttpSession, to serialize invocations
- * from the same client. No effect if there is no HttpSession.
- * </td>
- * </tr>
- * </table>
- *
- * @author Rod Johnson
- * @author Juergen Hoeller
- * @author Rossen Stoyanchev
- * @see WebContentInterceptor
- */
- public abstract class AbstractController extends WebContentGenerator implements Controller {
-
- private boolean synchronizeOnSession = false;
-
-
- /**
- * Create a new AbstractController which supports
- * HTTP methods GET, HEAD and POST by default.
- */
- public AbstractController() {
- this(true);
- }
-
- /**
- * Create a new AbstractController.
- * @param restrictDefaultSupportedMethods {@code true} if this
- * controller should support HTTP methods GET, HEAD and POST by default,
- * or {@code false} if it should be unrestricted
- * @since 4.3
- */
- public AbstractController(boolean restrictDefaultSupportedMethods) {
- super(restrictDefaultSupportedMethods);
- }
-
-
- /**
- * Set if controller execution should be synchronized on the session,
- * to serialize parallel invocations from the same client.
- * <p>More specifically, the execution of the {@code handleRequestInternal}
- * method will get synchronized if this flag is "true". The best available
- * session mutex will be used for the synchronization; ideally, this will
- * be a mutex exposed by HttpSessionMutexListener.
- * <p>The session mutex is guaranteed to be the same object during
- * the entire lifetime of the session, available under the key defined
- * by the {@code SESSION_MUTEX_ATTRIBUTE} constant. It serves as a
- * safe reference to synchronize on for locking on the current session.
- * <p>In many cases, the HttpSession reference itself is a safe mutex
- * as well, since it will always be the same object reference for the
- * same active logical session. However, this is not guaranteed across
- * different servlet containers; the only 100% safe way is a session mutex.
- * @see AbstractController#handleRequestInternal
- * @see org.springframework.web.util.HttpSessionMutexListener
- * @see org.springframework.web.util.WebUtils#getSessionMutex(javax.servlet.http.HttpSession)
- */
- public final void setSynchronizeOnSession(boolean synchronizeOnSession) {
- this.synchronizeOnSession = synchronizeOnSession;
- }
-
- /**
- * Return whether controller execution should be synchronized on the session.
- */
- public final boolean isSynchronizeOnSession() {
- return this.synchronizeOnSession;
- }
-
-
- @Override
- @Nullable
- public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
- throws Exception {
-
- if (HttpMethod.OPTIONS.matches(request.getMethod())) {
- response.setHeader("Allow", getAllowHeader());
- return null;
- }
-
- // Delegate to WebContentGenerator for checking and preparing.
- checkRequest(request);
- prepareResponse(response);
-
- // Execute handleRequestInternal in synchronized block if required.
- if (this.synchronizeOnSession) {
- HttpSession session = request.getSession(false);
- if (session != null) {
- Object mutex = WebUtils.getSessionMutex(session);
- synchronized (mutex) {
- return handleRequestInternal(request, response);
- }
- }
- }
-
- return handleRequestInternal(request, response);
- }
-
- /**
- * Template method. Subclasses must implement this.
- * The contract is the same as for {@code handleRequest}.
- * @see #handleRequest
- */
- @Nullable
- protected abstract ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
- throws Exception;
-
- }
-
-
-
- WebContentGenerator类
-
- /*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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.springframework.web.servlet.support;
-
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.LinkedHashSet;
- import java.util.Set;
- import java.util.concurrent.TimeUnit;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.springframework.http.CacheControl;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpMethod;
- import org.springframework.lang.Nullable;
- import org.springframework.util.ObjectUtils;
- import org.springframework.util.StringUtils;
- import org.springframework.web.HttpRequestMethodNotSupportedException;
- import org.springframework.web.HttpSessionRequiredException;
- import org.springframework.web.context.support.WebApplicationObjectSupport;
-
- /**
- * Convenient superclass for any kind of web content generator,
- * like {@link org.springframework.web.servlet.mvc.AbstractController}
- * and {@link org.springframework.web.servlet.mvc.WebContentInterceptor}.
- * Can also be used for custom handlers that have their own
- * {@link org.springframework.web.servlet.HandlerAdapter}.
- *
- * <p>Supports HTTP cache control options. The usage of corresponding HTTP
- * headers can be controlled via the {@link #setCacheSeconds "cacheSeconds"}
- * and {@link #setCacheControl "cacheControl"} properties.
- *
- * <p><b>NOTE:</b> As of Spring 4.2, this generator's default behavior changed when
- * using only {@link #setCacheSeconds}, sending HTTP response headers that are in line
- * with current browsers and proxies implementations (i.e. no HTTP 1.0 headers anymore)
- * Reverting to the previous behavior can be easily done by using one of the newly
- * deprecated methods {@link #setUseExpiresHeader}, {@link #setUseCacheControlHeader},
- * {@link #setUseCacheControlNoStore} or {@link #setAlwaysMustRevalidate}.
- *
- * @author Rod Johnson
- * @author Juergen Hoeller
- * @author Brian Clozel
- * @author Rossen Stoyanchev
- * @see #setCacheSeconds
- * @see #setCacheControl
- * @see #setRequireSession
- */
- public abstract class WebContentGenerator extends WebApplicationObjectSupport {
-
- /** HTTP method "GET" */
- public static final String METHOD_GET = "GET";
-
- /** HTTP method "HEAD" */
- public static final String METHOD_HEAD = "HEAD";
-
- /** HTTP method "POST" */
- public static final String METHOD_POST = "POST";
-
- private static final String HEADER_PRAGMA = "Pragma";
-
- private static final String HEADER_EXPIRES = "Expires";
-
- protected static final String HEADER_CACHE_CONTROL = "Cache-Control";
-
-
- /** Set of supported HTTP methods */
- @Nullable
- private Set<String> supportedMethods;
-
- @Nullable
- private String allowHeader;
-
- private boolean requireSession = false;
-
- @Nullable
- private CacheControl cacheControl;
-
- private int cacheSeconds = -1;
-
- @Nullable
- private String[] varyByRequestHeaders;
-
-
- // deprecated fields
-
- /** Use HTTP 1.0 expires header? */
- private boolean useExpiresHeader = false;
-
- /** Use HTTP 1.1 cache-control header? */
- private boolean useCacheControlHeader = true;
-
- /** Use HTTP 1.1 cache-control header value "no-store"? */
- private boolean useCacheControlNoStore = true;
-
- private boolean alwaysMustRevalidate = false;
-
-
- /**
- * Create a new WebContentGenerator which supports
- * HTTP methods GET, HEAD and POST by default.
- */
- public WebContentGenerator() {
- this(true);
- }
-
- /**
- * Create a new WebContentGenerator.
- * @param restrictDefaultSupportedMethods {@code true} if this
- * generator should support HTTP methods GET, HEAD and POST by default,
- * or {@code false} if it should be unrestricted
- */
- public WebContentGenerator(boolean restrictDefaultSupportedMethods) {
- if (restrictDefaultSupportedMethods) {
- this.supportedMethods = new LinkedHashSet<>(4);
- this.supportedMethods.add(METHOD_GET);
- this.supportedMethods.add(METHOD_HEAD);
- this.supportedMethods.add(METHOD_POST);
- }
- initAllowHeader();
- }
-
- /**
- * Create a new WebContentGenerator.
- * @param supportedMethods the supported HTTP methods for this content generator
- */
- public WebContentGenerator(String... supportedMethods) {
- setSupportedMethods(supportedMethods);
- }
-
-
- /**
- * Set the HTTP methods that this content generator should support.
- * <p>Default is GET, HEAD and POST for simple form controller types;
- * unrestricted for general controllers and interceptors.
- */
- public final void setSupportedMethods(@Nullable String... methods) {
- if (!ObjectUtils.isEmpty(methods)) {
- this.supportedMethods = new LinkedHashSet<>(Arrays.asList(methods));
- }
- else {
- this.supportedMethods = null;
- }
- initAllowHeader();
- }
-
- /**
- * Return the HTTP methods that this content generator supports.
- */
- @Nullable
- public final String[] getSupportedMethods() {
- return (this.supportedMethods != null ? StringUtils.toStringArray(this.supportedMethods) : null);
- }
-
- private void initAllowHeader() {
- Collection<String> allowedMethods;
- if (this.supportedMethods == null) {
- allowedMethods = new ArrayList<>(HttpMethod.values().length - 1);
- for (HttpMethod method : HttpMethod.values()) {
- if (method != HttpMethod.TRACE) {
- allowedMethods.add(method.name());
- }
- }
- }
- else if (this.supportedMethods.contains(HttpMethod.OPTIONS.name())) {
- allowedMethods = this.supportedMethods;
- }
- else {
- allowedMethods = new ArrayList<>(this.supportedMethods);
- allowedMethods.add(HttpMethod.OPTIONS.name());
-
- }
- this.allowHeader = StringUtils.collectionToCommaDelimitedString(allowedMethods);
- }
-
- /**
- * Return the "Allow" header value to use in response to an HTTP OPTIONS request
- * based on the configured {@link #setSupportedMethods supported methods} also
- * automatically adding "OPTIONS" to the list even if not present as a supported
- * method. This means subclasses don't have to explicitly list "OPTIONS" as a
- * supported method as long as HTTP OPTIONS requests are handled before making a
- * call to {@link #checkRequest(HttpServletRequest)}.
- * @since 4.3
- */
- @Nullable
- protected String getAllowHeader() {
- return this.allowHeader;
- }
-
- /**
- * Set whether a session should be required to handle requests.
- */
- public final void setRequireSession(boolean requireSession) {
- this.requireSession = requireSession;
- }
-
- /**
- * Return whether a session is required to handle requests.
- */
- public final boolean isRequireSession() {
- return this.requireSession;
- }
-
- /**
- * Set the {@link org.springframework.http.CacheControl} instance to build
- * the Cache-Control HTTP response header.
- * @since 4.2
- */
- public final void setCacheControl(@Nullable CacheControl cacheControl) {
- this.cacheControl = cacheControl;
- }
-
- /**
- * Get the {@link org.springframework.http.CacheControl} instance
- * that builds the Cache-Control HTTP response header.
- * @since 4.2
- */
- @Nullable
- public final CacheControl getCacheControl() {
- return this.cacheControl;
- }
-
- /**
- * Cache content for the given number of seconds, by writing
- * cache-related HTTP headers to the response:
- * <ul>
- * <li>seconds == -1 (default value): no generation cache-related headers</li>
- * <li>seconds == 0: "Cache-Control: no-store" will prevent caching</li>
- * <li>seconds > 0: "Cache-Control: max-age=seconds" will ask to cache content</li>
- * </ul>
- * <p>For more specific needs, a custom {@link org.springframework.http.CacheControl}
- * should be used.
- * @see #setCacheControl
- */
- public final void setCacheSeconds(int seconds) {
- this.cacheSeconds = seconds;
- }
-
- /**
- * Return the number of seconds that content is cached.
- */
- public final int getCacheSeconds() {
- return this.cacheSeconds;
- }
-
- /**
- * Configure one or more request header names (e.g. "Accept-Language") to
- * add to the "Vary" response header to inform clients that the response is
- * subject to content negotiation and variances based on the value of the
- * given request headers. The configured request header names are added only
- * if not already present in the response "Vary" header.
- * @param varyByRequestHeaders one or more request header names
- * @since 4.3
- */
- public final void setVaryByRequestHeaders(@Nullable String... varyByRequestHeaders) {
- this.varyByRequestHeaders = varyByRequestHeaders;
- }
-
- /**
- * Return the configured request header names for the "Vary" response header.
- * @since 4.3
- */
- @Nullable
- public final String[] getVaryByRequestHeaders() {
- return this.varyByRequestHeaders;
- }
-
- /**
- * Set whether to use the HTTP 1.0 expires header. Default is "false",
- * as of 4.2.
- * <p>Note: Cache headers will only get applied if caching is enabled
- * (or explicitly prevented) for the current request.
- * @deprecated as of 4.2, since going forward, the HTTP 1.1 cache-control
- * header will be required, with the HTTP 1.0 headers disappearing
- */
- @Deprecated
- public final void setUseExpiresHeader(boolean useExpiresHeader) {
- this.useExpiresHeader = useExpiresHeader;
- }
-
- /**
- * Return whether the HTTP 1.0 expires header is used.
- * @deprecated as of 4.2, in favor of {@link #getCacheControl()}
- */
- @Deprecated
- public final boolean isUseExpiresHeader() {
- return this.useExpiresHeader;
- }
-
- /**
- * Set whether to use the HTTP 1.1 cache-control header. Default is "true".
- * <p>Note: Cache headers will only get applied if caching is enabled
- * (or explicitly prevented) for the current request.
- * @deprecated as of 4.2, since going forward, the HTTP 1.1 cache-control
- * header will be required, with the HTTP 1.0 headers disappearing
- */
- @Deprecated
- public final void setUseCacheControlHeader(boolean useCacheControlHeader) {
- this.useCacheControlHeader = useCacheControlHeader;
- }
-
- /**
- * Return whether the HTTP 1.1 cache-control header is used.
- * @deprecated as of 4.2, in favor of {@link #getCacheControl()}
- */
- @Deprecated
- public final boolean isUseCacheControlHeader() {
- return this.useCacheControlHeader;
- }
-
- /**
- * Set whether to use the HTTP 1.1 cache-control header value "no-store"
- * when preventing caching. Default is "true".
- * @deprecated as of 4.2, in favor of {@link #setCacheControl}
- */
- @Deprecated
- public final void setUseCacheControlNoStore(boolean useCacheControlNoStore) {
- this.useCacheControlNoStore = useCacheControlNoStore;
- }
-
- /**
- * Return whether the HTTP 1.1 cache-control header value "no-store" is used.
- * @deprecated as of 4.2, in favor of {@link #getCacheControl()}
- */
- @Deprecated
- public final boolean isUseCacheControlNoStore() {
- return this.useCacheControlNoStore;
- }
-
- /**
- * An option to add 'must-revalidate' to every Cache-Control header.
- * This may be useful with annotated controller methods, which can
- * programmatically do a last-modified calculation as described in
- * {@link org.springframework.web.context.request.WebRequest#checkNotModified(long)}.
- * <p>Default is "false".
- * @deprecated as of 4.2, in favor of {@link #setCacheControl}
- */
- @Deprecated
- public final void setAlwaysMustRevalidate(boolean mustRevalidate) {
- this.alwaysMustRevalidate = mustRevalidate;
- }
-
- /**
- * Return whether 'must-revalidate' is added to every Cache-Control header.
- * @deprecated as of 4.2, in favor of {@link #getCacheControl()}
- */
- @Deprecated
- public final boolean isAlwaysMustRevalidate() {
- return this.alwaysMustRevalidate;
- }
-
-
- /**
- * Check the given request for supported methods and a required session, if any.
- * @param request current HTTP request
- * @throws ServletException if the request cannot be handled because a check failed
- * @since 4.2
- */
- protected final void checkRequest(HttpServletRequest request) throws ServletException {
- // Check whether we should support the request method.
- String method = request.getMethod();
- if (this.supportedMethods != null && !this.supportedMethods.contains(method)) {
- throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods);
- }
-
- // Check whether a session is required.
- if (this.requireSession && request.getSession(false) == null) {
- throw new HttpSessionRequiredException("Pre-existing session required but none found");
- }
- }
-
- /**
- * Prepare the given response according to the settings of this generator.
- * Applies the number of cache seconds specified for this generator.
- * @param response current HTTP response
- * @since 4.2
- */
- protected final void prepareResponse(HttpServletResponse response) {
- if (this.cacheControl != null) {
- applyCacheControl(response, this.cacheControl);
- }
- else {
- applyCacheSeconds(response, this.cacheSeconds);
- }
- if (this.varyByRequestHeaders != null) {
- for (String value : getVaryRequestHeadersToAdd(response, this.varyByRequestHeaders)) {
- response.addHeader("Vary", value);
- }
- }
- }
-
- /**
- * Set the HTTP Cache-Control header according to the given settings.
- * @param response current HTTP response
- * @param cacheControl the pre-configured cache control settings
- * @since 4.2
- */
- protected final void applyCacheControl(HttpServletResponse response, CacheControl cacheControl) {
- String ccValue = cacheControl.getHeaderValue();
- if (ccValue != null) {
- // Set computed HTTP 1.1 Cache-Control header
- response.setHeader(HEADER_CACHE_CONTROL, ccValue);
-
- if (response.containsHeader(HEADER_PRAGMA)) {
- // Reset HTTP 1.0 Pragma header if present
- response.setHeader(HEADER_PRAGMA, "");
- }
- if (response.containsHeader(HEADER_EXPIRES)) {
- // Reset HTTP 1.0 Expires header if present
- response.setHeader(HEADER_EXPIRES, "");
- }
- }
- }
-
- /**
- * Apply the given cache seconds and generate corresponding HTTP headers,
- * i.e. allow caching for the given number of seconds in case of a positive
- * value, prevent caching if given a 0 value, do nothing else.
- * Does not tell the browser to revalidate the resource.
- * @param response current HTTP response
- * @param cacheSeconds positive number of seconds into the future that the
- * response should be cacheable for, 0 to prevent caching
- */
- @SuppressWarnings("deprecation")
- protected final void applyCacheSeconds(HttpServletResponse response, int cacheSeconds) {
- if (this.useExpiresHeader || !this.useCacheControlHeader) {
- // Deprecated HTTP 1.0 cache behavior, as in previous Spring versions
- if (cacheSeconds > 0) {
- cacheForSeconds(response, cacheSeconds);
- }
- else if (cacheSeconds == 0) {
- preventCaching(response);
- }
- }
- else {
- CacheControl cControl;
- if (cacheSeconds > 0) {
- cControl = CacheControl.maxAge(cacheSeconds, TimeUnit.SECONDS);
- if (this.alwaysMustRevalidate) {
- cControl = cControl.mustRevalidate();
- }
- }
- else if (cacheSeconds == 0) {
- cControl = (this.useCacheControlNoStore ? CacheControl.noStore() : CacheControl.noCache());
- }
- else {
- cControl = CacheControl.empty();
- }
- applyCacheControl(response, cControl);
- }
- }
-
-
- /**
- * @see #checkRequest(HttpServletRequest)
- * @see #prepareResponse(HttpServletResponse)
- * @deprecated as of 4.2, since the {@code lastModified} flag is effectively ignored,
- * with a must-revalidate header only generated if explicitly configured
- */
- @Deprecated
- protected final void checkAndPrepare(
- HttpServletRequest request, HttpServletResponse response, boolean lastModified) throws ServletException {
-
- checkRequest(request);
- prepareResponse(response);
- }
-
- /**
- * @see #checkRequest(HttpServletRequest)
- * @see #applyCacheSeconds(HttpServletResponse, int)
- * @deprecated as of 4.2, since the {@code lastModified} flag is effectively ignored,
- * with a must-revalidate header only generated if explicitly configured
- */
- @Deprecated
- protected final void checkAndPrepare(
- HttpServletRequest request, HttpServletResponse response, int cacheSeconds, boolean lastModified)
- throws ServletException {
-
- checkRequest(request);
- applyCacheSeconds(response, cacheSeconds);
- }
-
- /**
- * Apply the given cache seconds and generate respective HTTP headers.
- * <p>That is, allow caching for the given number of seconds in the
- * case of a positive value, prevent caching if given a 0 value, else
- * do nothing (i.e. leave caching to the client).
- * @param response the current HTTP response
- * @param cacheSeconds the (positive) number of seconds into the future
- * that the response should be cacheable for; 0 to prevent caching; and
- * a negative value to leave caching to the client.
- * @param mustRevalidate whether the client should revalidate the resource
- * (typically only necessary for controllers with last-modified support)
- * @deprecated as of 4.2, in favor of {@link #applyCacheControl}
- */
- @Deprecated
- protected final void applyCacheSeconds(HttpServletResponse response, int cacheSeconds, boolean mustRevalidate) {
- if (cacheSeconds > 0) {
- cacheForSeconds(response, cacheSeconds, mustRevalidate);
- }
- else if (cacheSeconds == 0) {
- preventCaching(response);
- }
- }
-
- /**
- * Set HTTP headers to allow caching for the given number of seconds.
- * Does not tell the browser to revalidate the resource.
- * @param response current HTTP response
- * @param seconds number of seconds into the future that the response
- * should be cacheable for
- * @deprecated as of 4.2, in favor of {@link #applyCacheControl}
- */
- @Deprecated
- protected final void cacheForSeconds(HttpServletResponse response, int seconds) {
- cacheForSeconds(response, seconds, false);
- }
-
- /**
- * Set HTTP headers to allow caching for the given number of seconds.
- * Tells the browser to revalidate the resource if mustRevalidate is
- * {@code true}.
- * @param response the current HTTP response
- * @param seconds number of seconds into the future that the response
- * should be cacheable for
- * @param mustRevalidate whether the client should revalidate the resource
- * (typically only necessary for controllers with last-modified support)
- * @deprecated as of 4.2, in favor of {@link #applyCacheControl}
- */
- @Deprecated
- protected final void cacheForSeconds(HttpServletResponse response, int seconds, boolean mustRevalidate) {
- if (this.useExpiresHeader) {
- // HTTP 1.0 header
- response.setDateHeader(HEADER_EXPIRES, System.currentTimeMillis() + seconds * 1000L);
- }
- else if (response.containsHeader(HEADER_EXPIRES)) {
- // Reset HTTP 1.0 Expires header if present
- response.setHeader(HEADER_EXPIRES, "");
- }
-
- if (this.useCacheControlHeader) {
- // HTTP 1.1 header
- String headerValue = "max-age=" + seconds;
- if (mustRevalidate || this.alwaysMustRevalidate) {
- headerValue += ", must-revalidate";
- }
- response.setHeader(HEADER_CACHE_CONTROL, headerValue);
- }
-
- if (response.containsHeader(HEADER_PRAGMA)) {
- // Reset HTTP 1.0 Pragma header if present
- response.setHeader(HEADER_PRAGMA, "");
- }
- }
-
- /**
- * Prevent the response from being cached.
- * Only called in HTTP 1.0 compatibility mode.
- * <p>See {@code http://www.mnot.net/cache_docs}.
- * @deprecated as of 4.2, in favor of {@link #applyCacheControl}
- */
- @Deprecated
- protected final void preventCaching(HttpServletResponse response) {
- response.setHeader(HEADER_PRAGMA, "no-cache");
-
- if (this.useExpiresHeader) {
- // HTTP 1.0 Expires header
- response.setDateHeader(HEADER_EXPIRES, 1L);
- }
-
- if (this.useCacheControlHeader) {
- // HTTP 1.1 Cache-Control header: "no-cache" is the standard value,
- // "no-store" is necessary to prevent caching on Firefox.
- response.setHeader(HEADER_CACHE_CONTROL, "no-cache");
- if (this.useCacheControlNoStore) {
- response.addHeader(HEADER_CACHE_CONTROL, "no-store");
- }
- }
- }
-
-
- private Collection<String> getVaryRequestHeadersToAdd(HttpServletResponse response, String[] varyByRequestHeaders) {
- if (!response.containsHeader(HttpHeaders.VARY)) {
- return Arrays.asList(varyByRequestHeaders);
- }
- Collection<String> result = new ArrayList<>(varyByRequestHeaders.length);
- Collections.addAll(result, varyByRequestHeaders);
- for (String header : response.getHeaders(HttpHeaders.VARY)) {
- for (String existing : StringUtils.tokenizeToStringArray(header, ",")) {
- if ("*".equals(existing)) {
- return Collections.emptyList();
- }
- for (String value : varyByRequestHeaders) {
- if (value.equalsIgnoreCase(existing)) {
- result.remove(value);
- }
- }
- }
- }
- return result;
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。