Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
f770dbab
Commit
f770dbab
authored
Oct 14, 2015
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Apply HttpMessageConverter auto-config to form part converters
Closes gh-3525
parent
30f24eac
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
127 additions
and
13 deletions
+127
-13
HttpMessageConverters.java
...amework/boot/autoconfigure/web/HttpMessageConverters.java
+64
-13
HttpMessageConvertersTests.java
...rk/boot/autoconfigure/web/HttpMessageConvertersTests.java
+63
-0
No files found.
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/HttpMessageConverters.java
View file @
f770dbab
/*
/*
* Copyright 2012-201
4
the original author or authors.
* Copyright 2012-201
5
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
web
;
package
org
.
springframework
.
boot
.
autoconfigure
.
web
;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collection
;
...
@@ -24,9 +25,11 @@ import java.util.Iterator;
...
@@ -24,9 +25,11 @@ import java.util.Iterator;
import
java.util.List
;
import
java.util.List
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
;
import
org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter
;
import
org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter
;
import
org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter
;
import
org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.ReflectionUtils
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
;
...
@@ -45,6 +48,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupp
...
@@ -45,6 +48,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupp
*
*
* @author Dave Syer
* @author Dave Syer
* @author Phillip Webb
* @author Phillip Webb
* @author Andy Wilkinson
* @see #HttpMessageConverters(HttpMessageConverter...)
* @see #HttpMessageConverters(HttpMessageConverter...)
* @see #HttpMessageConverters(Collection)
* @see #HttpMessageConverters(Collection)
* @see #getConverters()
* @see #getConverters()
...
@@ -97,25 +101,37 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
...
@@ -97,25 +101,37 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
*/
*/
public
HttpMessageConverters
(
boolean
addDefaultConverters
,
public
HttpMessageConverters
(
boolean
addDefaultConverters
,
Collection
<
HttpMessageConverter
<?>>
converters
)
{
Collection
<
HttpMessageConverter
<?>>
converters
)
{
List
<
HttpMessageConverter
<?>>
combined
=
getCombinedConverters
(
converters
,
addDefaultConverters
?
getDefaultConverters
()
:
Collections
.<
HttpMessageConverter
<?>>
emptyList
());
combined
=
postProcessConverters
(
combined
);
this
.
converters
=
Collections
.
unmodifiableList
(
combined
);
}
private
List
<
HttpMessageConverter
<?>>
getCombinedConverters
(
Collection
<
HttpMessageConverter
<?>>
converters
,
List
<
HttpMessageConverter
<?>>
defaultConverters
)
{
List
<
HttpMessageConverter
<?>>
combined
=
new
ArrayList
<
HttpMessageConverter
<?>>();
List
<
HttpMessageConverter
<?>>
combined
=
new
ArrayList
<
HttpMessageConverter
<?>>();
List
<
HttpMessageConverter
<?>>
processing
=
new
ArrayList
<
HttpMessageConverter
<?>>(
List
<
HttpMessageConverter
<?>>
processing
=
new
ArrayList
<
HttpMessageConverter
<?>>(
converters
);
converters
);
if
(
addDefaultConverters
)
{
for
(
HttpMessageConverter
<?>
defaultConverter
:
defaultConverters
)
{
for
(
HttpMessageConverter
<?>
defaultConverter
:
getDefaultConverters
())
{
Iterator
<
HttpMessageConverter
<?>>
iterator
=
processing
.
iterator
();
Iterator
<
HttpMessageConverter
<?>>
iterator
=
processing
.
iterator
();
while
(
iterator
.
hasNext
())
{
while
(
iterator
.
hasNext
())
{
HttpMessageConverter
<?>
candidate
=
iterator
.
next
();
HttpMessageConverter
<?>
candidate
=
iterator
.
next
();
if
(
isReplacement
(
defaultConverter
,
candidate
))
{
if
(
isReplacement
(
defaultConverter
,
candidate
))
{
combined
.
add
(
candidate
);
combined
.
add
(
candidate
);
iterator
.
remove
();
iterator
.
remove
();
}
}
}
combined
.
add
(
defaultConverter
);
}
combined
.
add
(
defaultConverter
);
if
(
defaultConverter
instanceof
AllEncompassingFormHttpMessageConverter
)
{
configurePartConverters
(
(
AllEncompassingFormHttpMessageConverter
)
defaultConverter
,
converters
);
}
}
}
}
combined
.
addAll
(
0
,
processing
);
combined
.
addAll
(
0
,
processing
);
combined
=
postProcessConverters
(
combined
);
return
combined
;
this
.
converters
=
Collections
.
unmodifiableList
(
combined
);
}
}
private
boolean
isReplacement
(
HttpMessageConverter
<?>
defaultConverter
,
private
boolean
isReplacement
(
HttpMessageConverter
<?>
defaultConverter
,
...
@@ -128,6 +144,28 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
...
@@ -128,6 +144,28 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
return
ClassUtils
.
isAssignableValue
(
defaultConverter
.
getClass
(),
candidate
);
return
ClassUtils
.
isAssignableValue
(
defaultConverter
.
getClass
(),
candidate
);
}
}
private
void
configurePartConverters
(
AllEncompassingFormHttpMessageConverter
formConverter
,
Collection
<
HttpMessageConverter
<?>>
converters
)
{
List
<
HttpMessageConverter
<?>>
partConverters
=
extractPartConverters
(
formConverter
);
List
<
HttpMessageConverter
<?>>
combinedConverters
=
getCombinedConverters
(
converters
,
partConverters
);
combinedConverters
=
postProcessPartConverters
(
combinedConverters
);
formConverter
.
setPartConverters
(
combinedConverters
);
}
private
List
<
HttpMessageConverter
<?>>
extractPartConverters
(
AllEncompassingFormHttpMessageConverter
formConverter
)
{
Field
field
=
ReflectionUtils
.
findField
(
AllEncompassingFormHttpMessageConverter
.
class
,
"partConverters"
);
ReflectionUtils
.
makeAccessible
(
field
);
@SuppressWarnings
(
"unchecked"
)
List
<
HttpMessageConverter
<?>>
partConverters
=
(
List
<
HttpMessageConverter
<?>>)
ReflectionUtils
.
getField
(
field
,
formConverter
);
return
partConverters
;
}
/**
/**
* Method that can be used to post-process the {@link HttpMessageConverter} list
* Method that can be used to post-process the {@link HttpMessageConverter} list
* before it is used.
* before it is used.
...
@@ -139,6 +177,19 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
...
@@ -139,6 +177,19 @@ public class HttpMessageConverters implements Iterable<HttpMessageConverter<?>>
return
converters
;
return
converters
;
}
}
/**
* Method that can be used to post-process the {@link HttpMessageConverter} list
* before it is used to configure the part converters of
* {@link AllEncompassingFormHttpMessageConverter}.
* @param converters a mutable list of the converters that will be used.
* @return the final converts list to use
* @since 1.3.0
*/
protected
List
<
HttpMessageConverter
<?>>
postProcessPartConverters
(
List
<
HttpMessageConverter
<?>>
converters
)
{
return
converters
;
}
private
List
<
HttpMessageConverter
<?>>
getDefaultConverters
()
{
private
List
<
HttpMessageConverter
<?>>
getDefaultConverters
()
{
List
<
HttpMessageConverter
<?>>
converters
=
new
ArrayList
<
HttpMessageConverter
<?>>();
List
<
HttpMessageConverter
<?>>
converters
=
new
ArrayList
<
HttpMessageConverter
<?>>();
if
(
ClassUtils
.
isPresent
(
"org.springframework.web.servlet.config.annotation."
if
(
ClassUtils
.
isPresent
(
"org.springframework.web.servlet.config.annotation."
...
...
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/HttpMessageConvertersTests.java
View file @
f770dbab
...
@@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.web;
...
@@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.web;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Iterator
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.List
;
...
@@ -32,6 +33,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
...
@@ -32,6 +33,7 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
import
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
;
import
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter
;
import
org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter
;
import
org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter
;
import
org.springframework.http.converter.xml.SourceHttpMessageConverter
;
import
org.springframework.http.converter.xml.SourceHttpMessageConverter
;
import
org.springframework.test.util.ReflectionTestUtils
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
...
@@ -100,6 +102,19 @@ public class HttpMessageConvertersTests {
...
@@ -100,6 +102,19 @@ public class HttpMessageConvertersTests {
assertEquals
(
converter2
,
converters
.
getConverters
().
get
(
1
));
assertEquals
(
converter2
,
converters
.
getConverters
().
get
(
1
));
}
}
@Test
public
void
convertersAreAddedToFormPartConverter
()
{
HttpMessageConverter
<?>
converter1
=
mock
(
HttpMessageConverter
.
class
);
HttpMessageConverter
<?>
converter2
=
mock
(
HttpMessageConverter
.
class
);
List
<
HttpMessageConverter
<?>>
converters
=
new
HttpMessageConverters
(
converter1
,
converter2
).
getConverters
();
List
<
HttpMessageConverter
<?>>
partConverters
=
extractFormPartConverters
(
converters
);
assertTrue
(
partConverters
.
contains
(
converter1
));
assertEquals
(
converter1
,
partConverters
.
get
(
0
));
assertEquals
(
converter2
,
partConverters
.
get
(
1
));
}
@Test
@Test
public
void
postProcessConverters
()
throws
Exception
{
public
void
postProcessConverters
()
throws
Exception
{
HttpMessageConverters
converters
=
new
HttpMessageConverters
()
{
HttpMessageConverters
converters
=
new
HttpMessageConverters
()
{
...
@@ -129,4 +144,52 @@ public class HttpMessageConvertersTests {
...
@@ -129,4 +144,52 @@ public class HttpMessageConvertersTests {
MappingJackson2HttpMessageConverter
.
class
)));
MappingJackson2HttpMessageConverter
.
class
)));
}
}
@Test
public
void
postProcessPartConverters
()
throws
Exception
{
HttpMessageConverters
converters
=
new
HttpMessageConverters
()
{
@Override
protected
List
<
HttpMessageConverter
<?>>
postProcessPartConverters
(
List
<
HttpMessageConverter
<?>>
converters
)
{
for
(
Iterator
<
HttpMessageConverter
<?>>
iterator
=
converters
.
iterator
();
iterator
.
hasNext
();)
{
if
(
iterator
.
next
()
instanceof
MappingJackson2XmlHttpMessageConverter
)
{
iterator
.
remove
();
}
}
return
converters
;
};
};
List
<
Class
<?>>
converterClasses
=
new
ArrayList
<
Class
<?>>();
for
(
HttpMessageConverter
<?>
converter
:
extractFormPartConverters
(
converters
.
getConverters
()))
{
converterClasses
.
add
(
converter
.
getClass
());
}
assertThat
(
converterClasses
,
equalTo
(
Arrays
.<
Class
<?>>
asList
(
ByteArrayHttpMessageConverter
.
class
,
StringHttpMessageConverter
.
class
,
ResourceHttpMessageConverter
.
class
,
SourceHttpMessageConverter
.
class
,
MappingJackson2HttpMessageConverter
.
class
)));
}
@SuppressWarnings
(
"unchecked"
)
private
List
<
HttpMessageConverter
<?>>
extractFormPartConverters
(
List
<
HttpMessageConverter
<?>>
converters
)
{
AllEncompassingFormHttpMessageConverter
formConverter
=
findFormConverter
(
converters
);
return
(
List
<
HttpMessageConverter
<?>>)
ReflectionTestUtils
.
getField
(
formConverter
,
"partConverters"
);
}
private
AllEncompassingFormHttpMessageConverter
findFormConverter
(
Collection
<
HttpMessageConverter
<?>>
converters
)
{
for
(
HttpMessageConverter
<?>
converter
:
converters
)
{
if
(
converter
instanceof
AllEncompassingFormHttpMessageConverter
)
{
return
(
AllEncompassingFormHttpMessageConverter
)
converter
;
}
}
return
null
;
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment