Skip to content
Snippets Groups Projects
Commit e019796d authored by Paul-Christian Volkmer's avatar Paul-Christian Volkmer
Browse files

Added CacheControl annotation and interceptor handler

This should enable annotation based cache-control header values.
Added a cache max age of 60 seconds to statistics resource. Proxy-Servers
should cache a statistics resource for about 60 seconds.
parent 50d96a48
Branches
Tags
No related merge requests found
......@@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RestController;
import de.thm.arsnova.entities.Statistics;
import de.thm.arsnova.services.IStatisticsService;
import de.thm.arsnova.web.CacheControl;
@RestController
public class StatisticsController extends AbstractController {
......@@ -19,6 +20,7 @@ public class StatisticsController extends AbstractController {
private IStatisticsService statisticsService;
@RequestMapping(method = RequestMethod.GET, value = "/statistics")
@CacheControl(maxAge = 60, policy = CacheControl.Policy.PUBLIC)
public final Statistics getStatistics() {
return statisticsService.getStatistics();
}
......
package de.thm.arsnova.web;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheControl {
enum Policy {
NO_CACHE("no-cache"),
NO_STORE("no-store"),
PRIVATE("private"),
PUBLIC("public");
private Policy() {
this.policyString = null;
}
private Policy(String policyString) {
this.policyString = policyString;
}
public String getPolicyString() {
return this.policyString;
}
private final String policyString;
}
boolean noCache() default false;
int maxAge() default 0;
Policy[] policy() default {};
}
package de.thm.arsnova.web;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@Component
public class CacheControlInterceptorHandler extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
setCacheControlResponseHeader(request, response, handler);
return super.preHandle(request, response, handler);
}
private void setCacheControlResponseHeader(
HttpServletRequest request,
HttpServletResponse response,
Object handler) {
CacheControl cacheControl = getCacheControlAnnotation(request, response, handler);
if (cacheControl == null) {
return;
}
StringBuilder headerValue = new StringBuilder();
if(cacheControl.policy().length > 0) {
for (CacheControl.Policy policy : cacheControl.policy()) {
if (headerValue.length() > 0) {
headerValue.append(", ");
}
headerValue.append(policy.getPolicyString());
}
}
if (cacheControl.noCache()) {
if (headerValue.length() > 0) {
headerValue.append(", ");
}
headerValue.append("max-age=0, no-cache");
response.setHeader("cache-control", headerValue.toString());
}
if(cacheControl.maxAge() >= 0) {
if (headerValue.length() > 0) {
headerValue.append(", ");
}
headerValue.append("max-age=").append(cacheControl.maxAge());
}
response.setHeader("cache-control", headerValue.toString());
}
private CacheControl getCacheControlAnnotation(
HttpServletRequest request,
HttpServletResponse response,
Object handler
) {
if (handler == null || !(handler instanceof HandlerMethod)) {
return null;
}
final HandlerMethod handlerMethod = (HandlerMethod) handler;
return handlerMethod.getMethodAnnotation(CacheControl.class);
}
}
......@@ -13,6 +13,10 @@
<mvc:annotation-driven
content-negotiation-manager="contentNegotiationManager" />
<mvc:interceptors>
<bean class="de.thm.arsnova.web.CacheControlInterceptorHandler" />
</mvc:interceptors>
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
......
......@@ -2,6 +2,7 @@ package de.thm.arsnova.controller;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
......@@ -59,4 +60,11 @@ public class StatisticsControllerTest {
.andExpect(status().isOk())
.andExpect(content().string("{\"answers\":0,\"questions\":0,\"openSessions\":3,\"closedSessions\":0,\"activeUsers\":0}"));
}
@Test
public final void testShouldGetCacheControlHeaderForStatistics() throws Exception {
mockMvc.perform(get("/statistics"))
.andExpect(status().isOk())
.andExpect(header().string("cache-control", "public, max-age=60"));
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment