Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save HomoEfficio/7e57247818abaa0c2759c015cdf62190 to your computer and use it in GitHub Desktop.
Save HomoEfficio/7e57247818abaa0c2759c015cdf62190 to your computer and use it in GitHub Desktop.
Spring Web MVC produces error with parameter names including square brackets
$.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
});
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]
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
}
@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);
}
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]
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"));
}
@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);
}
{
"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