Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
4fdd8532
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,发现更多精彩内容 >>
提交
4fdd8532
编写于
5月 05, 2017
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Aligned exception handling in Jackson and JAXB codecs
Issue: SPR-15516
上级
1c4babd4
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
96 addition
and
85 deletion
+96
-85
spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java
.../springframework/http/codec/json/Jackson2JsonDecoder.java
+3
-3
spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java
.../springframework/http/codec/json/Jackson2JsonEncoder.java
+7
-4
spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java
...a/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java
+72
-63
spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java
...a/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java
+6
-7
spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java
.../converter/json/AbstractJackson2HttpMessageConverter.java
+7
-7
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java
...ation/AbstractMessageConverterMethodArgumentResolver.java
+1
-1
未找到文件。
spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonDecoder.java
浏览文件 @
4fdd8532
...
...
@@ -117,13 +117,13 @@ public class Jackson2JsonDecoder extends Jackson2CodecSupport implements HttpMes
return
value
;
}
catch
(
InvalidDefinitionException
ex
)
{
throw
new
CodecException
(
"Type definition error: "
+
ex
.
get
Messag
e
(),
ex
);
throw
new
CodecException
(
"Type definition error: "
+
ex
.
get
Typ
e
(),
ex
);
}
catch
(
JsonProcessingException
ex
)
{
throw
new
DecodingException
(
"JSON
parse error: "
+
ex
.
get
Message
(),
ex
);
throw
new
DecodingException
(
"JSON
decoding error: "
+
ex
.
getOriginal
Message
(),
ex
);
}
catch
(
IOException
ex
)
{
throw
new
CodecException
(
"I/O error while reading: "
+
ex
.
getMessage
()
,
ex
);
throw
new
DecodingException
(
"I/O error while parsing input stream"
,
ex
);
}
});
}
...
...
spring-web/src/main/java/org/springframework/http/codec/json/Jackson2JsonEncoder.java
浏览文件 @
4fdd8532
...
...
@@ -32,6 +32,7 @@ import com.fasterxml.jackson.databind.JavaType;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.ObjectWriter
;
import
com.fasterxml.jackson.databind.SerializationFeature
;
import
com.fasterxml.jackson.databind.exc.InvalidDefinitionException
;
import
com.fasterxml.jackson.databind.type.TypeFactory
;
import
org.reactivestreams.Publisher
;
import
reactor.core.publisher.Flux
;
...
...
@@ -51,7 +52,6 @@ import org.springframework.http.server.reactive.ServerHttpResponse;
import
org.springframework.util.Assert
;
import
org.springframework.util.MimeType
;
/**
* Encode from an {@code Object} stream to a byte stream of JSON objects,
* using Jackson 2.9.
...
...
@@ -107,7 +107,7 @@ public class Jackson2JsonEncoder extends Jackson2CodecSupport implements HttpMes
@Override
public
boolean
canEncode
(
ResolvableType
elementType
,
MimeType
mimeType
)
{
Class
<?>
clazz
=
elementType
.
resolve
(
Object
.
class
);
return
Object
.
class
.
equals
(
clazz
)
||
return
(
Object
.
class
==
clazz
)
||
!
String
.
class
.
isAssignableFrom
(
elementType
.
resolve
(
clazz
))
&&
this
.
objectMapper
.
canSerialize
(
clazz
)
&&
supportsMimeType
(
mimeType
);
}
...
...
@@ -166,11 +166,14 @@ public class Jackson2JsonEncoder extends Jackson2CodecSupport implements HttpMes
try
{
writer
.
writeValue
(
outputStream
,
value
);
}
catch
(
InvalidDefinitionException
ex
)
{
throw
new
CodecException
(
"Type definition error: "
+
ex
.
getType
(),
ex
);
}
catch
(
JsonProcessingException
ex
)
{
throw
new
EncodingException
(
"JSON encoding error: "
+
ex
.
getMessage
(),
ex
);
throw
new
EncodingException
(
"JSON encoding error: "
+
ex
.
get
Original
Message
(),
ex
);
}
catch
(
IOException
ex
)
{
throw
new
CodecException
(
"I/O error while writing: "
+
ex
.
getMessage
()
,
ex
);
throw
new
IllegalStateException
(
"Unexpected I/O error while writing to data buffer"
,
ex
);
}
return
buffer
;
...
...
spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java
浏览文件 @
4fdd8532
/*
* Copyright 2002-201
6
the original author or authors.
* Copyright 2002-201
7
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.
...
...
@@ -23,6 +23,7 @@ import java.util.function.Function;
import
javax.xml.XMLConstants
;
import
javax.xml.bind.JAXBElement
;
import
javax.xml.bind.JAXBException
;
import
javax.xml.bind.UnmarshalException
;
import
javax.xml.bind.Unmarshaller
;
import
javax.xml.bind.annotation.XmlRootElement
;
import
javax.xml.bind.annotation.XmlSchema
;
...
...
@@ -37,6 +38,7 @@ import reactor.core.publisher.Mono;
import
org.springframework.core.ResolvableType
;
import
org.springframework.core.codec.AbstractDecoder
;
import
org.springframework.core.codec.CodecException
;
import
org.springframework.core.codec.DecodingException
;
import
org.springframework.core.io.buffer.DataBuffer
;
import
org.springframework.util.ClassUtils
;
...
...
@@ -92,8 +94,7 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
MimeType
mimeType
,
Map
<
String
,
Object
>
hints
)
{
Class
<?>
outputClass
=
elementType
.
getRawClass
();
Flux
<
XMLEvent
>
xmlEventFlux
=
this
.
xmlEventDecoder
.
decode
(
inputStream
,
null
,
mimeType
,
hints
);
Flux
<
XMLEvent
>
xmlEventFlux
=
this
.
xmlEventDecoder
.
decode
(
inputStream
,
null
,
mimeType
,
hints
);
QName
typeName
=
toQName
(
outputClass
);
Flux
<
List
<
XMLEvent
>>
splitEvents
=
split
(
xmlEventFlux
,
typeName
);
...
...
@@ -101,6 +102,26 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
return
splitEvents
.
map
(
events
->
unmarshal
(
events
,
outputClass
));
}
private
Object
unmarshal
(
List
<
XMLEvent
>
events
,
Class
<?>
outputClass
)
{
try
{
Unmarshaller
unmarshaller
=
this
.
jaxbContexts
.
createUnmarshaller
(
outputClass
);
XMLEventReader
eventReader
=
StaxUtils
.
createXMLEventReader
(
events
);
if
(
outputClass
.
isAnnotationPresent
(
XmlRootElement
.
class
))
{
return
unmarshaller
.
unmarshal
(
eventReader
);
}
else
{
JAXBElement
<?>
jaxbElement
=
unmarshaller
.
unmarshal
(
eventReader
,
outputClass
);
return
jaxbElement
.
getValue
();
}
}
catch
(
UnmarshalException
ex
)
{
throw
new
DecodingException
(
"Could not unmarshal XML to "
+
outputClass
,
ex
);
}
catch
(
JAXBException
ex
)
{
throw
new
CodecException
(
"Invalid JAXB configuration"
,
ex
);
}
}
/**
* Returns the qualified name for the given class, according to the mapping rules
* in the JAXB specification.
...
...
@@ -120,8 +141,8 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
namespaceUri
=
annotation
.
namespace
();
}
else
{
throw
new
IllegalArgumentException
(
"Output
class ["
+
outputClass
+
"] is "
+
"neither annotated with @XmlRootElement nor @XmlType"
);
throw
new
IllegalArgumentException
(
"Output
class ["
+
outputClass
.
getName
()
+
"
] is
neither annotated with @XmlRootElement nor @XmlType"
);
}
if
(
JAXB_DEFAULT_ANNOTATION_VALUE
.
equals
(
localPart
))
{
...
...
@@ -129,8 +150,7 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
}
if
(
JAXB_DEFAULT_ANNOTATION_VALUE
.
equals
(
namespaceUri
))
{
Package
outputClassPackage
=
outputClass
.
getPackage
();
if
(
outputClassPackage
!=
null
&&
outputClassPackage
.
isAnnotationPresent
(
XmlSchema
.
class
))
{
if
(
outputClassPackage
!=
null
&&
outputClassPackage
.
isAnnotationPresent
(
XmlSchema
.
class
))
{
XmlSchema
annotation
=
outputClassPackage
.
getAnnotation
(
XmlSchema
.
class
);
namespaceUri
=
annotation
.
namespace
();
}
...
...
@@ -142,21 +162,20 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
}
/**
* Split a flux of {@link XMLEvent}s into a flux of XMLEvent lists, one list for each
* branch of the tree that starts with the given qualified name.
* That is, given the XMLEvents shown
* {@linkplain XmlEventDecoder here},
* and the {@code desiredName} "{@code child}", this method
* returns a flux of two lists, each of which containing the events of a particular
* branch of the tree that starts with "{@code child}".
* Split a flux of {@link XMLEvent}s into a flux of XMLEvent lists, one list
* for each branch of the tree that starts with the given qualified name.
* That is, given the XMLEvents shown {@linkplain XmlEventDecoder here},
* and the {@code desiredName} "{@code child}", this method returns a flux
* of two lists, each of which containing the events of a particular branch
* of the tree that starts with "{@code child}".
* <ol>
* <li>The first list, dealing with the first branch of the tree
* <li>The first list, dealing with the first branch of the tree
:
* <ol>
* <li>{@link javax.xml.stream.events.StartElement} {@code child}</li>
* <li>{@link javax.xml.stream.events.Characters} {@code foo}</li>
* <li>{@link javax.xml.stream.events.EndElement} {@code child}</li>
* </ol>
* <li>The second list, dealing with the second branch of the tree
* <li>The second list, dealing with the second branch of the tree
:
* <ol>
* <li>{@link javax.xml.stream.events.StartElement} {@code child}</li>
* <li>{@link javax.xml.stream.events.Characters} {@code bar}</li>
...
...
@@ -166,57 +185,47 @@ public class Jaxb2XmlDecoder extends AbstractDecoder<Object> {
* </ol>
*/
Flux
<
List
<
XMLEvent
>>
split
(
Flux
<
XMLEvent
>
xmlEventFlux
,
QName
desiredName
)
{
return
xmlEventFlux
.
flatMap
(
new
Function
<
XMLEvent
,
Publisher
<?
extends
List
<
XMLEvent
>>>()
{
private
List
<
XMLEvent
>
events
=
null
;
private
int
elementDepth
=
0
;
private
int
barrier
=
Integer
.
MAX_VALUE
;
@Override
public
Publisher
<?
extends
List
<
XMLEvent
>>
apply
(
XMLEvent
event
)
{
if
(
event
.
isStartElement
())
{
if
(
this
.
barrier
==
Integer
.
MAX_VALUE
)
{
QName
startElementName
=
event
.
asStartElement
().
getName
();
if
(
desiredName
.
equals
(
startElementName
))
{
this
.
events
=
new
ArrayList
<
XMLEvent
>();
this
.
barrier
=
this
.
elementDepth
;
}
}
this
.
elementDepth
++;
}
if
(
this
.
elementDepth
>
this
.
barrier
)
{
this
.
events
.
add
(
event
);
}
if
(
event
.
isEndElement
())
{
this
.
elementDepth
--;
if
(
this
.
elementDepth
==
this
.
barrier
)
{
this
.
barrier
=
Integer
.
MAX_VALUE
;
return
Mono
.
just
(
this
.
events
);
}
}
return
Mono
.
empty
();
}
});
return
xmlEventFlux
.
flatMap
(
new
SplitFunction
(
desiredName
));
}
private
Object
unmarshal
(
List
<
XMLEvent
>
events
,
Class
<?>
outputClass
)
{
try
{
Unmarshaller
unmarshaller
=
this
.
jaxbContexts
.
createUnmarshaller
(
outputClass
);
XMLEventReader
eventReader
=
StaxUtils
.
createXMLEventReader
(
events
);
if
(
outputClass
.
isAnnotationPresent
(
XmlRootElement
.
class
))
{
return
unmarshaller
.
unmarshal
(
eventReader
);
private
static
class
SplitFunction
implements
Function
<
XMLEvent
,
Publisher
<?
extends
List
<
XMLEvent
>>>
{
private
final
QName
desiredName
;
private
List
<
XMLEvent
>
events
;
private
int
elementDepth
=
0
;
private
int
barrier
=
Integer
.
MAX_VALUE
;
public
SplitFunction
(
QName
desiredName
)
{
this
.
desiredName
=
desiredName
;
}
@Override
public
Publisher
<?
extends
List
<
XMLEvent
>>
apply
(
XMLEvent
event
)
{
if
(
event
.
isStartElement
())
{
if
(
this
.
barrier
==
Integer
.
MAX_VALUE
)
{
QName
startElementName
=
event
.
asStartElement
().
getName
();
if
(
this
.
desiredName
.
equals
(
startElementName
))
{
this
.
events
=
new
ArrayList
<>();
this
.
barrier
=
this
.
elementDepth
;
}
}
this
.
elementDepth
++;
}
else
{
JAXBElement
<?>
jaxbElement
=
unmarshaller
.
unmarshal
(
eventReader
,
outputClass
);
return
jaxbElement
.
getValue
();
if
(
this
.
elementDepth
>
this
.
barrier
)
{
this
.
events
.
add
(
event
);
}
}
catch
(
JAXBException
ex
)
{
throw
new
DecodingException
(
ex
.
getMessage
(),
ex
);
if
(
event
.
isEndElement
())
{
this
.
elementDepth
--;
if
(
this
.
elementDepth
==
this
.
barrier
)
{
this
.
barrier
=
Integer
.
MAX_VALUE
;
return
Mono
.
just
(
this
.
events
);
}
}
return
Mono
.
empty
();
}
}
...
...
spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java
浏览文件 @
4fdd8532
...
...
@@ -11,7 +11,7 @@
* 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.
* limitations under the License.
H
*/
package
org.springframework.http.codec.xml
;
...
...
@@ -20,8 +20,8 @@ import java.io.OutputStream;
import
java.nio.charset.StandardCharsets
;
import
java.util.Map
;
import
javax.xml.bind.JAXBException
;
import
javax.xml.bind.MarshalException
;
import
javax.xml.bind.Marshaller
;
import
javax.xml.bind.UnmarshalException
;
import
javax.xml.bind.annotation.XmlRootElement
;
import
javax.xml.bind.annotation.XmlType
;
...
...
@@ -75,17 +75,16 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
DataBuffer
buffer
=
dataBufferFactory
.
allocateBuffer
(
1024
);
OutputStream
outputStream
=
buffer
.
asOutputStream
();
Class
<?>
clazz
=
ClassUtils
.
getUserClass
(
value
);
Marshaller
marshaller
=
jaxbContexts
.
createMarshaller
(
clazz
);
Marshaller
marshaller
=
this
.
jaxbContexts
.
createMarshaller
(
clazz
);
marshaller
.
setProperty
(
Marshaller
.
JAXB_ENCODING
,
StandardCharsets
.
UTF_8
.
name
());
marshaller
.
marshal
(
value
,
outputStream
);
return
Flux
.
just
(
buffer
);
}
catch
(
UnmarshalException
ex
)
{
return
Flux
.
error
(
new
EncodingException
(
"Could not unmarshal to ["
+
value
.
getClass
()
+
"]: "
+
ex
.
getMessage
(),
ex
));
catch
(
MarshalException
ex
)
{
return
Flux
.
error
(
new
EncodingException
(
"Could not marshal "
+
value
.
getClass
()
+
" to XML"
,
ex
));
}
catch
(
JAXBException
ex
)
{
return
Flux
.
error
(
new
CodecException
(
"
Could not instantiate JAXBContext: "
+
ex
.
getMessage
()
,
ex
));
return
Flux
.
error
(
new
CodecException
(
"
Invalid JAXB configuration"
,
ex
));
}
}
...
...
spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java
浏览文件 @
4fdd8532
...
...
@@ -218,7 +218,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
return
readJavaType
(
javaType
,
inputMessage
);
}
private
Object
readJavaType
(
JavaType
javaType
,
HttpInputMessage
inputMessage
)
{
private
Object
readJavaType
(
JavaType
javaType
,
HttpInputMessage
inputMessage
)
throws
IOException
{
try
{
if
(
inputMessage
instanceof
MappingJacksonInputMessage
)
{
Class
<?>
deserializationView
=
((
MappingJacksonInputMessage
)
inputMessage
).
getDeserializationView
();
...
...
@@ -230,13 +230,10 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
return
this
.
objectMapper
.
readValue
(
inputMessage
.
getBody
(),
javaType
);
}
catch
(
InvalidDefinitionException
ex
)
{
throw
new
HttpMessageConversionException
(
"Type definition error: "
+
ex
.
get
Messag
e
(),
ex
);
throw
new
HttpMessageConversionException
(
"Type definition error: "
+
ex
.
get
Typ
e
(),
ex
);
}
catch
(
JsonProcessingException
ex
)
{
throw
new
HttpMessageNotReadableException
(
"JSON parse error: "
+
ex
.
getMessage
(),
ex
);
}
catch
(
IOException
ex
)
{
throw
new
HttpMessageNotReadableException
(
"I/O error while reading: "
+
ex
.
getMessage
(),
ex
);
throw
new
HttpMessageNotReadableException
(
"JSON parse error: "
+
ex
.
getOriginalMessage
(),
ex
);
}
}
...
...
@@ -287,8 +284,11 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
generator
.
flush
();
}
catch
(
InvalidDefinitionException
ex
)
{
throw
new
HttpMessageConversionException
(
"Type definition error: "
+
ex
.
getType
(),
ex
);
}
catch
(
JsonProcessingException
ex
)
{
throw
new
HttpMessageNotWritableException
(
"Could not write JSON
document: "
+
ex
.
get
Message
(),
ex
);
throw
new
HttpMessageNotWritableException
(
"Could not write JSON
: "
+
ex
.
getOriginal
Message
(),
ex
);
}
}
...
...
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java
浏览文件 @
4fdd8532
...
...
@@ -225,7 +225,7 @@ public abstract class AbstractMessageConverterMethodArgumentResolver implements
}
}
catch
(
IOException
ex
)
{
throw
new
HttpMessageNotReadableException
(
"
Could not read document: "
+
ex
.
getMessage
()
,
ex
);
throw
new
HttpMessageNotReadableException
(
"
I/O error while reading input message"
,
ex
);
}
if
(
body
==
NO_VALUE
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录