我的设置如下。
public class TestController {
@RequestMapping(method = RequestMethod.POST, value = "/test")
public void readQuery(@RequestBody Query query) {
}
}
public class Query {
private String foo;
private String bar;
private Map<String,String> other;
}
我希望能够发布一个json对象,如:
{
"foo":"1",
"bar":"2",
"x":"3",
"y":"4"
}
让spring自动填充foo和bar到查询的foo和bar变量,以及other
映射中的任何未定义参数(所以在这种情况下other
将包含x - &gt; 3和ÿ - →4)。这样的事情是可配置的吗?我当前的临时工作是用@RequestBody Query query
替换@RequestBody Map<String,String> mapping
并迭代映射并将变量读入我的Query对象。我希望能够摆脱这样一个单调乏味的步骤。
答案 0 :(得分:1)
正如我之前评论过的,这是一个做你想做的事的例子。
创建自定义反序列化器:
public class QueryDeserializer extends JsonDeserializer<Query> {
@Override
public Query deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
Iterator<Entry<String, JsonNode>> nodeIterator = node.fields();
Query query = new Query();
Map<String, String> other = new HashMap<>();
while (nodeIterator.hasNext()) {
Map.Entry<String, JsonNode> entry = nodeIterator.next();
Field field = getField(entry.getKey());
if (field != null) {
try {
field.set(query, entry.getValue().textValue());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
other.put(entry.getKey(), entry.getValue().textValue());
}
}
if (other.size() != 0) {
query.setOther(other);
}
return query;
}
public static Field getField(String entryName) {
for (Field field : Query.class.getDeclaredFields()) {
field.setAccessible(true);
String fieldName;
if (field.isAnnotationPresent(JsonProperty.class)) {
fieldName = field.getAnnotation(JsonProperty.class).value();
} else {
fieldName = field.getName();
}
if (entryName.equalsIgnoreCase(fieldName)) {
return field;
}
}
return null;
}
}
注册反序列化器:
@JsonDeserialize(using = QueryDeserializer.class)
public class Query {
...
}
现在当你在下面这样的控制器中使用它时,Spring会自动使用你的反序列化器来构建你想要的对象:
@RequestMapping(value = "/test", method = RequestMethod.PUT)
public String test(@RequestBody Query query) {}
答案 1 :(得分:0)
部分映射不起作用。可能有一种解决方法,但更容易的方法是引入包装器对象并更改您的json对象:
{
"foo":"1",
"bar":"2",
"other":{
"x":"3",
"y":"4"
}
}