diff --git a/org.springframework.web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java b/org.springframework.web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java index b4d399ebe7d..92ac689b637 100644 --- a/org.springframework.web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java +++ b/org.springframework.web/src/main/java/org/springframework/web/multipart/commons/CommonsFileUploadSupport.java @@ -22,6 +22,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.nio.charset.Charset; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; @@ -36,6 +37,7 @@ import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.util.WebUtils; +import org.springframework.http.MediaType; /** * Base class for multipart resolvers that use Jakarta Commons FileUpload @@ -221,14 +223,15 @@ public abstract class CommonsFileUploadSupport { for (FileItem fileItem : fileItems) { if (fileItem.isFormField()) { String value; - if (encoding != null) { + String partEncoding = determineEncoding(fileItem.getContentType(), encoding); + if (partEncoding != null) { try { - value = fileItem.getString(encoding); + value = fileItem.getString(partEncoding); } catch (UnsupportedEncodingException ex) { if (logger.isWarnEnabled()) { logger.warn("Could not decode multipart item '" + fileItem.getFieldName() + - "' with encoding '" + encoding + "': using platform default"); + "' with encoding '" + partEncoding + "': using platform default"); } value = fileItem.getString(); } @@ -281,6 +284,15 @@ public abstract class CommonsFileUploadSupport { } } + private String determineEncoding(String contentTypeHeader, String defaultEncoding) { + if (!StringUtils.hasText(contentTypeHeader)) { + return defaultEncoding; + } + MediaType contentType = MediaType.parseMediaType(contentTypeHeader); + Charset charset = contentType.getCharSet(); + return charset != null ? charset.name() : defaultEncoding; + } + /** * Holder for a Map of Spring MultipartFiles and a Map of diff --git a/org.springframework.web/src/test/java/org/springframework/http/MediaTypeTests.java b/org.springframework.web/src/test/java/org/springframework/http/MediaTypeTests.java index ce912014970..355667eee6f 100644 --- a/org.springframework.web/src/test/java/org/springframework/http/MediaTypeTests.java +++ b/org.springframework.web/src/test/java/org/springframework/http/MediaTypeTests.java @@ -19,6 +19,7 @@ package org.springframework.http; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.nio.charset.Charset; import static org.junit.Assert.*; import org.junit.Test; @@ -55,6 +56,15 @@ public class MediaTypeTests { assertEquals("Invalid quality factor", 0.2D, mediaType.getQualityValue(), 0D); } + @Test + public void parseCharset() throws Exception { + String s = "text/html; charset=iso-8859-1"; + MediaType mediaType = MediaType.parseMediaType(s); + assertEquals("Invalid type", "text", mediaType.getType()); + assertEquals("Invalid subtype", "html", mediaType.getSubtype()); + assertEquals("Invalid charset", Charset.forName("ISO-8859-1"), mediaType.getCharSet()); + } + @Test public void parseURLConnectionMediaType() throws Exception { String s = "*; q=.2"; diff --git a/org.springframework.web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java b/org.springframework.web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java index 4ddd02e285b..2862abd869e 100644 --- a/org.springframework.web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java +++ b/org.springframework.web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java @@ -375,7 +375,7 @@ public class CommonsMultipartResolverTests { MockFileItem fileItem2x = new MockFileItem( "field2x", "type2", empty ? "" : "C:\\field2x.txt", empty ? "" : "text2"); MockFileItem fileItem3 = new MockFileItem("field3", null, null, "value3"); - MockFileItem fileItem4 = new MockFileItem("field4", null, null, "value4"); + MockFileItem fileItem4 = new MockFileItem("field4", "text/html; charset=iso-8859-1", null, "value4"); MockFileItem fileItem5 = new MockFileItem("field4", null, null, "value5"); fileItems.add(fileItem1); fileItems.add(fileItem1x);