提交 9be0cf21 编写于 作者: R Rossen Stoyanchev

Support writing multipart non-ASCII file names

Issue: SPR-12108
上级 6cbe1433
......@@ -684,6 +684,7 @@ project("spring-web") {
optional("log4j:log4j:1.2.17")
optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.2")
optional("com.google.protobuf:protobuf-java:${protobufVersion}")
optional("javax.mail:javax.mail-api:1.5.2")
testCompile(project(":spring-context-support")) // for JafMediaTypeFactory
testCompile("xmlunit:xmlunit:1.5")
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
......
......@@ -41,6 +41,8 @@ import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import javax.mail.internet.MimeUtility;
/**
* Implementation of {@link HttpMessageConverter} to read and write 'normal' HTML
* forms and also to write (but not read) multipart data (e.g. file uploads).
......@@ -92,6 +94,8 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
private Charset charset = Charset.forName("UTF-8");
private Charset multipartCharset;
private List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
private List<HttpMessageConverter<?>> partConverters = new ArrayList<HttpMessageConverter<?>>();
......@@ -118,6 +122,18 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
this.charset = charset;
}
/**
* Set the character set to use when writing multipart data to encode file
* names. Encoding is based on the encoded-word syntax defined in RFC 2047
* and relies on the MimeUtility class from "javax.mail-api".
* <p>If not set file names will be encoded as US-ASCII.
* @param multipartCharset the charset to use
* @see <a href="http://en.wikipedia.org/wiki/MIME#Encoded-Word">Encoded-Word</a>
*/
public void setMultipartCharset(Charset multipartCharset) {
this.multipartCharset = multipartCharset;
}
/**
* Set the list of {@link MediaType} objects supported by this converter.
*/
......@@ -374,7 +390,17 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
protected String getFilename(Object part) {
if (part instanceof Resource) {
Resource resource = (Resource) part;
return resource.getFilename();
String filename = resource.getFilename();
if (multipartCharset != null) {
try {
filename = MimeUtility.encodeText(filename, multipartCharset.name(), null);
}
catch (UnsupportedEncodingException e) {
// should not happen
throw new IllegalStateException(e);
}
}
return filename;
}
else {
return null;
......
......@@ -116,6 +116,17 @@ public class FormHttpMessageConverterTests {
Resource logo = new ClassPathResource("/org/springframework/http/converter/logo.jpg");
parts.add("logo", logo);
// SPR-12108
Resource utf8 = new ClassPathResource("/org/springframework/http/converter/logo.jpg") {
@Override
public String getFilename() {
return "Hall\u00F6le.jpg";
}
};
parts.add("utf8", utf8);
Source xml = new StreamSource(new StringReader("<root><child/></root>"));
HttpHeaders entityHeaders = new HttpHeaders();
entityHeaders.setContentType(MediaType.TEXT_XML);
......@@ -123,6 +134,7 @@ public class FormHttpMessageConverterTests {
parts.add("xml", entity);
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.setMultipartCharset(Charset.forName("UTF-8"));
converter.write(parts, MediaType.MULTIPART_FORM_DATA, outputMessage);
final MediaType contentType = outputMessage.getHeaders().getContentType();
......@@ -132,7 +144,7 @@ public class FormHttpMessageConverterTests {
FileItemFactory fileItemFactory = new DiskFileItemFactory();
FileUpload fileUpload = new FileUpload(fileItemFactory);
List<FileItem> items = fileUpload.parseRequest(new MockHttpOutputMessageRequestContext(outputMessage));
assertEquals(5, items.size());
assertEquals(6, items.size());
FileItem item = items.get(0);
assertTrue(item.isFormField());
assertEquals("name 1", item.getFieldName());
......@@ -156,6 +168,13 @@ public class FormHttpMessageConverterTests {
assertEquals(logo.getFile().length(), item.getSize());
item = items.get(4);
assertFalse(item.isFormField());
assertEquals("utf8", item.getFieldName());
assertEquals("Hall\u00F6le.jpg", item.getName());
assertEquals("image/jpeg", item.getContentType());
assertEquals(logo.getFile().length(), item.getSize());
item = items.get(5);
assertEquals("xml", item.getFieldName());
assertEquals("text/xml", item.getContentType());
verify(outputMessage.getBody(), never()).close();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册