diff --git a/src/main/java/de/thm/arsnova/config/AppConfig.java b/src/main/java/de/thm/arsnova/config/AppConfig.java index 287c5772ca4289bfe3aeb0a2df7222ad0d31020d..4d8f3f782e59f10aa408643ed21f26215b8b8fab 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 0000000000000000000000000000000000000000..83e417d19370d8bfa5afb32b968088ca1678e6cc --- /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; + } +}