From ba08cf4b192a4b593cc09f18ab44111b0b5bdeec Mon Sep 17 00:00:00 2001 From: Daniel Gerhardt <code@dgerhardt.net> Date: Sat, 27 Jan 2018 16:44:19 +0100 Subject: [PATCH] Add custom ContentNegotiationStrategy as fallback PathApiVersionContentNegotiationStrategy selects the media type based on request path. It allows to set the correct media type for old clients which do not set the 'Accept' header. --- .../java/de/thm/arsnova/config/AppConfig.java | 8 +++- ...hApiVersionContentNegotiationStrategy.java | 46 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/main/java/de/thm/arsnova/web/PathApiVersionContentNegotiationStrategy.java diff --git a/src/main/java/de/thm/arsnova/config/AppConfig.java b/src/main/java/de/thm/arsnova/config/AppConfig.java index 287c5772c..4d8f3f782 100644 --- a/src/main/java/de/thm/arsnova/config/AppConfig.java +++ b/src/main/java/de/thm/arsnova/config/AppConfig.java @@ -27,6 +27,7 @@ import de.thm.arsnova.connector.client.ConnectorClient; import de.thm.arsnova.connector.client.ConnectorClientImpl; import de.thm.arsnova.entities.serialization.CouchDbDocumentModule; import de.thm.arsnova.entities.serialization.View; +import de.thm.arsnova.web.PathApiVersionContentNegotiationStrategy; import de.thm.arsnova.websocket.ArsnovaSocketioServer; import de.thm.arsnova.websocket.ArsnovaSocketioServerImpl; import de.thm.arsnova.websocket.ArsnovaSocketioServerListener; @@ -127,11 +128,14 @@ public class AppConfig extends WebMvcConfigurerAdapter { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { + PathApiVersionContentNegotiationStrategy strategy = + new PathApiVersionContentNegotiationStrategy(API_V3_MEDIA_TYPE); configurer.mediaType("json", MediaType.APPLICATION_JSON_UTF8); configurer.mediaType("xml", MediaType.APPLICATION_XML); - configurer.defaultContentType(API_V3_MEDIA_TYPE); - configurer.favorParameter(true); + configurer.favorParameter(false); configurer.favorPathExtension(false); + //configurer.defaultContentType(API_V3_MEDIA_TYPE); + configurer.defaultContentTypeStrategy(strategy); } @Override diff --git a/src/main/java/de/thm/arsnova/web/PathApiVersionContentNegotiationStrategy.java b/src/main/java/de/thm/arsnova/web/PathApiVersionContentNegotiationStrategy.java new file mode 100644 index 000000000..83e417d19 --- /dev/null +++ b/src/main/java/de/thm/arsnova/web/PathApiVersionContentNegotiationStrategy.java @@ -0,0 +1,46 @@ +package de.thm.arsnova.web; + +import de.thm.arsnova.config.AppConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.web.HttpMediaTypeNotAcceptableException; +import org.springframework.web.accept.ContentNegotiationStrategy; +import org.springframework.web.context.request.NativeWebRequest; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; + +/** + * This {@link ContentNegotiationStrategy} selects the media type based on request path. It allows to set the correct + * media type for old clients which do not set the 'Accept' header. + * + * @author Daniel Gerhardt + */ +public class PathApiVersionContentNegotiationStrategy implements ContentNegotiationStrategy { + private static final Logger logger = LoggerFactory.getLogger(PathApiVersionContentNegotiationStrategy.class); + + private MediaType fallback; + + public PathApiVersionContentNegotiationStrategy(MediaType fallback) { + this.fallback = fallback; + } + + @Override + public List<MediaType> resolveMediaTypes(final NativeWebRequest webRequest) + throws HttpMediaTypeNotAcceptableException { + final HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); + final List<MediaType> mediaTypes = new ArrayList<>(); + if (servletRequest.getServletPath().startsWith("/v2/")) { + logger.trace("Negotiating content based on path for API v2"); + mediaTypes.add(AppConfig.API_V2_MEDIA_TYPE); + mediaTypes.add(MediaType.TEXT_PLAIN); + } else { + logger.trace("Content negotiation falling back to {}", fallback); + mediaTypes.add(fallback); + } + + return mediaTypes; + } +} -- GitLab