Browse Source
The revised builder emphasizes creating a list of resolvers either built-in or custom with each top-level builder method resulting in adding a resolver. By default only the Header resolver is configured. The path extension resolver is removed altogether to discourage its use but is trivial to create manually with the helpf of UriUtils#extractFileExtension + MediaTypeFactory. Issue: SPR-15639pull/1457/head
20 changed files with 340 additions and 707 deletions
@ -1,82 +0,0 @@
@@ -1,82 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.reactive.accept; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Locale; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.http.MediaTypeFactory; |
||||
import org.springframework.lang.Nullable; |
||||
import org.springframework.util.StringUtils; |
||||
import org.springframework.web.server.ServerWebExchange; |
||||
|
||||
/** |
||||
* Base class for resolvers that extract a key from the request and look up a |
||||
* mapping to a MediaType. The use case is URI-based content negotiation for |
||||
* example based on query parameter or file extension in the request path. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 5.0 |
||||
*/ |
||||
public abstract class AbstractMappingContentTypeResolver implements RequestedContentTypeResolver { |
||||
|
||||
/** Primary lookup for media types by key (e.g. "json" -> "application/json") */ |
||||
private final Map<String, MediaType> mediaTypeLookup = new ConcurrentHashMap<>(64); |
||||
|
||||
|
||||
public AbstractMappingContentTypeResolver(Map<String, MediaType> mediaTypes) { |
||||
mediaTypes.forEach((key, mediaType) -> |
||||
this.mediaTypeLookup.put(key.toLowerCase(Locale.ENGLISH), mediaType)); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange) { |
||||
String key = getKey(exchange); |
||||
if (StringUtils.hasText(key)) { |
||||
MediaType mediaType = getMediaType(key); |
||||
if (mediaType != null) { |
||||
this.mediaTypeLookup.putIfAbsent(key, mediaType); |
||||
return Collections.singletonList(mediaType); |
||||
} |
||||
} |
||||
return Collections.emptyList(); |
||||
} |
||||
|
||||
/** |
||||
* Get the key to look up a MediaType with. |
||||
*/ |
||||
@Nullable |
||||
protected abstract String getKey(ServerWebExchange exchange); |
||||
|
||||
/** |
||||
* Get the MediaType for the given key. |
||||
*/ |
||||
@Nullable |
||||
protected MediaType getMediaType(String key) { |
||||
key = key.toLowerCase(Locale.ENGLISH); |
||||
MediaType mediaType = this.mediaTypeLookup.get(key); |
||||
if (mediaType == null) { |
||||
mediaType = MediaTypeFactory.getMediaType("filename." + key).orElse(null); |
||||
} |
||||
return mediaType; |
||||
} |
||||
|
||||
} |
@ -1,55 +0,0 @@
@@ -1,55 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.reactive.accept; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.web.server.ServerWebExchange; |
||||
|
||||
/** |
||||
* Contains and delegates to other {@link RequestedContentTypeResolver}. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 5.0 |
||||
*/ |
||||
public class CompositeContentTypeResolver implements RequestedContentTypeResolver { |
||||
|
||||
private final List<RequestedContentTypeResolver> resolvers = new ArrayList<>(); |
||||
|
||||
|
||||
public CompositeContentTypeResolver(List<RequestedContentTypeResolver> resolvers) { |
||||
Assert.notEmpty(resolvers, "At least one resolver is expected."); |
||||
this.resolvers.addAll(resolvers); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
public List<MediaType> resolveMediaTypes(ServerWebExchange exchange) { |
||||
for (RequestedContentTypeResolver resolver : this.resolvers) { |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
if (mediaTypes.isEmpty() || (mediaTypes.size() == 1 && mediaTypes.contains(MediaType.ALL))) { |
||||
continue; |
||||
} |
||||
return mediaTypes; |
||||
} |
||||
return Collections.emptyList(); |
||||
} |
||||
|
||||
} |
@ -1,45 +0,0 @@
@@ -1,45 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.reactive.accept; |
||||
|
||||
import java.util.Map; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.web.server.ServerWebExchange; |
||||
import org.springframework.web.util.UriUtils; |
||||
|
||||
/** |
||||
* Path file extension sub-class of {@link AbstractMappingContentTypeResolver}. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 5.0 |
||||
*/ |
||||
public class PathExtensionContentTypeResolver extends AbstractMappingContentTypeResolver { |
||||
|
||||
|
||||
public PathExtensionContentTypeResolver(Map<String, MediaType> mediaTypes) { |
||||
super(mediaTypes); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
protected String getKey(ServerWebExchange exchange) { |
||||
String path = exchange.getRequest().getURI().getRawPath(); |
||||
return UriUtils.extractFileExtension(path); |
||||
} |
||||
|
||||
} |
@ -1,132 +0,0 @@
@@ -1,132 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.reactive.accept; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; |
||||
import org.springframework.mock.http.server.reactive.test.MockServerWebExchange; |
||||
import org.springframework.web.server.ServerWebExchange; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
/** |
||||
* Unit tests for {@link RequestedContentTypeResolverBuilder}. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class CompositeContentTypeResolverBuilderTests { |
||||
|
||||
@Test |
||||
public void defaultSettings() throws Exception { |
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder().build(); |
||||
|
||||
MockServerWebExchange exchange = MockServerHttpRequest.get("/flower.gif").toExchange(); |
||||
|
||||
assertEquals("Should be able to resolve file extensions by default", |
||||
Collections.singletonList(MediaType.IMAGE_GIF), resolver.resolveMediaTypes(exchange)); |
||||
|
||||
exchange = MockServerHttpRequest.get("/flower.foobar").toExchange(); |
||||
|
||||
assertEquals("Should ignore unknown extensions by default", |
||||
Collections.<MediaType>emptyList(), resolver.resolveMediaTypes(exchange)); |
||||
|
||||
exchange = MockServerHttpRequest.get("/flower?format=gif").toExchange(); |
||||
|
||||
assertEquals("Should not resolve request parameters by default", |
||||
Collections.<MediaType>emptyList(), resolver.resolveMediaTypes(exchange)); |
||||
|
||||
exchange = MockServerHttpRequest.get("/flower").accept(MediaType.IMAGE_GIF).toExchange(); |
||||
|
||||
assertEquals("Should resolve Accept header by default", |
||||
Collections.singletonList(MediaType.IMAGE_GIF), resolver.resolveMediaTypes(exchange)); |
||||
} |
||||
|
||||
@Test |
||||
public void favorPath() throws Exception { |
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder() |
||||
.favorPathExtension(true) |
||||
.mediaType("foo", new MediaType("application", "foo")) |
||||
.mediaType("bar", new MediaType("application", "bar")) |
||||
.build(); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/flower.foo").toExchange(); |
||||
assertEquals(Collections.singletonList(new MediaType("application", "foo")), |
||||
resolver.resolveMediaTypes(exchange)); |
||||
|
||||
exchange = MockServerHttpRequest.get("/flower.bar").toExchange(); |
||||
assertEquals(Collections.singletonList(new MediaType("application", "bar")), |
||||
resolver.resolveMediaTypes(exchange)); |
||||
|
||||
exchange = MockServerHttpRequest.get("/flower.gif").toExchange(); |
||||
assertEquals(Collections.singletonList(MediaType.IMAGE_GIF), resolver.resolveMediaTypes(exchange)); |
||||
} |
||||
|
||||
@Test |
||||
public void favorParameter() throws Exception { |
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder() |
||||
.favorParameter(true) |
||||
.mediaType("json", MediaType.APPLICATION_JSON) |
||||
.build(); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/flower?format=json").toExchange(); |
||||
|
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), resolver.resolveMediaTypes(exchange)); |
||||
} |
||||
|
||||
@Test |
||||
public void ignoreAcceptHeader() throws Exception { |
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder() |
||||
.ignoreAcceptHeader(true) |
||||
.build(); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/flower").accept(MediaType.IMAGE_GIF).toExchange(); |
||||
|
||||
assertEquals(Collections.<MediaType>emptyList(), resolver.resolveMediaTypes(exchange)); |
||||
} |
||||
|
||||
@Test // SPR-10513
|
||||
public void setDefaultContentType() throws Exception { |
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder() |
||||
.defaultContentType(MediaType.APPLICATION_JSON) |
||||
.build(); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/").accept(MediaType.ALL).toExchange(); |
||||
|
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), resolver.resolveMediaTypes(exchange)); |
||||
} |
||||
|
||||
@Test // SPR-12286
|
||||
public void setDefaultContentTypeWithStrategy() throws Exception { |
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder() |
||||
.defaultContentTypeResolver(new FixedContentTypeResolver(MediaType.APPLICATION_JSON)) |
||||
.build(); |
||||
|
||||
List<MediaType> expected = Collections.singletonList(MediaType.APPLICATION_JSON); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/").toExchange(); |
||||
assertEquals(expected, resolver.resolveMediaTypes(exchange)); |
||||
|
||||
exchange = MockServerHttpRequest.get("/").accept(MediaType.ALL).toExchange(); |
||||
assertEquals(expected, resolver.resolveMediaTypes(exchange)); |
||||
} |
||||
|
||||
|
||||
} |
@ -1,103 +0,0 @@
@@ -1,103 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.reactive.accept; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.lang.Nullable; |
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; |
||||
import org.springframework.web.server.NotAcceptableStatusException; |
||||
import org.springframework.web.server.ServerWebExchange; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
/** |
||||
* Unit tests for {@link AbstractMappingContentTypeResolver}. |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class MappingContentTypeResolverTests { |
||||
|
||||
@Test // SPR-13747
|
||||
public void resolveCaseInsensitive() { |
||||
Map<String, MediaType> mapping = Collections.singletonMap("json", MediaType.APPLICATION_JSON); |
||||
TestMappingContentTypeResolver resolver = new TestMappingContentTypeResolver("JSoN", mapping); |
||||
List<MediaType> mediaTypes = resolver.resolve(); |
||||
|
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), mediaTypes); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveMediaTypes() throws Exception { |
||||
Map<String, MediaType> mapping = Collections.singletonMap("json", MediaType.APPLICATION_JSON); |
||||
TestMappingContentTypeResolver resolver = new TestMappingContentTypeResolver("json", mapping); |
||||
List<MediaType> mediaTypes = resolver.resolve(); |
||||
|
||||
assertEquals(1, mediaTypes.size()); |
||||
assertEquals("application/json", mediaTypes.get(0).toString()); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveNoMatch() throws Exception { |
||||
TestMappingContentTypeResolver resolver = new TestMappingContentTypeResolver("blah", Collections.emptyMap()); |
||||
List<MediaType> mediaTypes = resolver.resolve(); |
||||
|
||||
assertEquals(0, mediaTypes.size()); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveNoKey() throws Exception { |
||||
Map<String, MediaType> mapping = Collections.singletonMap("json", MediaType.APPLICATION_JSON); |
||||
TestMappingContentTypeResolver resolver = new TestMappingContentTypeResolver(null, mapping); |
||||
List<MediaType> mediaTypes = resolver.resolve(); |
||||
|
||||
assertEquals(0, mediaTypes.size()); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveMediaTypesHandleNoMatch() throws Exception { |
||||
TestMappingContentTypeResolver resolver = new TestMappingContentTypeResolver("xml", Collections.emptyMap()); |
||||
List<MediaType> mediaTypes = resolver.resolve(); |
||||
|
||||
assertEquals(1, mediaTypes.size()); |
||||
assertEquals("application/xml", mediaTypes.get(0).toString()); |
||||
} |
||||
|
||||
|
||||
private static class TestMappingContentTypeResolver extends AbstractMappingContentTypeResolver { |
||||
|
||||
private final String key; |
||||
|
||||
TestMappingContentTypeResolver(@Nullable String key, Map<String, MediaType> mapping) { |
||||
super(mapping); |
||||
this.key = key; |
||||
} |
||||
|
||||
public List<MediaType> resolve() throws NotAcceptableStatusException { |
||||
return super.resolveMediaTypes(MockServerHttpRequest.get("/").toExchange()); |
||||
} |
||||
|
||||
@Override |
||||
protected String getKey(ServerWebExchange exchange) { |
||||
return this.key; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.reactive.accept; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; |
||||
import org.springframework.mock.http.server.reactive.test.MockServerWebExchange; |
||||
import org.springframework.web.server.NotAcceptableStatusException; |
||||
import org.springframework.web.server.ServerWebExchange; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
/** |
||||
* Unit tests for {@link ParameterContentTypeResolver}. |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class ParameterContentTypeResolverTests { |
||||
|
||||
@Test |
||||
public void noKey() throws Exception { |
||||
ParameterContentTypeResolver resolver = new ParameterContentTypeResolver(Collections.emptyMap()); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(MockServerHttpRequest.get("/").toExchange()); |
||||
|
||||
assertEquals(0, mediaTypes.size()); |
||||
} |
||||
|
||||
@Test(expected = NotAcceptableStatusException.class) |
||||
public void noMatchForKey() throws Exception { |
||||
ParameterContentTypeResolver resolver = new ParameterContentTypeResolver(Collections.emptyMap()); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(createExchange("blah")); |
||||
|
||||
assertEquals(0, mediaTypes.size()); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveKeyFromRegistrations() throws Exception { |
||||
ServerWebExchange exchange = createExchange("html"); |
||||
|
||||
Map<String, MediaType> mapping = Collections.emptyMap(); |
||||
RequestedContentTypeResolver resolver = new ParameterContentTypeResolver(mapping); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
assertEquals(Collections.singletonList(new MediaType("text", "html")), mediaTypes); |
||||
|
||||
mapping = Collections.singletonMap("HTML", MediaType.APPLICATION_XHTML_XML); |
||||
resolver = new ParameterContentTypeResolver(mapping); |
||||
mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
assertEquals(Collections.singletonList(new MediaType("application", "xhtml+xml")), mediaTypes); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveKeyThroughMediaTypeFactory() throws Exception { |
||||
ServerWebExchange exchange = createExchange("xls"); |
||||
RequestedContentTypeResolver resolver = new ParameterContentTypeResolver(Collections.emptyMap()); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(new MediaType("application", "vnd.ms-excel")), mediaTypes); |
||||
} |
||||
|
||||
@Test // SPR-13747
|
||||
public void resolveKeyIsCaseInsensitive() { |
||||
ServerWebExchange exchange = createExchange("JSoN"); |
||||
Map<String, MediaType> mapping = Collections.singletonMap("json", MediaType.APPLICATION_JSON); |
||||
ParameterContentTypeResolver resolver = new ParameterContentTypeResolver(mapping); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), mediaTypes); |
||||
} |
||||
|
||||
private MockServerWebExchange createExchange(String format) { |
||||
return MockServerHttpRequest.get("/path?format=" + format).toExchange(); |
||||
} |
||||
|
||||
} |
@ -1,83 +0,0 @@
@@ -1,83 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.reactive.accept; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; |
||||
import org.springframework.web.server.ServerWebExchange; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
/** |
||||
* Unit tests for {@link PathExtensionContentTypeResolver}. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class PathExtensionContentTypeResolverTests { |
||||
|
||||
@Test |
||||
public void resolveFromRegistrations() throws Exception { |
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/test.html").toExchange(); |
||||
PathExtensionContentTypeResolver resolver = createResolver(); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(new MediaType("text", "html")), mediaTypes); |
||||
|
||||
Map<String, MediaType> mapping = Collections.singletonMap("HTML", MediaType.APPLICATION_XHTML_XML); |
||||
resolver = new PathExtensionContentTypeResolver(mapping); |
||||
mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(new MediaType("application", "xhtml+xml")), mediaTypes); |
||||
} |
||||
|
||||
@Test |
||||
public void resolveFromMediaTypeFactory() throws Exception { |
||||
ServerWebExchange exchange = MockServerHttpRequest.get("test.xls").toExchange(); |
||||
PathExtensionContentTypeResolver resolver = createResolver(); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(new MediaType("application", "vnd.ms-excel")), mediaTypes); |
||||
} |
||||
|
||||
@Test // SPR-9390
|
||||
public void resolveFromFilenameWithEncodedURI() throws Exception { |
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/quo%20vadis%3f.html").toExchange(); |
||||
PathExtensionContentTypeResolver resolver = createResolver(); |
||||
List<MediaType> result = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals("Invalid content type", Collections.singletonList(new MediaType("text", "html")), result); |
||||
} |
||||
|
||||
@Test // SPR-10170
|
||||
public void resolveAndIgnoreUnknownExtension() throws Exception { |
||||
ServerWebExchange exchange = MockServerHttpRequest.get("test.foobar").toExchange(); |
||||
PathExtensionContentTypeResolver resolver = createResolver(); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.<MediaType>emptyList(), mediaTypes); |
||||
} |
||||
|
||||
private PathExtensionContentTypeResolver createResolver() { |
||||
return new PathExtensionContentTypeResolver(Collections.emptyMap()); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
/* |
||||
* Copyright 2002-2017 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.reactive.accept; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; |
||||
import org.springframework.web.server.ServerWebExchange; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
|
||||
/** |
||||
* Unit tests for {@link RequestedContentTypeResolverBuilder}. |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class RequestedContentTypeResolverBuilderTests { |
||||
|
||||
@Test |
||||
public void defaultSettings() throws Exception { |
||||
|
||||
RequestedContentTypeResolver resolver = new RequestedContentTypeResolverBuilder().build(); |
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/flower").accept(MediaType.IMAGE_GIF).toExchange(); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(MediaType.IMAGE_GIF), mediaTypes); |
||||
} |
||||
|
||||
@Test |
||||
public void parameterResolver() throws Exception { |
||||
|
||||
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder(); |
||||
builder.parameterResolver().mediaType("json", MediaType.APPLICATION_JSON); |
||||
RequestedContentTypeResolver resolver = builder.build(); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/flower?format=json").toExchange(); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), mediaTypes); |
||||
} |
||||
|
||||
@Test |
||||
public void parameterResolverWithCustomParamName() throws Exception { |
||||
|
||||
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder(); |
||||
builder.parameterResolver().mediaType("json", MediaType.APPLICATION_JSON).parameterName("s"); |
||||
RequestedContentTypeResolver resolver = builder.build(); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/flower?s=json").toExchange(); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), mediaTypes); |
||||
} |
||||
|
||||
@Test // SPR-10513
|
||||
public void fixedResolver() throws Exception { |
||||
|
||||
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder(); |
||||
builder.fixedResolver(MediaType.APPLICATION_JSON); |
||||
RequestedContentTypeResolver resolver = builder.build(); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/").accept(MediaType.ALL).toExchange(); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
|
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), mediaTypes); |
||||
} |
||||
|
||||
@Test // SPR-12286
|
||||
public void resolver() throws Exception { |
||||
|
||||
RequestedContentTypeResolverBuilder builder = new RequestedContentTypeResolverBuilder(); |
||||
builder.resolver(new FixedContentTypeResolver(MediaType.APPLICATION_JSON)); |
||||
RequestedContentTypeResolver resolver = builder.build(); |
||||
|
||||
ServerWebExchange exchange = MockServerHttpRequest.get("/").toExchange(); |
||||
List<MediaType> mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), mediaTypes); |
||||
|
||||
exchange = MockServerHttpRequest.get("/").accept(MediaType.ALL).toExchange(); |
||||
mediaTypes = resolver.resolveMediaTypes(exchange); |
||||
assertEquals(Collections.singletonList(MediaType.APPLICATION_JSON), mediaTypes); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue