diff --git a/spring-core/src/main/java/org/springframework/util/MimeType.java b/spring-core/src/main/java/org/springframework/util/MimeType.java index f4ca7953ed..ccfd56ada9 100644 --- a/spring-core/src/main/java/org/springframework/util/MimeType.java +++ b/spring-core/src/main/java/org/springframework/util/MimeType.java @@ -25,6 +25,7 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.TreeSet; /** @@ -430,7 +431,37 @@ public class MimeType implements Comparable, Serializable { MimeType otherType = (MimeType) other; return (this.type.equalsIgnoreCase(otherType.type) && this.subtype.equalsIgnoreCase(otherType.subtype) && - this.parameters.equals(otherType.parameters)); + parametersAreEqual(otherType)); + } + + /** + * Determine if the parameters in this {@code MimeType} and the supplied + * {@code MimeType} are equal, performing case-insensitive comparisons + * for {@link Charset}s. + * @since 4.2 + */ + private boolean parametersAreEqual(MimeType that) { + if (this.parameters.size() != that.parameters.size()) { + return false; + } + + for (Entry entry : this.parameters.entrySet()) { + String key = entry.getKey(); + if (!that.parameters.containsKey(key)) { + return false; + } + + if (PARAM_CHARSET.equals(key)) { + if (!ObjectUtils.nullSafeEquals(this.getCharSet(), that.getCharSet())) { + return false; + } + } + else if (!ObjectUtils.nullSafeEquals(this.parameters.get(key), that.parameters.get(key))) { + return false; + } + } + + return true; } @Override diff --git a/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java b/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java index da7d9c1178..b9d3480fd7 100644 --- a/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java +++ b/spring-core/src/test/java/org/springframework/util/MimeTypeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -27,15 +27,18 @@ import org.junit.Test; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.DefaultConversionService; +import static java.util.Collections.singletonMap; import static org.junit.Assert.*; /** + * Unit tests for {@link MimeType}. + * * @author Arjen Poutsma * @author Juergen Hoeller + * @author Sam Brannen */ public class MimeTypeTests { - @Test(expected = IllegalArgumentException.class) public void slashInSubtype() { new MimeType("text", "/"); @@ -85,7 +88,7 @@ public class MimeTypeTests { } @Test - public void testWithConversionService() { + public void withConversionService() { ConversionService conversionService = new DefaultConversionService(); assertTrue(conversionService.canConvert(String.class, MimeType.class)); MimeType mimeType = MimeType.valueOf("application/xml"); @@ -211,16 +214,18 @@ public class MimeTypeTests { MimeTypeUtils.parseMimeType("text/html; charset=foo-bar"); } - // SPR-8917 - + /** + * SPR-8917 + */ @Test public void parseMimeTypeQuotedParameterValue() { MimeType mimeType = MimeTypeUtils.parseMimeType("audio/*;attr=\"v>alue\""); assertEquals("\"v>alue\"", mimeType.getParameter("attr")); } - // SPR-8917 - + /** + * SPR-8917 + */ @Test public void parseMimeTypeSingleQuotedParameterValue() { MimeType mimeType = MimeTypeUtils.parseMimeType("audio/*;attr='v>alue'"); @@ -249,7 +254,7 @@ public class MimeTypeTests { MimeType audioBasic = new MimeType("audio", "basic"); MimeType audio = new MimeType("audio"); MimeType audioWave = new MimeType("audio", "wave"); - MimeType audioBasicLevel = new MimeType("audio", "basic", Collections.singletonMap("level", "1")); + MimeType audioBasicLevel = new MimeType("audio", "basic", singletonMap("level", "1")); // equal assertEquals("Invalid comparison result", 0, audioBasic.compareTo(audioBasic)); @@ -284,16 +289,27 @@ public class MimeTypeTests { assertEquals("Invalid comparison result", 0, m1.compareTo(m2)); assertEquals("Invalid comparison result", 0, m2.compareTo(m1)); - m1 = new MimeType("audio", "basic", Collections.singletonMap("foo", "bar")); - m2 = new MimeType("audio", "basic", Collections.singletonMap("Foo", "bar")); + m1 = new MimeType("audio", "basic", singletonMap("foo", "bar")); + m2 = new MimeType("audio", "basic", singletonMap("Foo", "bar")); assertEquals("Invalid comparison result", 0, m1.compareTo(m2)); assertEquals("Invalid comparison result", 0, m2.compareTo(m1)); - m1 = new MimeType("audio", "basic", Collections.singletonMap("foo", "bar")); - m2 = new MimeType("audio", "basic", Collections.singletonMap("foo", "Bar")); + m1 = new MimeType("audio", "basic", singletonMap("foo", "bar")); + m2 = new MimeType("audio", "basic", singletonMap("foo", "Bar")); assertTrue("Invalid comparison result", m1.compareTo(m2) != 0); assertTrue("Invalid comparison result", m2.compareTo(m1) != 0); } + /** + * SPR-13157 + * @since 4.2 + */ + @Test + public void equalsIsCaseInsensitiveForCharsets() { + MimeType m1 = new MimeType("text", "plain", singletonMap("charset", "UTF-8")); + MimeType m2 = new MimeType("text", "plain", singletonMap("charset", "utf-8")); + assertEquals(m1, m2); + assertEquals(m2, m1); + } } diff --git a/spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java b/spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java index f633dec43e..5f54060ba9 100644 --- a/spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java +++ b/spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java @@ -56,7 +56,7 @@ public class AbstractJettyServerTestCase { protected static final String baseUrl = "http://localhost:" + port; - protected static final MediaType textContentType = new MediaType("text", "plain", Collections.singletonMap("charset", "utf-8")); + protected static final MediaType textContentType = new MediaType("text", "plain", Collections.singletonMap("charset", "UTF-8")); protected static final MediaType jsonContentType = new MediaType("application", "json", Collections.singletonMap("charset", "utf-8"));