Last active
November 19, 2020 05:09
-
-
Save HomoEfficio/7e57247818abaa0c2759c015cdf62190 to your computer and use it in GitHub Desktop.
Spring Web MVC produces error with parameter names including square brackets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$.ajax({ | |
url: 'http://localhost:8080/data-binder', | |
contentType: 'application/json', | |
method: 'GET', | |
crossDomain: true, | |
data: { | |
id: "321", | |
addresses: [ | |
{ | |
city: "Seoul", | |
goo: "Peace", | |
street: "Forever", | |
number: 3 | |
}, | |
{ | |
city: "Incheon", | |
goo: "Hapiness", | |
street: "Together", | |
number: 33 | |
} | |
], | |
emails: ['[email protected]', '[email protected]'] | |
} | |
}).done(function(msg) { | |
// Do something with msg | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
id:321 | |
addresses[0][city]:Seoul | |
addresses[0][goo]:Peace | |
addresses[0][street]:Forever | |
addresses[0][number]:3 | |
addresses[1][city]:Incheon | |
addresses[1][goo]:Hapiness | |
addresses[1][street]:Together | |
addresses[1][number]:33 | |
emails[]:[email protected] | |
emails[]:[email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SampleDTO { | |
private String id; | |
private List<Address> addresses; | |
private List<String> emails; | |
public String getId() { | |
return id; | |
} | |
public void setId(String id) { | |
this.id = id; | |
} | |
public List<Address> getAddresses() { | |
return addresses; | |
} | |
public void setAddresses(List<Address> addresses) { | |
this.addresses = addresses; | |
} | |
public List<String> getEmails() { | |
return emails; | |
} | |
public void setEmails(List<String> emails) { | |
this.emails = emails; | |
} | |
} | |
public class Address { | |
private String city; | |
private String goo; | |
private String street; | |
private String number; | |
// getter, setter | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RequestMapping(value = "/data-binder", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) | |
public ResponseEntity<SampleDTO> saveSampleEntity(HttpServletRequest request, SampleDTO dto) { | |
return ResponseEntity.ok(dto); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
org.springframework.beans.InvalidPropertyException: | |
Invalid property 'addresses[0][city]' of bean class [homo.efficio.springboot.scratchpad.jackson.model.SampleDTO]: | |
Property referenced in indexed property path 'addresses[0][city]' is neither an array nor a List nor a Map; | |
returned value was [homo.efficio.springboot.scratchpad.jackson.model.Address@3e95df7] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class WebUtils { | |
public static <T> T getDTOFromParamMap(Map<String, String[]> parameterMap, Class<T> dto) throws IllegalAccessException, InstantiationException { | |
final MutablePropertyValues sourceProps = getPropsFrom(parameterMap); | |
T targetDTO = dto.newInstance(); | |
DataBinder binder = new DataBinder(targetDTO); | |
binder.bind(sourceProps); | |
return targetDTO; | |
} | |
private static MutablePropertyValues getPropsFrom(Map<String, String[]> parameterMap) { | |
final MutablePropertyValues mpvs = new MutablePropertyValues(); | |
parameterMap.forEach( | |
(k, v) -> { | |
String dotKey = | |
k | |
.replaceAll("\\['", "[") | |
.replaceAll("']", "]") | |
.replaceAll("\\[\"", "[") | |
.replaceAll("\"]", "]") | |
.replaceAll("\\[]", "") | |
.replaceAll("\\[(\\d+)]", "!#%@$1%@#!") | |
.replaceAll("\\[", ".") | |
.replaceAll("]", "") | |
.replaceAll("!#%@(\\d+)%@#!", "[$1]"); | |
mpvs.addPropertyValue(dotKey, v); | |
} | |
); | |
return mpvs; | |
} | |
} | |
// Test Example | |
@Test | |
public void convertSquareBracketToDot() throws Exception { | |
String k = "items[0][options][1][a][12][b][abc][c][1234][c1][33][_1][___][99][a33][b3][aa3]"; | |
String result = | |
k | |
.replaceAll("\\['", "[") | |
.replaceAll("']", "]") | |
.replaceAll("\\[\"", "[") | |
.replaceAll("\"]", "]") | |
.replaceAll("\\[]", "") | |
.replaceAll("\\[(\\d+)]", "!#%@$1%@#!") | |
.replaceAll("\\[", ".") | |
.replaceAll("]", "") | |
.replaceAll("!#%@(\\d+)%@#!", "[$1]"); | |
Assert.assertThat(result, Matchers.is("items[0].options[1].a[12].b.abc.c[1234].c1[33]._1.___[99].a33.b3.aa3")); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RequestMapping(value = "/data-binder", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE) | |
public ResponseEntity<SampleDTO> saveSampleEntity(HttpServletRequest request) { | |
SampleDTO dto = null; | |
try { | |
dto = HomoEfficioWebUtils.getDTOFromParamMap(request.getParameterMap(), SampleDTO.class); | |
} catch (IllegalAccessException e) { | |
e.printStackTrace(); | |
} catch (InstantiationException e) { | |
e.printStackTrace(); | |
} | |
return ResponseEntity.ok(dto); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"id": "321", | |
"addresses": [{ | |
"city": "Seoul", | |
"goo": "Peace", | |
"street": "Forever", | |
"number": "3" | |
}, { | |
"city": "Incheon", | |
"goo": "Hapiness", | |
"street": "Together", | |
"number": "33" | |
}], | |
"emails": ["[email protected]", "[email protected]"] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment