当前位置:   article > 正文

SpringMVC 3:Controller接口及其实现类_spring interface 调用接口 controller

spring interface 调用接口 controller

※. Controller接口及其实现类

    Controller是控制器接口,此处只有一个方法handleRequest,
用于进行请求的功能处理,处理完请求后返回ModelAndView(Model模型数据部分 和 View视图部分)。
    
    如果想直接在处理器/控制器里使用response向客户端写回数据,
    可以通过返回null来告诉DispatcherServlet我们已经写出响应了,
    不需要它进行视图解析

  1. 例:
  2. package com.briup.web.controller;
  3. import java.io.PrintWriter;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import org.springframework.web.servlet.ModelAndView;
  7. import org.springframework.web.servlet.mvc.Controller;
  8. public class SecondController
  9. implements Controller{
  10. @Override
  11. public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
  12. // PrintWriter pw=
  13. // response.getWriter();
  14. // pw.println("test...ok");
  15. // pw.flush();
  16. //request.getSession(false);
  17. //false:有session返回session对象,没有session返回null
  18. //true:有session返回session对象,没有session对象创建session
  19. request.getSession();
  20. //可以服务器内部页面跳转,不能重定向
  21. //因为浏览器拿不到WEB-INF下的jsp文件
  22. request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp")
  23. .forward(request, response);
  24. //返回null 前端控制器不会调用
  25. //视图解析器处理
  26. return null;
  27. }
  28. }
  29. 2.spring.xml配置
  30. <bean name="/second"
  31. class="com.briup.web.controller.SecondController"></bean>

    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类的配置。


    提供了【可选】的会话的串行化访问功能,例如:
  

  1. //即同一会话,线程同步
  2. public class HelloWorldController extends AbstractController{
  3. @Override
  4. protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
  5. throws Exception {
  6. String name = request.getParameter("name");
  7. //ModelAndView对象中包括了要返回的逻辑视图,以及数据模型
  8. ModelAndView mv = new ModelAndView();
  9. //设置视图名称,可以是字符串 也可以是视图对象
  10. mv.setViewName("hello");
  11. //设置数据模型
  12. mv.addObject("name", name);
  13. return mv;
  14. }
  15. }
  16. <!--synchronizeOnSession,统一浏览器访问串行-->
  17. <bean name="/hello" class="com.briup.web.controller.HelloWorldController">
  18. <property name="synchronizeOnSession" value="test"></property>
  19. </bean>
  20. 直接通过response写响应,例如:
  21. public class HelloWorldController extends AbstractController{
  22. @Override
  23. protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
  24. throws Exception {
  25. response.getWriter().write("Hello World!!");
  26. //如果想直接在该处理器/控制器写响应 可以通过返回null告诉DispatcherServlet自己已经写出响应了,不需要它进行视图解析
  27. return null;
  28. }
  29. }


    
    强制请求方法类型,例如:
  

  1. //只支持post和get方法
  2. <bean name="/hello" class="com.briup.web.controller.HelloWorldController">
  3. <property name="supportedMethods" value="POST,GET"></property>
  4. </bean>
  5. 当前请求的session前置条件检查,如果当前请求无session将抛出HttpSessionRequiredException异常,例如:
  6. //在进入该控制器时,一定要有session存在,否则抛出HttpSessionRequiredException异常。
  7. <bean name="/hello" class="com.briup.web.controller.HelloWorldController">
  8. <property name="requireSession" value="true"/>
  9. </bean>

 ThirdController类:

  1. 例:避免重复刷新造成线程不安全
  2. package com.briup.web.controller;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import org.springframework.web.servlet.ModelAndView;
  6. import org.springframework.web.servlet.mvc.AbstractController;
  7. /*
  8. * 实现特定的功能用特定类
  9. *
  10. *同一个个浏览器。发出多个请求
  11. *请求相同的资源的时候,会话级别的
  12. *对访问的资源加锁
  13. *注意:浏览器每次发出一个请求服务器
  14. *都会启动一个线程去处理(多次请求
  15. *用同一个线程,也可能多个请求用的
  16. *不同的线程)
  17. */
  18. public class ThirdController
  19. extends AbstractController{
  20. @Override
  21. protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
  22. throws Exception {
  23. ModelAndView mv=
  24. new ModelAndView();
  25. mv.setViewName("hello");
  26. return mv;
  27. }
  28. }
  29. spring.xml配置:
  30. <bean name="/third"
  31. class="com.briup.web.controller.ThirdController">
  32. <!-- <property name="synchronizeOnSession"
  33. value="true"></property> -->
  34. <!--本次请求支持提交的方式 WebControllerGenerator类中supportedMethods属性 -->
  35. <!--value中没有请求提交的方式会报405错误-->
  36. <!-- <property name="supportedMethods" value="POST,GET">
  37. </property> -->
  38. <!-- 本次请求,服务器必须给当前浏览器
  39. 构建过session 会话,没有session直接报错
  40. -->
  41. <!-- <property name="requireSession"
  42. value="true"></property> -->
  43. <!-- (-1)表示默认,缓存上次的内容
  44. 0 表示直接不缓存
  45. 正数,表示缓存,缓存时间的设置
  46. -->
  47. <property name="cacheSeconds" value="0"></property>
  48. </bean>
  1. 注:Controller抽象类Spring给了很多,方法很多,扩展性很强。
  2. AbstractController类
  3. /*
  4. * Copyright 2002-2016 the original author or authors.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.springframework.web.servlet.mvc;
  19. import javax.servlet.http.HttpServletRequest;
  20. import javax.servlet.http.HttpServletResponse;
  21. import javax.servlet.http.HttpSession;
  22. import org.springframework.http.HttpMethod;
  23. import org.springframework.lang.Nullable;
  24. import org.springframework.web.servlet.ModelAndView;
  25. import org.springframework.web.servlet.support.WebContentGenerator;
  26. import org.springframework.web.util.WebUtils;
  27. /**
  28. * Convenient superclass for controller implementations, using the Template Method
  29. * design pattern.
  30. *
  31. * <p><b><a name="workflow">Workflow
  32. * (<a href="Controller.html#workflow">and that defined by interface</a>):</b><br>
  33. * <ol>
  34. * <li>{@link #handleRequest(HttpServletRequest, HttpServletResponse) handleRequest()}
  35. * will be called by the DispatcherServlet</li>
  36. * <li>Inspection of supported methods (ServletException if request method
  37. * is not support)</li>
  38. * <li>If session is required, try to get it (ServletException if not found)</li>
  39. * <li>Set caching headers if needed according to the cacheSeconds property</li>
  40. * <li>Call abstract method
  41. * {@link #handleRequestInternal(HttpServletRequest, HttpServletResponse) handleRequestInternal()}
  42. * (optionally synchronizing around the call on the HttpSession),
  43. * which should be implemented by extending classes to provide actual
  44. * functionality to return {@link org.springframework.web.servlet.ModelAndView ModelAndView} objects.</li>
  45. * </ol>
  46. *
  47. * <p><b><a name="config">Exposed configuration properties</a>
  48. * (<a href="Controller.html#config">and those defined by interface</a>):</b><br>
  49. * <table border="1">
  50. * <tr>
  51. * <td><b>name</b></th>
  52. * <td><b>default</b></td>
  53. * <td><b>description</b></td>
  54. * </tr>
  55. * <tr>
  56. * <td>supportedMethods</td>
  57. * <td>GET,POST</td>
  58. * <td>comma-separated (CSV) list of methods supported by this controller,
  59. * such as GET, POST and PUT</td>
  60. * </tr>
  61. * <tr>
  62. * <td>requireSession</td>
  63. * <td>false</td>
  64. * <td>whether a session should be required for requests to be able to
  65. * be handled by this controller. This ensures that derived controller
  66. * can - without fear of null pointers - call request.getSession() to
  67. * retrieve a session. If no session can be found while processing
  68. * the request, a ServletException will be thrown</td>
  69. * </tr>
  70. * <tr>
  71. * <td>cacheSeconds</td>
  72. * <td>-1</td>
  73. * <td>indicates the amount of seconds to include in the cache header
  74. * for the response following on this request. 0 (zero) will include
  75. * headers for no caching at all, -1 (the default) will not generate
  76. * <i>any headers</i> and any positive number will generate headers
  77. * that state the amount indicated as seconds to cache the content</td>
  78. * </tr>
  79. * <tr>
  80. * <td>synchronizeOnSession</td>
  81. * <td>false</td>
  82. * <td>whether the call to {@code handleRequestInternal} should be
  83. * synchronized around the HttpSession, to serialize invocations
  84. * from the same client. No effect if there is no HttpSession.
  85. * </td>
  86. * </tr>
  87. * </table>
  88. *
  89. * @author Rod Johnson
  90. * @author Juergen Hoeller
  91. * @author Rossen Stoyanchev
  92. * @see WebContentInterceptor
  93. */
  94. public abstract class AbstractController extends WebContentGenerator implements Controller {
  95. private boolean synchronizeOnSession = false;
  96. /**
  97. * Create a new AbstractController which supports
  98. * HTTP methods GET, HEAD and POST by default.
  99. */
  100. public AbstractController() {
  101. this(true);
  102. }
  103. /**
  104. * Create a new AbstractController.
  105. * @param restrictDefaultSupportedMethods {@code true} if this
  106. * controller should support HTTP methods GET, HEAD and POST by default,
  107. * or {@code false} if it should be unrestricted
  108. * @since 4.3
  109. */
  110. public AbstractController(boolean restrictDefaultSupportedMethods) {
  111. super(restrictDefaultSupportedMethods);
  112. }
  113. /**
  114. * Set if controller execution should be synchronized on the session,
  115. * to serialize parallel invocations from the same client.
  116. * <p>More specifically, the execution of the {@code handleRequestInternal}
  117. * method will get synchronized if this flag is "true". The best available
  118. * session mutex will be used for the synchronization; ideally, this will
  119. * be a mutex exposed by HttpSessionMutexListener.
  120. * <p>The session mutex is guaranteed to be the same object during
  121. * the entire lifetime of the session, available under the key defined
  122. * by the {@code SESSION_MUTEX_ATTRIBUTE} constant. It serves as a
  123. * safe reference to synchronize on for locking on the current session.
  124. * <p>In many cases, the HttpSession reference itself is a safe mutex
  125. * as well, since it will always be the same object reference for the
  126. * same active logical session. However, this is not guaranteed across
  127. * different servlet containers; the only 100% safe way is a session mutex.
  128. * @see AbstractController#handleRequestInternal
  129. * @see org.springframework.web.util.HttpSessionMutexListener
  130. * @see org.springframework.web.util.WebUtils#getSessionMutex(javax.servlet.http.HttpSession)
  131. */
  132. public final void setSynchronizeOnSession(boolean synchronizeOnSession) {
  133. this.synchronizeOnSession = synchronizeOnSession;
  134. }
  135. /**
  136. * Return whether controller execution should be synchronized on the session.
  137. */
  138. public final boolean isSynchronizeOnSession() {
  139. return this.synchronizeOnSession;
  140. }
  141. @Override
  142. @Nullable
  143. public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
  144. throws Exception {
  145. if (HttpMethod.OPTIONS.matches(request.getMethod())) {
  146. response.setHeader("Allow", getAllowHeader());
  147. return null;
  148. }
  149. // Delegate to WebContentGenerator for checking and preparing.
  150. checkRequest(request);
  151. prepareResponse(response);
  152. // Execute handleRequestInternal in synchronized block if required.
  153. if (this.synchronizeOnSession) {
  154. HttpSession session = request.getSession(false);
  155. if (session != null) {
  156. Object mutex = WebUtils.getSessionMutex(session);
  157. synchronized (mutex) {
  158. return handleRequestInternal(request, response);
  159. }
  160. }
  161. }
  162. return handleRequestInternal(request, response);
  163. }
  164. /**
  165. * Template method. Subclasses must implement this.
  166. * The contract is the same as for {@code handleRequest}.
  167. * @see #handleRequest
  168. */
  169. @Nullable
  170. protected abstract ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
  171. throws Exception;
  172. }
  173. WebContentGenerator类
  174. /*
  175. * Copyright 2002-2018 the original author or authors.
  176. *
  177. * Licensed under the Apache License, Version 2.0 (the "License");
  178. * you may not use this file except in compliance with the License.
  179. * You may obtain a copy of the License at
  180. *
  181. * http://www.apache.org/licenses/LICENSE-2.0
  182. *
  183. * Unless required by applicable law or agreed to in writing, software
  184. * distributed under the License is distributed on an "AS IS" BASIS,
  185. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  186. * See the License for the specific language governing permissions and
  187. * limitations under the License.
  188. */
  189. package org.springframework.web.servlet.support;
  190. import java.util.ArrayList;
  191. import java.util.Arrays;
  192. import java.util.Collection;
  193. import java.util.Collections;
  194. import java.util.LinkedHashSet;
  195. import java.util.Set;
  196. import java.util.concurrent.TimeUnit;
  197. import javax.servlet.ServletException;
  198. import javax.servlet.http.HttpServletRequest;
  199. import javax.servlet.http.HttpServletResponse;
  200. import org.springframework.http.CacheControl;
  201. import org.springframework.http.HttpHeaders;
  202. import org.springframework.http.HttpMethod;
  203. import org.springframework.lang.Nullable;
  204. import org.springframework.util.ObjectUtils;
  205. import org.springframework.util.StringUtils;
  206. import org.springframework.web.HttpRequestMethodNotSupportedException;
  207. import org.springframework.web.HttpSessionRequiredException;
  208. import org.springframework.web.context.support.WebApplicationObjectSupport;
  209. /**
  210. * Convenient superclass for any kind of web content generator,
  211. * like {@link org.springframework.web.servlet.mvc.AbstractController}
  212. * and {@link org.springframework.web.servlet.mvc.WebContentInterceptor}.
  213. * Can also be used for custom handlers that have their own
  214. * {@link org.springframework.web.servlet.HandlerAdapter}.
  215. *
  216. * <p>Supports HTTP cache control options. The usage of corresponding HTTP
  217. * headers can be controlled via the {@link #setCacheSeconds "cacheSeconds"}
  218. * and {@link #setCacheControl "cacheControl"} properties.
  219. *
  220. * <p><b>NOTE:</b> As of Spring 4.2, this generator's default behavior changed when
  221. * using only {@link #setCacheSeconds}, sending HTTP response headers that are in line
  222. * with current browsers and proxies implementations (i.e. no HTTP 1.0 headers anymore)
  223. * Reverting to the previous behavior can be easily done by using one of the newly
  224. * deprecated methods {@link #setUseExpiresHeader}, {@link #setUseCacheControlHeader},
  225. * {@link #setUseCacheControlNoStore} or {@link #setAlwaysMustRevalidate}.
  226. *
  227. * @author Rod Johnson
  228. * @author Juergen Hoeller
  229. * @author Brian Clozel
  230. * @author Rossen Stoyanchev
  231. * @see #setCacheSeconds
  232. * @see #setCacheControl
  233. * @see #setRequireSession
  234. */
  235. public abstract class WebContentGenerator extends WebApplicationObjectSupport {
  236. /** HTTP method "GET" */
  237. public static final String METHOD_GET = "GET";
  238. /** HTTP method "HEAD" */
  239. public static final String METHOD_HEAD = "HEAD";
  240. /** HTTP method "POST" */
  241. public static final String METHOD_POST = "POST";
  242. private static final String HEADER_PRAGMA = "Pragma";
  243. private static final String HEADER_EXPIRES = "Expires";
  244. protected static final String HEADER_CACHE_CONTROL = "Cache-Control";
  245. /** Set of supported HTTP methods */
  246. @Nullable
  247. private Set<String> supportedMethods;
  248. @Nullable
  249. private String allowHeader;
  250. private boolean requireSession = false;
  251. @Nullable
  252. private CacheControl cacheControl;
  253. private int cacheSeconds = -1;
  254. @Nullable
  255. private String[] varyByRequestHeaders;
  256. // deprecated fields
  257. /** Use HTTP 1.0 expires header? */
  258. private boolean useExpiresHeader = false;
  259. /** Use HTTP 1.1 cache-control header? */
  260. private boolean useCacheControlHeader = true;
  261. /** Use HTTP 1.1 cache-control header value "no-store"? */
  262. private boolean useCacheControlNoStore = true;
  263. private boolean alwaysMustRevalidate = false;
  264. /**
  265. * Create a new WebContentGenerator which supports
  266. * HTTP methods GET, HEAD and POST by default.
  267. */
  268. public WebContentGenerator() {
  269. this(true);
  270. }
  271. /**
  272. * Create a new WebContentGenerator.
  273. * @param restrictDefaultSupportedMethods {@code true} if this
  274. * generator should support HTTP methods GET, HEAD and POST by default,
  275. * or {@code false} if it should be unrestricted
  276. */
  277. public WebContentGenerator(boolean restrictDefaultSupportedMethods) {
  278. if (restrictDefaultSupportedMethods) {
  279. this.supportedMethods = new LinkedHashSet<>(4);
  280. this.supportedMethods.add(METHOD_GET);
  281. this.supportedMethods.add(METHOD_HEAD);
  282. this.supportedMethods.add(METHOD_POST);
  283. }
  284. initAllowHeader();
  285. }
  286. /**
  287. * Create a new WebContentGenerator.
  288. * @param supportedMethods the supported HTTP methods for this content generator
  289. */
  290. public WebContentGenerator(String... supportedMethods) {
  291. setSupportedMethods(supportedMethods);
  292. }
  293. /**
  294. * Set the HTTP methods that this content generator should support.
  295. * <p>Default is GET, HEAD and POST for simple form controller types;
  296. * unrestricted for general controllers and interceptors.
  297. */
  298. public final void setSupportedMethods(@Nullable String... methods) {
  299. if (!ObjectUtils.isEmpty(methods)) {
  300. this.supportedMethods = new LinkedHashSet<>(Arrays.asList(methods));
  301. }
  302. else {
  303. this.supportedMethods = null;
  304. }
  305. initAllowHeader();
  306. }
  307. /**
  308. * Return the HTTP methods that this content generator supports.
  309. */
  310. @Nullable
  311. public final String[] getSupportedMethods() {
  312. return (this.supportedMethods != null ? StringUtils.toStringArray(this.supportedMethods) : null);
  313. }
  314. private void initAllowHeader() {
  315. Collection<String> allowedMethods;
  316. if (this.supportedMethods == null) {
  317. allowedMethods = new ArrayList<>(HttpMethod.values().length - 1);
  318. for (HttpMethod method : HttpMethod.values()) {
  319. if (method != HttpMethod.TRACE) {
  320. allowedMethods.add(method.name());
  321. }
  322. }
  323. }
  324. else if (this.supportedMethods.contains(HttpMethod.OPTIONS.name())) {
  325. allowedMethods = this.supportedMethods;
  326. }
  327. else {
  328. allowedMethods = new ArrayList<>(this.supportedMethods);
  329. allowedMethods.add(HttpMethod.OPTIONS.name());
  330. }
  331. this.allowHeader = StringUtils.collectionToCommaDelimitedString(allowedMethods);
  332. }
  333. /**
  334. * Return the "Allow" header value to use in response to an HTTP OPTIONS request
  335. * based on the configured {@link #setSupportedMethods supported methods} also
  336. * automatically adding "OPTIONS" to the list even if not present as a supported
  337. * method. This means subclasses don't have to explicitly list "OPTIONS" as a
  338. * supported method as long as HTTP OPTIONS requests are handled before making a
  339. * call to {@link #checkRequest(HttpServletRequest)}.
  340. * @since 4.3
  341. */
  342. @Nullable
  343. protected String getAllowHeader() {
  344. return this.allowHeader;
  345. }
  346. /**
  347. * Set whether a session should be required to handle requests.
  348. */
  349. public final void setRequireSession(boolean requireSession) {
  350. this.requireSession = requireSession;
  351. }
  352. /**
  353. * Return whether a session is required to handle requests.
  354. */
  355. public final boolean isRequireSession() {
  356. return this.requireSession;
  357. }
  358. /**
  359. * Set the {@link org.springframework.http.CacheControl} instance to build
  360. * the Cache-Control HTTP response header.
  361. * @since 4.2
  362. */
  363. public final void setCacheControl(@Nullable CacheControl cacheControl) {
  364. this.cacheControl = cacheControl;
  365. }
  366. /**
  367. * Get the {@link org.springframework.http.CacheControl} instance
  368. * that builds the Cache-Control HTTP response header.
  369. * @since 4.2
  370. */
  371. @Nullable
  372. public final CacheControl getCacheControl() {
  373. return this.cacheControl;
  374. }
  375. /**
  376. * Cache content for the given number of seconds, by writing
  377. * cache-related HTTP headers to the response:
  378. * <ul>
  379. * <li>seconds == -1 (default value): no generation cache-related headers</li>
  380. * <li>seconds == 0: "Cache-Control: no-store" will prevent caching</li>
  381. * <li>seconds > 0: "Cache-Control: max-age=seconds" will ask to cache content</li>
  382. * </ul>
  383. * <p>For more specific needs, a custom {@link org.springframework.http.CacheControl}
  384. * should be used.
  385. * @see #setCacheControl
  386. */
  387. public final void setCacheSeconds(int seconds) {
  388. this.cacheSeconds = seconds;
  389. }
  390. /**
  391. * Return the number of seconds that content is cached.
  392. */
  393. public final int getCacheSeconds() {
  394. return this.cacheSeconds;
  395. }
  396. /**
  397. * Configure one or more request header names (e.g. "Accept-Language") to
  398. * add to the "Vary" response header to inform clients that the response is
  399. * subject to content negotiation and variances based on the value of the
  400. * given request headers. The configured request header names are added only
  401. * if not already present in the response "Vary" header.
  402. * @param varyByRequestHeaders one or more request header names
  403. * @since 4.3
  404. */
  405. public final void setVaryByRequestHeaders(@Nullable String... varyByRequestHeaders) {
  406. this.varyByRequestHeaders = varyByRequestHeaders;
  407. }
  408. /**
  409. * Return the configured request header names for the "Vary" response header.
  410. * @since 4.3
  411. */
  412. @Nullable
  413. public final String[] getVaryByRequestHeaders() {
  414. return this.varyByRequestHeaders;
  415. }
  416. /**
  417. * Set whether to use the HTTP 1.0 expires header. Default is "false",
  418. * as of 4.2.
  419. * <p>Note: Cache headers will only get applied if caching is enabled
  420. * (or explicitly prevented) for the current request.
  421. * @deprecated as of 4.2, since going forward, the HTTP 1.1 cache-control
  422. * header will be required, with the HTTP 1.0 headers disappearing
  423. */
  424. @Deprecated
  425. public final void setUseExpiresHeader(boolean useExpiresHeader) {
  426. this.useExpiresHeader = useExpiresHeader;
  427. }
  428. /**
  429. * Return whether the HTTP 1.0 expires header is used.
  430. * @deprecated as of 4.2, in favor of {@link #getCacheControl()}
  431. */
  432. @Deprecated
  433. public final boolean isUseExpiresHeader() {
  434. return this.useExpiresHeader;
  435. }
  436. /**
  437. * Set whether to use the HTTP 1.1 cache-control header. Default is "true".
  438. * <p>Note: Cache headers will only get applied if caching is enabled
  439. * (or explicitly prevented) for the current request.
  440. * @deprecated as of 4.2, since going forward, the HTTP 1.1 cache-control
  441. * header will be required, with the HTTP 1.0 headers disappearing
  442. */
  443. @Deprecated
  444. public final void setUseCacheControlHeader(boolean useCacheControlHeader) {
  445. this.useCacheControlHeader = useCacheControlHeader;
  446. }
  447. /**
  448. * Return whether the HTTP 1.1 cache-control header is used.
  449. * @deprecated as of 4.2, in favor of {@link #getCacheControl()}
  450. */
  451. @Deprecated
  452. public final boolean isUseCacheControlHeader() {
  453. return this.useCacheControlHeader;
  454. }
  455. /**
  456. * Set whether to use the HTTP 1.1 cache-control header value "no-store"
  457. * when preventing caching. Default is "true".
  458. * @deprecated as of 4.2, in favor of {@link #setCacheControl}
  459. */
  460. @Deprecated
  461. public final void setUseCacheControlNoStore(boolean useCacheControlNoStore) {
  462. this.useCacheControlNoStore = useCacheControlNoStore;
  463. }
  464. /**
  465. * Return whether the HTTP 1.1 cache-control header value "no-store" is used.
  466. * @deprecated as of 4.2, in favor of {@link #getCacheControl()}
  467. */
  468. @Deprecated
  469. public final boolean isUseCacheControlNoStore() {
  470. return this.useCacheControlNoStore;
  471. }
  472. /**
  473. * An option to add 'must-revalidate' to every Cache-Control header.
  474. * This may be useful with annotated controller methods, which can
  475. * programmatically do a last-modified calculation as described in
  476. * {@link org.springframework.web.context.request.WebRequest#checkNotModified(long)}.
  477. * <p>Default is "false".
  478. * @deprecated as of 4.2, in favor of {@link #setCacheControl}
  479. */
  480. @Deprecated
  481. public final void setAlwaysMustRevalidate(boolean mustRevalidate) {
  482. this.alwaysMustRevalidate = mustRevalidate;
  483. }
  484. /**
  485. * Return whether 'must-revalidate' is added to every Cache-Control header.
  486. * @deprecated as of 4.2, in favor of {@link #getCacheControl()}
  487. */
  488. @Deprecated
  489. public final boolean isAlwaysMustRevalidate() {
  490. return this.alwaysMustRevalidate;
  491. }
  492. /**
  493. * Check the given request for supported methods and a required session, if any.
  494. * @param request current HTTP request
  495. * @throws ServletException if the request cannot be handled because a check failed
  496. * @since 4.2
  497. */
  498. protected final void checkRequest(HttpServletRequest request) throws ServletException {
  499. // Check whether we should support the request method.
  500. String method = request.getMethod();
  501. if (this.supportedMethods != null && !this.supportedMethods.contains(method)) {
  502. throw new HttpRequestMethodNotSupportedException(method, this.supportedMethods);
  503. }
  504. // Check whether a session is required.
  505. if (this.requireSession && request.getSession(false) == null) {
  506. throw new HttpSessionRequiredException("Pre-existing session required but none found");
  507. }
  508. }
  509. /**
  510. * Prepare the given response according to the settings of this generator.
  511. * Applies the number of cache seconds specified for this generator.
  512. * @param response current HTTP response
  513. * @since 4.2
  514. */
  515. protected final void prepareResponse(HttpServletResponse response) {
  516. if (this.cacheControl != null) {
  517. applyCacheControl(response, this.cacheControl);
  518. }
  519. else {
  520. applyCacheSeconds(response, this.cacheSeconds);
  521. }
  522. if (this.varyByRequestHeaders != null) {
  523. for (String value : getVaryRequestHeadersToAdd(response, this.varyByRequestHeaders)) {
  524. response.addHeader("Vary", value);
  525. }
  526. }
  527. }
  528. /**
  529. * Set the HTTP Cache-Control header according to the given settings.
  530. * @param response current HTTP response
  531. * @param cacheControl the pre-configured cache control settings
  532. * @since 4.2
  533. */
  534. protected final void applyCacheControl(HttpServletResponse response, CacheControl cacheControl) {
  535. String ccValue = cacheControl.getHeaderValue();
  536. if (ccValue != null) {
  537. // Set computed HTTP 1.1 Cache-Control header
  538. response.setHeader(HEADER_CACHE_CONTROL, ccValue);
  539. if (response.containsHeader(HEADER_PRAGMA)) {
  540. // Reset HTTP 1.0 Pragma header if present
  541. response.setHeader(HEADER_PRAGMA, "");
  542. }
  543. if (response.containsHeader(HEADER_EXPIRES)) {
  544. // Reset HTTP 1.0 Expires header if present
  545. response.setHeader(HEADER_EXPIRES, "");
  546. }
  547. }
  548. }
  549. /**
  550. * Apply the given cache seconds and generate corresponding HTTP headers,
  551. * i.e. allow caching for the given number of seconds in case of a positive
  552. * value, prevent caching if given a 0 value, do nothing else.
  553. * Does not tell the browser to revalidate the resource.
  554. * @param response current HTTP response
  555. * @param cacheSeconds positive number of seconds into the future that the
  556. * response should be cacheable for, 0 to prevent caching
  557. */
  558. @SuppressWarnings("deprecation")
  559. protected final void applyCacheSeconds(HttpServletResponse response, int cacheSeconds) {
  560. if (this.useExpiresHeader || !this.useCacheControlHeader) {
  561. // Deprecated HTTP 1.0 cache behavior, as in previous Spring versions
  562. if (cacheSeconds > 0) {
  563. cacheForSeconds(response, cacheSeconds);
  564. }
  565. else if (cacheSeconds == 0) {
  566. preventCaching(response);
  567. }
  568. }
  569. else {
  570. CacheControl cControl;
  571. if (cacheSeconds > 0) {
  572. cControl = CacheControl.maxAge(cacheSeconds, TimeUnit.SECONDS);
  573. if (this.alwaysMustRevalidate) {
  574. cControl = cControl.mustRevalidate();
  575. }
  576. }
  577. else if (cacheSeconds == 0) {
  578. cControl = (this.useCacheControlNoStore ? CacheControl.noStore() : CacheControl.noCache());
  579. }
  580. else {
  581. cControl = CacheControl.empty();
  582. }
  583. applyCacheControl(response, cControl);
  584. }
  585. }
  586. /**
  587. * @see #checkRequest(HttpServletRequest)
  588. * @see #prepareResponse(HttpServletResponse)
  589. * @deprecated as of 4.2, since the {@code lastModified} flag is effectively ignored,
  590. * with a must-revalidate header only generated if explicitly configured
  591. */
  592. @Deprecated
  593. protected final void checkAndPrepare(
  594. HttpServletRequest request, HttpServletResponse response, boolean lastModified) throws ServletException {
  595. checkRequest(request);
  596. prepareResponse(response);
  597. }
  598. /**
  599. * @see #checkRequest(HttpServletRequest)
  600. * @see #applyCacheSeconds(HttpServletResponse, int)
  601. * @deprecated as of 4.2, since the {@code lastModified} flag is effectively ignored,
  602. * with a must-revalidate header only generated if explicitly configured
  603. */
  604. @Deprecated
  605. protected final void checkAndPrepare(
  606. HttpServletRequest request, HttpServletResponse response, int cacheSeconds, boolean lastModified)
  607. throws ServletException {
  608. checkRequest(request);
  609. applyCacheSeconds(response, cacheSeconds);
  610. }
  611. /**
  612. * Apply the given cache seconds and generate respective HTTP headers.
  613. * <p>That is, allow caching for the given number of seconds in the
  614. * case of a positive value, prevent caching if given a 0 value, else
  615. * do nothing (i.e. leave caching to the client).
  616. * @param response the current HTTP response
  617. * @param cacheSeconds the (positive) number of seconds into the future
  618. * that the response should be cacheable for; 0 to prevent caching; and
  619. * a negative value to leave caching to the client.
  620. * @param mustRevalidate whether the client should revalidate the resource
  621. * (typically only necessary for controllers with last-modified support)
  622. * @deprecated as of 4.2, in favor of {@link #applyCacheControl}
  623. */
  624. @Deprecated
  625. protected final void applyCacheSeconds(HttpServletResponse response, int cacheSeconds, boolean mustRevalidate) {
  626. if (cacheSeconds > 0) {
  627. cacheForSeconds(response, cacheSeconds, mustRevalidate);
  628. }
  629. else if (cacheSeconds == 0) {
  630. preventCaching(response);
  631. }
  632. }
  633. /**
  634. * Set HTTP headers to allow caching for the given number of seconds.
  635. * Does not tell the browser to revalidate the resource.
  636. * @param response current HTTP response
  637. * @param seconds number of seconds into the future that the response
  638. * should be cacheable for
  639. * @deprecated as of 4.2, in favor of {@link #applyCacheControl}
  640. */
  641. @Deprecated
  642. protected final void cacheForSeconds(HttpServletResponse response, int seconds) {
  643. cacheForSeconds(response, seconds, false);
  644. }
  645. /**
  646. * Set HTTP headers to allow caching for the given number of seconds.
  647. * Tells the browser to revalidate the resource if mustRevalidate is
  648. * {@code true}.
  649. * @param response the current HTTP response
  650. * @param seconds number of seconds into the future that the response
  651. * should be cacheable for
  652. * @param mustRevalidate whether the client should revalidate the resource
  653. * (typically only necessary for controllers with last-modified support)
  654. * @deprecated as of 4.2, in favor of {@link #applyCacheControl}
  655. */
  656. @Deprecated
  657. protected final void cacheForSeconds(HttpServletResponse response, int seconds, boolean mustRevalidate) {
  658. if (this.useExpiresHeader) {
  659. // HTTP 1.0 header
  660. response.setDateHeader(HEADER_EXPIRES, System.currentTimeMillis() + seconds * 1000L);
  661. }
  662. else if (response.containsHeader(HEADER_EXPIRES)) {
  663. // Reset HTTP 1.0 Expires header if present
  664. response.setHeader(HEADER_EXPIRES, "");
  665. }
  666. if (this.useCacheControlHeader) {
  667. // HTTP 1.1 header
  668. String headerValue = "max-age=" + seconds;
  669. if (mustRevalidate || this.alwaysMustRevalidate) {
  670. headerValue += ", must-revalidate";
  671. }
  672. response.setHeader(HEADER_CACHE_CONTROL, headerValue);
  673. }
  674. if (response.containsHeader(HEADER_PRAGMA)) {
  675. // Reset HTTP 1.0 Pragma header if present
  676. response.setHeader(HEADER_PRAGMA, "");
  677. }
  678. }
  679. /**
  680. * Prevent the response from being cached.
  681. * Only called in HTTP 1.0 compatibility mode.
  682. * <p>See {@code http://www.mnot.net/cache_docs}.
  683. * @deprecated as of 4.2, in favor of {@link #applyCacheControl}
  684. */
  685. @Deprecated
  686. protected final void preventCaching(HttpServletResponse response) {
  687. response.setHeader(HEADER_PRAGMA, "no-cache");
  688. if (this.useExpiresHeader) {
  689. // HTTP 1.0 Expires header
  690. response.setDateHeader(HEADER_EXPIRES, 1L);
  691. }
  692. if (this.useCacheControlHeader) {
  693. // HTTP 1.1 Cache-Control header: "no-cache" is the standard value,
  694. // "no-store" is necessary to prevent caching on Firefox.
  695. response.setHeader(HEADER_CACHE_CONTROL, "no-cache");
  696. if (this.useCacheControlNoStore) {
  697. response.addHeader(HEADER_CACHE_CONTROL, "no-store");
  698. }
  699. }
  700. }
  701. private Collection<String> getVaryRequestHeadersToAdd(HttpServletResponse response, String[] varyByRequestHeaders) {
  702. if (!response.containsHeader(HttpHeaders.VARY)) {
  703. return Arrays.asList(varyByRequestHeaders);
  704. }
  705. Collection<String> result = new ArrayList<>(varyByRequestHeaders.length);
  706. Collections.addAll(result, varyByRequestHeaders);
  707. for (String header : response.getHeaders(HttpHeaders.VARY)) {
  708. for (String existing : StringUtils.tokenizeToStringArray(header, ",")) {
  709. if ("*".equals(existing)) {
  710. return Collections.emptyList();
  711. }
  712. for (String value : varyByRequestHeaders) {
  713. if (value.equalsIgnoreCase(existing)) {
  714. result.remove(value);
  715. }
  716. }
  717. }
  718. }
  719. return result;
  720. }
  721. }

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/302626
推荐阅读
相关标签
  

闽ICP备14008679号