Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
def90d10
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
GitCode(gitcode.net)2024年7月9日维护升级公告
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
def90d10
编写于
3月 10, 2010
作者:
A
Arjen Poutsma
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SPR-5904 - Multipart/mixed requests using RestTemplate
上级
f30b0a86
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
614 addition
and
216 deletion
+614
-216
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
.../servlet/config/AnnotationDrivenBeanDefinitionParser.java
+10
-0
org.springframework.web/src/main/java/org/springframework/http/HttpHeaders.java
...b/src/main/java/org/springframework/http/HttpHeaders.java
+19
-0
org.springframework.web/src/main/java/org/springframework/http/MediaType.java
...web/src/main/java/org/springframework/http/MediaType.java
+92
-2
org.springframework.web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java
...ramework/http/converter/ResourceHttpMessageConverter.java
+147
-0
org.springframework.web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java
...gframework/http/converter/StringHttpMessageConverter.java
+13
-1
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/ByteArrayPart.java
...ringframework/http/converter/multipart/ByteArrayPart.java
+0
-44
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/MultipartHttpMessageConverter.java
...tp/converter/multipart/MultipartHttpMessageConverter.java
+120
-29
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/MultipartHttpOutputMessage.java
.../http/converter/multipart/MultipartHttpOutputMessage.java
+89
-0
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/MultipartMap.java
...pringframework/http/converter/multipart/MultipartMap.java
+11
-41
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/Part.java
...va/org/springframework/http/converter/multipart/Part.java
+0
-30
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/StringPart.java
.../springframework/http/converter/multipart/StringPart.java
+0
-54
org.springframework.web/src/main/java/org/springframework/web/client/RestTemplate.java
...ain/java/org/springframework/web/client/RestTemplate.java
+11
-0
org.springframework.web/src/test/java/org/springframework/http/HttpHeadersTests.java
.../test/java/org/springframework/http/HttpHeadersTests.java
+11
-1
org.springframework.web/src/test/java/org/springframework/http/MediaTypeTests.java
...rc/test/java/org/springframework/http/MediaTypeTests.java
+1
-1
org.springframework.web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java
...ork/http/converter/ResourceHttpMessageConverterTests.java
+73
-0
org.springframework.web/src/test/java/org/springframework/http/converter/multipart/MultipartHttpMessageConverterTest.java
...onverter/multipart/MultipartHttpMessageConverterTest.java
+11
-8
org.springframework.web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java
...ingframework/web/client/RestTemplateIntegrationTests.java
+5
-5
org.springframework.web/template.mf
org.springframework.web/template.mf
+1
-0
未找到文件。
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
浏览文件 @
def90d10
...
...
@@ -30,7 +30,10 @@ import org.springframework.core.convert.ConversionService;
import
org.springframework.format.support.FormattingConversionServiceFactoryBean
;
import
org.springframework.http.converter.ByteArrayHttpMessageConverter
;
import
org.springframework.http.converter.FormHttpMessageConverter
;
import
org.springframework.http.converter.ResourceHttpMessageConverter
;
import
org.springframework.http.converter.StringHttpMessageConverter
;
import
org.springframework.http.converter.feed.AtomFeedHttpMessageConverter
;
import
org.springframework.http.converter.feed.RssChannelHttpMessageConverter
;
import
org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
;
import
org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter
;
import
org.springframework.http.converter.xml.SourceHttpMessageConverter
;
...
...
@@ -82,6 +85,8 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
ClassUtils
.
isPresent
(
"org.codehaus.jackson.map.ObjectMapper"
,
AnnotationDrivenBeanDefinitionParser
.
class
.
getClassLoader
())
&&
ClassUtils
.
isPresent
(
"org.codehaus.jackson.JsonGenerator"
,
AnnotationDrivenBeanDefinitionParser
.
class
.
getClassLoader
());
private
static
boolean
romePresent
=
ClassUtils
.
isPresent
(
"com.sun.syndication.feed.WireFeed"
,
AnnotationDrivenBeanDefinitionParser
.
class
.
getClassLoader
());
public
BeanDefinition
parse
(
Element
element
,
ParserContext
parserContext
)
{
...
...
@@ -167,6 +172,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
messageConverters
.
setSource
(
source
);
messageConverters
.
add
(
new
RootBeanDefinition
(
ByteArrayHttpMessageConverter
.
class
));
messageConverters
.
add
(
new
RootBeanDefinition
(
StringHttpMessageConverter
.
class
));
messageConverters
.
add
(
new
RootBeanDefinition
(
ResourceHttpMessageConverter
.
class
));
messageConverters
.
add
(
new
RootBeanDefinition
(
FormHttpMessageConverter
.
class
));
messageConverters
.
add
(
new
RootBeanDefinition
(
SourceHttpMessageConverter
.
class
));
if
(
jaxb2Present
)
{
...
...
@@ -175,6 +181,10 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
if
(
jacksonPresent
)
{
messageConverters
.
add
(
new
RootBeanDefinition
(
MappingJacksonHttpMessageConverter
.
class
));
}
if
(
romePresent
)
{
messageConverters
.
add
(
new
RootBeanDefinition
(
AtomFeedHttpMessageConverter
.
class
));
messageConverters
.
add
(
new
RootBeanDefinition
(
RssChannelHttpMessageConverter
.
class
));
}
return
messageConverters
;
}
...
...
org.springframework.web/src/main/java/org/springframework/http/HttpHeaders.java
浏览文件 @
def90d10
...
...
@@ -64,6 +64,8 @@ public class HttpHeaders implements MultiValueMap<String, String> {
private
static
final
String
CACHE_CONTROL
=
"Cache-Control"
;
private
static
final
String
CONTENT_DISPOSITION
=
"Content-Disposition"
;
private
static
final
String
CONTENT_LENGTH
=
"Content-Length"
;
private
static
final
String
CONTENT_TYPE
=
"Content-Type"
;
...
...
@@ -95,6 +97,7 @@ public class HttpHeaders implements MultiValueMap<String, String> {
private
final
Map
<
String
,
List
<
String
>>
headers
;
/**
* Private constructor that can create read-only {@code HttpHeader} instances.
*/
...
...
@@ -229,6 +232,22 @@ public class HttpHeaders implements MultiValueMap<String, String> {
return
getFirst
(
CACHE_CONTROL
);
}
/**
* Sets the (new) value of the {@code Content-Disposition} header for {@code form-data}.
* @param name the control name
* @param filename the filename, may be {@code null}
*/
public
void
setContentDispositionFormData
(
String
name
,
String
filename
)
{
Assert
.
notNull
(
name
,
"'name' must not be null"
);
StringBuilder
builder
=
new
StringBuilder
(
"form-data; name=\""
);
builder
.
append
(
name
).
append
(
'\"'
);
if
(
filename
!=
null
)
{
builder
.
append
(
"; filename=\""
);
builder
.
append
(
filename
).
append
(
'\"'
);
}
set
(
CONTENT_DISPOSITION
,
builder
.
toString
());
}
/**
* Set the length of the body in bytes, as specified by the {@code Content-Length} header.
* @param contentLength the content length
...
...
org.springframework.web/src/main/java/org/springframework/http/MediaType.java
浏览文件 @
def90d10
...
...
@@ -49,10 +49,75 @@ import org.springframework.util.StringUtils;
public
class
MediaType
implements
Comparable
<
MediaType
>
{
/**
* Public constant that includes all media ranges (i.e. <code>*/*</code>).
* Public constant
media type
that includes all media ranges (i.e. <code>*/*</code>).
*/
public
static
final
MediaType
ALL
;
/**
* Public constant media type for {@code application/atom+xml}.
*/
public
final
static
MediaType
APPLICATION_ATOM_XML
;
/**
* Public constant media type for {@code application/x-www-form-urlencoded}.
* */
public
final
static
MediaType
APPLICATION_FORM_URLENCODED
;
/**
* Public constant media type for {@code application/json}.
* */
public
final
static
MediaType
APPLICATION_JSON
;
/**
* Public constant media type for {@code application/octet-stream}.
* */
public
final
static
MediaType
APPLICATION_OCTET_STREAM
;
/**
* Public constant media type for {@code application/xhtml+xml}.
* */
public
final
static
MediaType
APPLICATION_XHTML_XML
;
/**
* Public constant media type for {@code image/gif}.
*/
public
final
static
MediaType
IMAGE_GIF
;
/**
* Public constant media type for {@code image/jpeg}.
*/
public
final
static
MediaType
IMAGE_JPEG
;
/**
* Public constant media type for {@code image/png}.
*/
public
final
static
MediaType
IMAGE_PNG
;
/**
* Public constant media type for {@code image/xml}.
*/
public
final
static
MediaType
APPLICATION_XML
;
/**
* Public constant media type for {@code multipart/form-data}.
* */
public
final
static
MediaType
MULTIPART_FORM_DATA
;
/**
* Public constant media type for {@code text/html}.
* */
public
final
static
MediaType
TEXT_HTML
;
/**
* Public constant media type for {@code text/plain}.
* */
public
final
static
MediaType
TEXT_PLAIN
;
/**
* Public constant media type for {@code text/xml}.
* */
public
final
static
MediaType
TEXT_XML
;
private
static
final
BitSet
TOKEN
;
private
static
final
String
WILDCARD_TYPE
=
"*"
;
...
...
@@ -104,6 +169,19 @@ public class MediaType implements Comparable<MediaType> {
TOKEN
.
andNot
(
separators
);
ALL
=
new
MediaType
(
"*"
,
"*"
);
APPLICATION_ATOM_XML
=
new
MediaType
(
"application"
,
"atom+xml"
);
APPLICATION_FORM_URLENCODED
=
new
MediaType
(
"application"
,
"x-www-form-urlencoded"
);
APPLICATION_JSON
=
new
MediaType
(
"application"
,
"json"
);
APPLICATION_OCTET_STREAM
=
new
MediaType
(
"application"
,
"octet-stream"
);
APPLICATION_XHTML_XML
=
new
MediaType
(
"application"
,
"xhtml+xml"
);
APPLICATION_XML
=
new
MediaType
(
"application"
,
"xml"
);
IMAGE_GIF
=
new
MediaType
(
"image"
,
"gif"
);
IMAGE_JPEG
=
new
MediaType
(
"image"
,
"jpeg"
);
IMAGE_PNG
=
new
MediaType
(
"image"
,
"png"
);
MULTIPART_FORM_DATA
=
new
MediaType
(
"multipart"
,
"form-data"
);
TEXT_HTML
=
new
MediaType
(
"text"
,
"html"
);
TEXT_PLAIN
=
new
MediaType
(
"text"
,
"plain"
);
TEXT_XML
=
new
MediaType
(
"text"
,
"xml"
);
}
/**
...
...
@@ -153,12 +231,24 @@ public class MediaType implements Comparable<MediaType> {
this
(
type
,
subtype
,
Collections
.
singletonMap
(
PARAM_QUALITY_FACTOR
,
Double
.
toString
(
qualityValue
)));
}
/**
* Copy-constructor that copies the type and subtype of the given {@link MediaType}, and allows for different
* parameter.
*
* @param other the other media type
* @param parameters the parameters, may be <code>null</code>
* @throws IllegalArgumentException if any of the parameters contain illegal characters
*/
public
MediaType
(
MediaType
other
,
Map
<
String
,
String
>
parameters
)
{
this
(
other
.
getType
(),
other
.
getSubtype
(),
parameters
);
}
/**
* Create a new {@link MediaType} for the given type, subtype, and parameters.
*
* @param type the primary type
* @param subtype the subtype
* @param parameters the parameters, ma
t
be <code>null</code>
* @param parameters the parameters, ma
y
be <code>null</code>
* @throws IllegalArgumentException if any of the parameters contain illegal characters
*/
public
MediaType
(
String
type
,
String
subtype
,
Map
<
String
,
String
>
parameters
)
{
...
...
org.springframework.web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java
0 → 100644
浏览文件 @
def90d10
/*
* Copyright 2002-2010 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.http.converter
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.Collections
;
import
java.util.List
;
import
javax.activation.FileTypeMap
;
import
javax.activation.MimetypesFileTypeMap
;
import
org.springframework.core.io.ByteArrayResource
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpInputMessage
;
import
org.springframework.http.HttpOutputMessage
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.FileCopyUtils
;
import
org.springframework.util.StringUtils
;
/**
* Implementation of {@link HttpMessageConverter} that can read and write {@link Resource Resources}.
*
* <p>By default, this converter can read all media types. The Java Activation Framework (JAF) - if available - is used
* to determine the {@code Content-Type} of written resources. If JAF is not available, {@code application/octet-stream}
* is used.
*
* @author Arjen Poutsma
* @since 3.0.2
*/
public
class
ResourceHttpMessageConverter
implements
HttpMessageConverter
<
Resource
>
{
private
static
final
boolean
jafPresent
=
ClassUtils
.
isPresent
(
"javax.activation.FileTypeMap"
,
ResourceHttpMessageConverter
.
class
.
getClassLoader
());
public
boolean
canRead
(
Class
<?>
clazz
,
MediaType
mediaType
)
{
return
Resource
.
class
.
isAssignableFrom
(
clazz
);
}
public
boolean
canWrite
(
Class
<?>
clazz
,
MediaType
mediaType
)
{
return
Resource
.
class
.
isAssignableFrom
(
clazz
);
}
public
List
<
MediaType
>
getSupportedMediaTypes
()
{
return
Collections
.
singletonList
(
MediaType
.
ALL
);
}
public
Resource
read
(
Class
<?
extends
Resource
>
clazz
,
HttpInputMessage
inputMessage
)
throws
IOException
,
HttpMessageNotReadableException
{
byte
[]
body
=
FileCopyUtils
.
copyToByteArray
(
inputMessage
.
getBody
());
return
new
ByteArrayResource
(
body
);
}
public
void
write
(
Resource
resource
,
MediaType
contentType
,
HttpOutputMessage
outputMessage
)
throws
IOException
,
HttpMessageNotWritableException
{
HttpHeaders
headers
=
outputMessage
.
getHeaders
();
if
(
contentType
==
null
||
contentType
.
isWildcardType
()
||
contentType
.
isWildcardSubtype
())
{
contentType
=
getContentType
(
resource
);
}
if
(
contentType
!=
null
)
{
headers
.
setContentType
(
contentType
);
}
Long
contentLength
=
getContentLength
(
resource
,
contentType
);
if
(
contentLength
!=
null
)
{
headers
.
setContentLength
(
contentLength
);
}
FileCopyUtils
.
copy
(
resource
.
getInputStream
(),
outputMessage
.
getBody
());
outputMessage
.
getBody
().
flush
();
}
private
MediaType
getContentType
(
Resource
resource
)
{
if
(
jafPresent
)
{
return
ActivationMediaTypeFactory
.
getMediaType
(
resource
);
}
else
{
return
MediaType
.
APPLICATION_OCTET_STREAM
;
}
}
protected
Long
getContentLength
(
Resource
resource
,
MediaType
contentType
)
{
try
{
return
resource
.
getFile
().
length
();
}
catch
(
IOException
e
)
{
return
null
;
}
}
/**
* Inner class to avoid hard-coded JAF dependency.
*/
private
static
class
ActivationMediaTypeFactory
{
private
static
final
FileTypeMap
fileTypeMap
;
static
{
fileTypeMap
=
loadFileTypeMapFromContextSupportModule
();
}
private
static
FileTypeMap
loadFileTypeMapFromContextSupportModule
()
{
// see if we can find the extended mime.types from the context-support module
Resource
mappingLocation
=
new
ClassPathResource
(
"org/springframework/mail/javamail/mime.types"
);
if
(
mappingLocation
.
exists
())
{
InputStream
inputStream
=
null
;
try
{
inputStream
=
mappingLocation
.
getInputStream
();
return
new
MimetypesFileTypeMap
(
inputStream
);
}
catch
(
IOException
ex
)
{
// ignore
}
finally
{
if
(
inputStream
!=
null
)
{
try
{
inputStream
.
close
();
}
catch
(
IOException
ex
)
{
// ignore
}
}
}
}
return
FileTypeMap
.
getDefaultFileTypeMap
();
}
public
static
MediaType
getMediaType
(
Resource
resource
)
{
String
mediaType
=
fileTypeMap
.
getContentType
(
resource
.
getFilename
());
return
StringUtils
.
hasText
(
mediaType
)
?
MediaType
.
parseMediaType
(
mediaType
)
:
null
;
}
}
}
org.springframework.web/src/main/java/org/springframework/http/converter/StringHttpMessageConverter.java
浏览文件 @
def90d10
...
...
@@ -45,11 +45,21 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
private
final
List
<
Charset
>
availableCharsets
;
private
boolean
writeAcceptCharset
=
true
;
public
StringHttpMessageConverter
()
{
super
(
new
MediaType
(
"text"
,
"plain"
,
DEFAULT_CHARSET
),
MediaType
.
ALL
);
this
.
availableCharsets
=
new
ArrayList
<
Charset
>(
Charset
.
availableCharsets
().
values
());
}
/**
* Indicates whether the {@code Accept-Charset} should be written to any outgoing request.
* <p>Default is {@code true}.
*/
public
void
setWriteAcceptCharset
(
boolean
writeAcceptCharset
)
{
this
.
writeAcceptCharset
=
writeAcceptCharset
;
}
@Override
public
boolean
supports
(
Class
<?>
clazz
)
{
return
String
.
class
.
equals
(
clazz
);
...
...
@@ -81,7 +91,9 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
@Override
protected
void
writeInternal
(
String
s
,
HttpOutputMessage
outputMessage
)
throws
IOException
{
outputMessage
.
getHeaders
().
setAcceptCharset
(
getAcceptedCharsets
());
if
(
writeAcceptCharset
)
{
outputMessage
.
getHeaders
().
setAcceptCharset
(
getAcceptedCharsets
());
}
MediaType
contentType
=
outputMessage
.
getHeaders
().
getContentType
();
Charset
charset
=
contentType
.
getCharSet
()
!=
null
?
contentType
.
getCharSet
()
:
DEFAULT_CHARSET
;
FileCopyUtils
.
copy
(
s
,
new
OutputStreamWriter
(
outputMessage
.
getBody
(),
charset
));
...
...
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/ByteArrayPart.java
已删除
100644 → 0
浏览文件 @
f30b0a86
/*
* Copyright 2002-2010 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.http.converter.multipart
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.Assert
;
import
org.springframework.util.FileCopyUtils
;
/**
* @author Arjen Poutsma
* @since 3.0.2
*/
class
ByteArrayPart
extends
AbstractPart
{
private
final
byte
[]
value
;
public
ByteArrayPart
(
byte
[]
value
,
MediaType
contentType
)
{
super
(
contentType
);
Assert
.
isTrue
(
value
!=
null
&&
value
.
length
!=
0
,
"'value' must not be null"
);
this
.
value
=
value
;
}
@Override
protected
void
writeData
(
OutputStream
os
)
throws
IOException
{
FileCopyUtils
.
copy
(
value
,
os
);
}
}
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/MultipartHttpMessageConverter.java
浏览文件 @
def90d10
...
...
@@ -18,26 +18,41 @@ package org.springframework.http.converter.multipart;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.UnsupportedEncodingException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Random
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpInputMessage
;
import
org.springframework.http.HttpOutputMessage
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.converter.AbstractHttpMessageConverter
;
import
org.springframework.http.converter.ByteArrayHttpMessageConverter
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.converter.HttpMessageNotReadableException
;
import
org.springframework.http.converter.HttpMessageNotWritableException
;
import
org.springframework.http.converter.ResourceHttpMessageConverter
;
import
org.springframework.http.converter.StringHttpMessageConverter
;
import
org.springframework.http.converter.xml.SourceHttpMessageConverter
;
import
org.springframework.util.Assert
;
/**
* Implementation of {@link org.springframework.http.converter.HttpMessageConverter} that can write multipart form data
* (i.e. file uploads).
*
* <p>This converter writes the media type ({@code multipart/form-data}). Multipart form data is provided as
* a {@link MultipartMap}.
*
* <p>Inspired by {@link org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity}.
*
* @author Arjen Poutsma
* @see MultipartMap
* @since 3.0.2
*/
public
class
MultipartHttpMessageConverter
extends
Abstract
HttpMessageConverter
<
MultipartMap
>
{
public
class
MultipartHttpMessageConverter
implements
HttpMessageConverter
<
MultipartMap
>
{
private
static
final
byte
[]
BOUNDARY_CHARS
=
new
byte
[]{
'-'
,
'_'
,
...
...
@@ -47,39 +62,126 @@ public class MultipartHttpMessageConverter extends AbstractHttpMessageConverter<
private
final
Random
rnd
=
new
Random
();
private
List
<
HttpMessageConverter
<?>>
partConverters
=
new
ArrayList
<
HttpMessageConverter
<?>>();
public
MultipartHttpMessageConverter
()
{
super
(
new
MediaType
(
"multipart"
,
"form-data"
));
this
.
partConverters
.
add
(
new
ByteArrayHttpMessageConverter
());
StringHttpMessageConverter
stringHttpMessageConverter
=
new
StringHttpMessageConverter
();
stringHttpMessageConverter
.
setWriteAcceptCharset
(
false
);
this
.
partConverters
.
add
(
stringHttpMessageConverter
);
this
.
partConverters
.
add
(
new
ResourceHttpMessageConverter
());
this
.
partConverters
.
add
(
new
SourceHttpMessageConverter
());
}
/**
* Set the message body converters to use. These converters are used to convert to MIME parts.
*/
public
void
setPartConverters
(
List
<
HttpMessageConverter
<?>>
partConverters
)
{
Assert
.
notEmpty
(
partConverters
,
"'messageConverters' must not be empty"
);
this
.
partConverters
=
partConverters
;
}
@Override
protected
boolean
supports
(
Class
<?>
clazz
)
{
return
MultipartMap
.
class
.
isAssignableFrom
(
clazz
);
/**
* Returns {@code false}, as reading multipart data is not supported.
*/
public
boolean
canRead
(
Class
<?>
clazz
,
MediaType
mediaType
)
{
return
false
;
}
@Override
protected
void
writeInternal
(
MultipartMap
map
,
HttpOutputMessage
outputMessage
)
public
boolean
canWrite
(
Class
<?>
clazz
,
MediaType
mediaType
)
{
if
(!
MultipartMap
.
class
.
isAssignableFrom
(
clazz
))
{
return
false
;
}
if
(
mediaType
!=
null
)
{
return
mediaType
.
includes
(
MediaType
.
MULTIPART_FORM_DATA
);
}
else
{
return
true
;
}
}
public
List
<
MediaType
>
getSupportedMediaTypes
()
{
return
Collections
.
singletonList
(
MediaType
.
MULTIPART_FORM_DATA
);
}
public
MultipartMap
read
(
Class
<?
extends
MultipartMap
>
clazz
,
HttpInputMessage
inputMessage
)
throws
IOException
,
HttpMessageNotReadableException
{
throw
new
UnsupportedOperationException
();
}
public
void
write
(
MultipartMap
map
,
MediaType
contentType
,
HttpOutputMessage
outputMessage
)
throws
IOException
,
HttpMessageNotWritableException
{
byte
[]
boundary
=
generateBoundary
();
HttpHeaders
headers
=
outputMessage
.
getHeaders
();
MediaType
contentType
=
headers
.
getContentType
();
if
(
contentType
!=
null
)
{
String
boundaryString
=
new
String
(
boundary
,
"US-ASCII"
);
Map
<
String
,
String
>
params
=
Collections
.
singletonMap
(
"boundary"
,
boundaryString
);
contentType
=
new
MediaType
(
contentType
.
getType
(),
contentType
.
getSubtype
(),
params
);
headers
.
setContentType
(
contentType
);
}
OutputStream
os
=
outputMessage
.
getBody
();
for
(
Map
.
Entry
<
String
,
List
<
Part
>>
entry
:
map
.
entrySet
())
{
setContentType
(
headers
,
boundary
);
writeParts
(
os
,
map
,
boundary
);
writeEnd
(
boundary
,
os
);
}
private
void
setContentType
(
HttpHeaders
headers
,
byte
[]
boundary
)
throws
UnsupportedEncodingException
{
Map
<
String
,
String
>
parameters
=
Collections
.
singletonMap
(
"boundary"
,
new
String
(
boundary
,
"US-ASCII"
));
MediaType
contentType
=
new
MediaType
(
MediaType
.
MULTIPART_FORM_DATA
,
parameters
);
headers
.
setContentType
(
contentType
);
}
private
void
writeParts
(
OutputStream
os
,
MultipartMap
map
,
byte
[]
boundary
)
throws
IOException
{
for
(
Map
.
Entry
<
String
,
List
<
Object
>>
entry
:
map
.
entrySet
())
{
String
name
=
entry
.
getKey
();
for
(
Part
part
:
entry
.
getValue
())
{
part
.
write
(
boundary
,
name
,
os
);
for
(
Object
part
:
entry
.
getValue
())
{
writeBoundary
(
boundary
,
os
);
writePart
(
name
,
part
,
os
);
writeNewLine
(
os
);
}
}
}
private
void
writeBoundary
(
byte
[]
boundary
,
OutputStream
os
)
throws
IOException
{
os
.
write
(
'-'
);
os
.
write
(
'-'
);
os
.
write
(
boundary
);
writeNewLine
(
os
);
}
@SuppressWarnings
(
"unchecked"
)
private
void
writePart
(
String
name
,
Object
part
,
OutputStream
os
)
throws
IOException
{
Class
<?>
partType
=
part
.
getClass
();
for
(
HttpMessageConverter
messageConverter
:
partConverters
)
{
if
(
messageConverter
.
canWrite
(
partType
,
null
))
{
HttpOutputMessage
multipartOutputMessage
=
new
MultipartHttpOutputMessage
(
os
);
multipartOutputMessage
.
getHeaders
().
setContentDispositionFormData
(
name
,
getFileName
(
part
));
messageConverter
.
write
(
part
,
null
,
multipartOutputMessage
);
return
;
}
}
throw
new
HttpMessageNotWritableException
(
"Could not write request: no suitable HttpMessageConverter found for request type ["
+
partType
.
getName
()
+
"]"
);
}
protected
String
getFileName
(
Object
part
)
{
if
(
part
instanceof
Resource
)
{
Resource
resource
=
(
Resource
)
part
;
return
resource
.
getFilename
();
}
else
{
return
null
;
}
}
private
void
writeEnd
(
byte
[]
boundary
,
OutputStream
os
)
throws
IOException
{
os
.
write
(
'-'
);
os
.
write
(
'-'
);
os
.
write
(
boundary
);
os
.
write
(
'-'
);
os
.
write
(
'-'
);
writeNewLine
(
os
);
}
private
void
writeNewLine
(
OutputStream
os
)
throws
IOException
{
os
.
write
(
'\r'
);
os
.
write
(
'\n'
);
}
...
...
@@ -99,15 +201,4 @@ public class MultipartHttpMessageConverter extends AbstractHttpMessageConverter<
return
boundary
;
}
@Override
public
boolean
canRead
(
Class
<?>
clazz
,
MediaType
mediaType
)
{
// reading not supported yet
return
false
;
}
@Override
protected
MultipartMap
readInternal
(
Class
<?
extends
MultipartMap
>
clazz
,
HttpInputMessage
inputMessage
)
throws
IOException
,
HttpMessageNotReadableException
{
throw
new
UnsupportedOperationException
();
}
}
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/
AbstractPart
.java
→
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/
MultipartHttpOutputMessage
.java
浏览文件 @
def90d10
...
...
@@ -19,59 +19,60 @@ package org.springframework.http.converter.multipart;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.UnsupportedEncodingException
;
import
java.util.List
;
import
java.util.Map
;
import
org.springframework.http.
MediaType
;
import
org.springframework.
util.Assert
;
import
org.springframework.http.
HttpHeaders
;
import
org.springframework.
http.HttpOutputMessage
;
/**
*
<p>Inspired by {@link org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity}
.
*
Implementation of {@link HttpOutputMessage} used for writing multipart data
.
*
* @author Arjen Poutsma
* @since 3.0.2
*/
abstract
class
AbstractPart
implements
Part
{
class
MultipartHttpOutputMessage
implements
HttpOutputMessage
{
private
static
final
byte
[]
CONTENT_DISPOSITION
=
new
byte
[]{
'C'
,
'o'
,
'n'
,
't'
,
'e'
,
'n'
,
't'
,
'-'
,
'D'
,
'i'
,
's'
,
'p'
,
'o'
,
's'
,
'i'
,
't'
,
'i'
,
'o'
,
'n'
,
':'
,
' '
,
'f'
,
'o'
,
'r'
,
'm'
,
'-'
,
'd'
,
'a'
,
't'
,
'a'
,
';'
,
' '
,
'n'
,
'a'
,
'm'
,
'e'
,
'='
};
private
final
HttpHeaders
headers
=
new
HttpHeaders
();
private
static
final
byte
[]
CONTENT_TYPE
=
new
byte
[]{
'C'
,
'o'
,
'n'
,
't'
,
'e'
,
'n'
,
't'
,
'-'
,
'T'
,
'y'
,
'p'
,
'e'
,
':'
,
' '
};
private
final
OutputStream
os
;
private
final
MediaType
contentTyp
e
;
private
boolean
headersWritten
=
fals
e
;
protected
AbstractPart
(
MediaType
contentType
)
{
Assert
.
notNull
(
contentType
,
"'contentType' must not be null"
);
this
.
contentType
=
contentType
;
public
MultipartHttpOutputMessage
(
OutputStream
os
)
{
this
.
os
=
os
;
}
public
final
void
write
(
byte
[]
boundary
,
String
name
,
OutputStream
os
)
throws
IOException
{
writeBoundary
(
boundary
,
os
);
writeContentDisposition
(
name
,
os
);
writeContentType
(
os
);
writeEndOfHeader
(
os
);
writeData
(
os
);
writeEnd
(
os
);
public
HttpHeaders
getHeaders
()
{
return
headersWritten
?
HttpHeaders
.
readOnlyHttpHeaders
(
headers
)
:
this
.
headers
;
}
protected
void
writeBoundary
(
byte
[]
boundary
,
OutputStream
os
)
throws
IOException
{
os
.
write
(
'-'
);
os
.
write
(
'-'
);
os
.
write
(
boundary
);
writeNewLine
(
os
);
public
OutputStream
getBody
()
throws
IOException
{
writeHeaders
();
return
this
.
os
;
}
protected
void
writeContentDisposition
(
String
name
,
OutputStream
os
)
throws
IOException
{
os
.
write
(
CONTENT_DISPOSITION
);
os
.
write
(
'"'
);
os
.
write
(
getAsciiBytes
(
name
));
os
.
write
(
'"'
);
private
void
writeHeaders
()
throws
IOException
{
if
(!
this
.
headersWritten
)
{
for
(
Map
.
Entry
<
String
,
List
<
String
>>
entry
:
this
.
headers
.
entrySet
())
{
byte
[]
headerName
=
getAsciiBytes
(
entry
.
getKey
());
for
(
String
headerValueString
:
entry
.
getValue
())
{
byte
[]
headerValue
=
getAsciiBytes
(
headerValueString
);
os
.
write
(
headerName
);
os
.
write
(
':'
);
os
.
write
(
' '
);
os
.
write
(
headerValue
);
writeNewLine
(
os
);
}
}
writeNewLine
(
os
);
this
.
headersWritten
=
true
;
}
}
protected
void
writeContentType
(
OutputStream
os
)
throws
IOException
{
writeNewLine
(
os
);
os
.
write
(
CONTENT_TYPE
);
os
.
write
(
getAsciiBytes
(
contentType
.
toString
()));
private
void
writeNewLine
(
OutputStream
os
)
throws
IOException
{
os
.
write
(
'\r'
);
os
.
write
(
'\n'
);
}
protected
byte
[]
getAsciiBytes
(
String
name
)
{
...
...
@@ -84,20 +85,5 @@ abstract class AbstractPart implements Part {
}
}
protected
void
writeEndOfHeader
(
OutputStream
os
)
throws
IOException
{
writeNewLine
(
os
);
writeNewLine
(
os
);
}
protected
void
writeEnd
(
OutputStream
os
)
throws
IOException
{
writeNewLine
(
os
);
}
private
void
writeNewLine
(
OutputStream
os
)
throws
IOException
{
os
.
write
(
'\r'
);
os
.
write
(
'\n'
);
}
protected
abstract
void
writeData
(
OutputStream
os
)
throws
IOException
;
}
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/MultipartMap.java
浏览文件 @
def90d10
...
...
@@ -16,52 +16,22 @@
package
org.springframework.http.converter.multipart
;
import
java.io.File
;
import
java.nio.charset.Charset
;
import
org.springframework.core.io.FileSystemResource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.Assert
;
import
org.springframework.util.LinkedMultiValueMap
;
/**
* Represents HTTP multipart form data, mapping names to parts.
*
* <p>In addition to the normal methods defined by {@link org.springframework.util.MultiValueMap}, this class offers
* the following convenience methods:
* <ul>
* <li>{@link #addTextPart} to add a text part (i.e. a form field)</li>
* <li>{@link #addBinaryPart} to add a binary part (i.e. a file)</li>
* <li>{@link #addPart} to add a custom part</li>
* </ul>
*
* @author Arjen Poutsma
* @since 3.0.2
*/
public
class
MultipartMap
extends
LinkedMultiValueMap
<
String
,
Part
>
{
public
void
addTextPart
(
String
name
,
String
value
)
{
Assert
.
hasText
(
name
,
"'name' must not be empty"
);
add
(
name
,
new
StringPart
(
value
));
}
public
void
addTextPart
(
String
name
,
String
value
,
Charset
charset
)
{
Assert
.
hasText
(
name
,
"'name' must not be empty"
);
add
(
name
,
new
StringPart
(
value
,
charset
));
}
public
void
addBinaryPart
(
String
name
,
Resource
resource
)
{
Assert
.
hasText
(
name
,
"'name' must not be empty"
);
add
(
name
,
new
ResourcePart
(
resource
));
}
public
void
addBinaryPart
(
Resource
resource
)
{
Assert
.
notNull
(
resource
,
"'resource' must not be null"
);
addBinaryPart
(
resource
.
getFilename
(),
resource
);
}
public
void
addBinaryPart
(
String
name
,
File
file
)
{
addBinaryPart
(
name
,
new
FileSystemResource
(
file
));
}
public
void
addBinaryPart
(
File
file
)
{
addBinaryPart
(
new
FileSystemResource
(
file
));
}
public
void
addPart
(
String
name
,
byte
[]
value
,
MediaType
contentType
)
{
Assert
.
hasText
(
name
,
"'name' must not be empty"
);
add
(
name
,
new
ByteArrayPart
(
value
,
contentType
));
}
public
class
MultipartMap
extends
LinkedMultiValueMap
<
String
,
Object
>
{
}
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/Part.java
已删除
100644 → 0
浏览文件 @
f30b0a86
/*
* Copyright 2002-2010 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.http.converter.multipart
;
import
java.io.IOException
;
import
java.io.OutputStream
;
/**
* @author Arjen Poutsma
* @since 3.0.2
*/
public
interface
Part
{
void
write
(
byte
[]
boundary
,
String
name
,
OutputStream
os
)
throws
IOException
;
}
org.springframework.web/src/main/java/org/springframework/http/converter/multipart/StringPart.java
已删除
100644 → 0
浏览文件 @
f30b0a86
/*
* Copyright 2002-2010 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.http.converter.multipart
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.OutputStreamWriter
;
import
java.nio.charset.Charset
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.Assert
;
import
org.springframework.util.FileCopyUtils
;
/** @author Arjen Poutsma */
class
StringPart
extends
AbstractPart
{
private
static
final
Charset
DEFAULT_CHARSET
=
Charset
.
forName
(
"ISO-8859-1"
);
private
final
String
value
;
private
final
Charset
charset
;
public
StringPart
(
String
value
)
{
this
(
value
,
DEFAULT_CHARSET
);
}
public
StringPart
(
String
value
,
Charset
charset
)
{
super
(
new
MediaType
(
"text"
,
"plain"
,
charset
));
Assert
.
hasText
(
value
,
"'value' must not be null"
);
Assert
.
notNull
(
charset
,
"'charset' must not be null"
);
this
.
value
=
value
;
this
.
charset
=
charset
;
}
@Override
protected
void
writeData
(
OutputStream
os
)
throws
IOException
{
FileCopyUtils
.
copy
(
value
,
new
OutputStreamWriter
(
os
,
charset
));
}
}
org.springframework.web/src/main/java/org/springframework/web/client/RestTemplate.java
浏览文件 @
def90d10
...
...
@@ -35,7 +35,10 @@ import org.springframework.http.client.support.HttpAccessor;
import
org.springframework.http.converter.ByteArrayHttpMessageConverter
;
import
org.springframework.http.converter.FormHttpMessageConverter
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.converter.ResourceHttpMessageConverter
;
import
org.springframework.http.converter.StringHttpMessageConverter
;
import
org.springframework.http.converter.feed.AtomFeedHttpMessageConverter
;
import
org.springframework.http.converter.feed.RssChannelHttpMessageConverter
;
import
org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
;
import
org.springframework.http.converter.multipart.MultipartHttpMessageConverter
;
import
org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter
;
...
...
@@ -111,6 +114,9 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
ClassUtils
.
isPresent
(
"org.codehaus.jackson.map.ObjectMapper"
,
RestTemplate
.
class
.
getClassLoader
())
&&
ClassUtils
.
isPresent
(
"org.codehaus.jackson.JsonGenerator"
,
RestTemplate
.
class
.
getClassLoader
());
private
static
boolean
romePresent
=
ClassUtils
.
isPresent
(
"com.sun.syndication.feed.WireFeed"
,
RestTemplate
.
class
.
getClassLoader
());
private
final
ResponseExtractor
<
HttpHeaders
>
headersExtractor
=
new
HeadersExtractor
();
...
...
@@ -123,6 +129,7 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
public
RestTemplate
()
{
this
.
messageConverters
.
add
(
new
ByteArrayHttpMessageConverter
());
this
.
messageConverters
.
add
(
new
StringHttpMessageConverter
());
this
.
messageConverters
.
add
(
new
ResourceHttpMessageConverter
());
this
.
messageConverters
.
add
(
new
MultipartHttpMessageConverter
());
this
.
messageConverters
.
add
(
new
FormHttpMessageConverter
());
this
.
messageConverters
.
add
(
new
SourceHttpMessageConverter
());
...
...
@@ -132,6 +139,10 @@ public class RestTemplate extends HttpAccessor implements RestOperations {
if
(
jacksonPresent
)
{
this
.
messageConverters
.
add
(
new
MappingJacksonHttpMessageConverter
());
}
if
(
romePresent
)
{
this
.
messageConverters
.
add
(
new
AtomFeedHttpMessageConverter
());
this
.
messageConverters
.
add
(
new
RssChannelHttpMessageConverter
());
}
}
/**
...
...
org.springframework.web/src/test/java/org/springframework/http/HttpHeadersTests.java
浏览文件 @
def90d10
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
10
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.
...
...
@@ -210,5 +210,15 @@ public class HttpHeadersTests {
assertEquals
(
"Invalid Cache-Control header"
,
"no-cache"
,
headers
.
getFirst
(
"cache-control"
));
}
@Test
public
void
contentDisposition
()
{
headers
.
setContentDispositionFormData
(
"name"
,
null
);
assertEquals
(
"Invalid Content-Disposition header"
,
"form-data; name=\"name\""
,
headers
.
getFirst
(
"Content-Disposition"
));
headers
.
setContentDispositionFormData
(
"name"
,
"filename"
);
assertEquals
(
"Invalid Content-Disposition header"
,
"form-data; name=\"name\"; filename=\"filename\""
,
headers
.
getFirst
(
"Content-Disposition"
));
}
}
org.springframework.web/src/test/java/org/springframework/http/MediaTypeTests.java
浏览文件 @
def90d10
...
...
@@ -31,7 +31,7 @@ public class MediaTypeTests {
@Test
public
void
includes
()
throws
Exception
{
MediaType
textPlain
=
new
MediaType
(
"text"
,
"plain"
)
;
MediaType
textPlain
=
MediaType
.
TEXT_PLAIN
;
assertTrue
(
"Equal types is not inclusive"
,
textPlain
.
includes
(
textPlain
));
MediaType
allText
=
new
MediaType
(
"text"
);
assertTrue
(
"All subtypes is not inclusive"
,
allText
.
includes
(
textPlain
));
...
...
org.springframework.web/src/
main/java/org/springframework/http/converter/multipart/ResourcePart
.java
→
org.springframework.web/src/
test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests
.java
浏览文件 @
def90d10
...
...
@@ -14,45 +14,60 @@
* limitations under the License.
*/
package
org.springframework.http.converter
.multipart
;
package
org.springframework.http.converter
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
static
org
.
junit
.
Assert
.*;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.Assert
;
import
org.springframework.http.MockHttpInputMessage
;
import
org.springframework.http.MockHttpOutputMessage
;
import
org.springframework.util.FileCopyUtils
;
import
org.springframework.util.StringUtils
;
/** @author Arjen Poutsma */
class
ResourcePart
extends
AbstractPart
{
/**
* @author Arjen Poutsma
*/
public
class
ResourceHttpMessageConverterTests
{
private
ResourceHttpMessageConverter
converter
;
private
static
final
byte
[]
FILE_NAME
=
new
byte
[]{
';'
,
' '
,
'f'
,
'i'
,
'l'
,
'e'
,
'n'
,
'a'
,
'm'
,
'e'
,
'='
};
@Before
public
void
setUp
()
{
converter
=
new
ResourceHttpMessageConverter
();
}
private
final
Resource
resource
;
@Test
public
void
canRead
()
{
assertTrue
(
converter
.
canRead
(
Resource
.
class
,
new
MediaType
(
"application"
,
"octet-stream"
)));
}
public
ResourcePart
(
Resource
resource
)
{
super
(
new
MediaType
(
"application"
,
"octet-stream"
));
Assert
.
notNull
(
resource
,
"'resource' must not be null"
);
Assert
.
isTrue
(
resource
.
exists
(),
"'"
+
resource
+
"' does not exist"
);
this
.
resource
=
resource
;
@Test
public
void
canWrite
()
{
assertTrue
(
converter
.
canWrite
(
Resource
.
class
,
new
MediaType
(
"application"
,
"octet-stream"
)));
assertTrue
(
converter
.
canWrite
(
Resource
.
class
,
MediaType
.
ALL
));
}
@Override
protected
void
writeContentDisposition
(
String
name
,
OutputStream
os
)
throws
IOException
{
super
.
writeContentDisposition
(
name
,
os
);
String
filename
=
resource
.
getFilename
();
if
(
StringUtils
.
hasLength
(
filename
))
{
os
.
write
(
FILE_NAME
);
os
.
write
(
'"'
);
os
.
write
(
getAsciiBytes
(
filename
));
os
.
write
(
'"'
);
}
@Test
public
void
read
()
throws
IOException
{
byte
[]
body
=
FileCopyUtils
.
copyToByteArray
(
getClass
().
getResourceAsStream
(
"logo.jpg"
));
MockHttpInputMessage
inputMessage
=
new
MockHttpInputMessage
(
body
);
inputMessage
.
getHeaders
().
setContentType
(
MediaType
.
IMAGE_JPEG
);
converter
.
read
(
Resource
.
class
,
inputMessage
);
}
@Override
protected
void
writeData
(
OutputStream
os
)
throws
IOException
{
FileCopyUtils
.
copy
(
resource
.
getInputStream
(),
os
);
@Test
public
void
write
()
throws
IOException
{
MockHttpOutputMessage
outputMessage
=
new
MockHttpOutputMessage
();
Resource
body
=
new
ClassPathResource
(
"logo.jpg"
,
getClass
());
converter
.
write
(
body
,
null
,
outputMessage
);
assertEquals
(
"Invalid content-type"
,
MediaType
.
IMAGE_JPEG
,
outputMessage
.
getHeaders
().
getContentType
());
assertEquals
(
"Invalid content-length"
,
body
.
getFile
().
length
(),
outputMessage
.
getHeaders
().
getContentLength
());
}
}
org.springframework.web/src/test/java/org/springframework/http/converter/multipart/MultipartHttpMessageConverterTest.java
浏览文件 @
def90d10
...
...
@@ -19,7 +19,10 @@ package org.springframework.http.converter.multipart;
import
java.io.ByteArrayInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.StringReader
;
import
java.util.List
;
import
javax.xml.transform.Source
;
import
javax.xml.transform.stream.StreamSource
;
import
org.apache.commons.fileupload.FileItem
;
import
org.apache.commons.fileupload.FileItemFactory
;
...
...
@@ -59,18 +62,19 @@ public class MultipartHttpMessageConverterTest {
@Test
public
void
write
()
throws
Exception
{
MultipartMap
body
=
new
MultipartMap
();
body
.
add
TextPart
(
"name 1"
,
"value 1"
);
body
.
add
TextPart
(
"name 2"
,
"value 2+1"
);
body
.
add
TextPart
(
"name 2"
,
"value 2+2"
);
body
.
add
(
"name 1"
,
"value 1"
);
body
.
add
(
"name 2"
,
"value 2+1"
);
body
.
add
(
"name 2"
,
"value 2+2"
);
Resource
logo
=
new
ClassPathResource
(
"/org/springframework/http/converter/logo.jpg"
);
body
.
add
BinaryPart
(
"logo"
,
logo
);
byte
[]
xml
=
"<root><child/></root>"
.
getBytes
(
"UTF-8"
);
body
.
add
Part
(
"xml"
,
xml
,
new
MediaType
(
"application"
,
"xml"
)
);
body
.
add
(
"logo"
,
logo
);
Source
xml
=
new
StreamSource
(
new
StringReader
(
"<root><child/></root>"
)
);
body
.
add
(
"xml"
,
xml
);
MockHttpOutputMessage
outputMessage
=
new
MockHttpOutputMessage
();
converter
.
write
(
body
,
null
,
outputMessage
);
final
MediaType
contentType
=
outputMessage
.
getHeaders
().
getContentType
();
final
byte
[]
result
=
outputMessage
.
getBodyAsBytes
();
System
.
out
.
println
(
new
String
(
result
));
assertNotNull
(
contentType
);
assertNotNull
(
contentType
.
getParameter
(
"boundary"
));
...
...
@@ -114,13 +118,12 @@ public class MultipartHttpMessageConverterTest {
assertFalse
(
item
.
isFormField
());
assertEquals
(
"logo"
,
item
.
getFieldName
());
assertEquals
(
"logo.jpg"
,
item
.
getName
());
assertEquals
(
"
application/octet-stream
"
,
item
.
getContentType
());
assertEquals
(
"
image/jpeg
"
,
item
.
getContentType
());
assertEquals
(
logo
.
getFile
().
length
(),
item
.
getSize
());
item
=
(
FileItem
)
items
.
get
(
4
);
assertEquals
(
"xml"
,
item
.
getFieldName
());
assertEquals
(
"application/xml"
,
item
.
getContentType
());
assertEquals
(
xml
.
length
,
item
.
getSize
());
}
...
...
org.springframework.web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java
浏览文件 @
def90d10
...
...
@@ -146,11 +146,11 @@ public class RestTemplateIntegrationTests {
@Test
public
void
multipart
()
throws
UnsupportedEncodingException
{
MultipartMap
body
=
new
MultipartMap
();
body
.
add
TextPart
(
"name 1"
,
"value 1"
);
body
.
add
TextPart
(
"name 2"
,
"value 2+1"
);
body
.
add
TextPart
(
"name 2"
,
"value 2+2"
);
body
.
add
(
"name 1"
,
"value 1"
);
body
.
add
(
"name 2"
,
"value 2+1"
);
body
.
add
(
"name 2"
,
"value 2+2"
);
Resource
logo
=
new
ClassPathResource
(
"/org/springframework/http/converter/logo.jpg"
);
body
.
add
BinaryPart
(
"logo"
,
logo
);
body
.
add
(
"logo"
,
logo
);
template
.
postForLocation
(
URI
+
"/multipart"
,
body
);
}
...
...
@@ -261,7 +261,7 @@ public class RestTemplateIntegrationTests {
assertFalse
(
item
.
isFormField
());
assertEquals
(
"logo"
,
item
.
getFieldName
());
assertEquals
(
"logo.jpg"
,
item
.
getName
());
assertEquals
(
"
application/octet-stream
"
,
item
.
getContentType
());
assertEquals
(
"
image/jpeg
"
,
item
.
getContentType
());
}
catch
(
FileUploadException
ex
)
{
throw
new
ServletException
(
ex
);
...
...
org.springframework.web/template.mf
浏览文件 @
def90d10
...
...
@@ -7,6 +7,7 @@ Import-Template:
com.sun.syndication.*;version="[1.0.0, 2.0.0)";resolution:=optional,
org.codehaus.jackson.*;version="[1.0.0, 2.0.0)";resolution:=optional,
com.sun.net.*;version="0";resolution:=optional,
javax.activation.*;version="0";resolution:=optional,
javax.el.*;version="[1.0.0, 3.0.0)";resolution:=optional,
javax.faces.*;version="[1.1.0, 3.0.0)";resolution:=optional,
javax.imageio.*;version="0";resolution:=optional,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录