首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring -将RequestBody的未知参数转储到Map<String、String>变量中的一种方法?

Spring -将RequestBody的未知参数转储到Map<String、String>变量中的一种方法?
EN

Stack Overflow用户
提问于 2016-04-07 06:22:53
回答 2查看 750关注 0票数 0

我有如下的设置。

代码语言:javascript
复制
public class TestController {
  @RequestMapping(method = RequestMethod.POST, value = "/test")
  public void readQuery(@RequestBody Query query) {
  }
}
代码语言:javascript
复制
public class Query {
  private String foo;
  private String bar;
  private Map<String,String> other;
}

我希望能够发布这样的json对象:

代码语言:javascript
复制
{
  "foo":"1",
  "bar":"2",
  "x":"3",
  "y":"4"
}

并让spring自动将foo和bar填充到查询的foo和bar变量中,并将任何未定义的参数填充到other映射中(因此在本例中,other将包含x->3和y->4)。这种东西是可配置的吗?我目前的工作是用@RequestBody Map<String,String> mapping替换@RequestBody Map<String,String> mapping,迭代映射并将变量读入查询对象。我很想摆脱这样一个乏味的步骤。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-07 08:16:27

正如我在前面提到的,下面是一个您想做的事情的例子。

创建自定义反序列化器:

代码语言:javascript
复制
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;
    }
}

注册反序列化器:

代码语言:javascript
复制
@JsonDeserialize(using = QueryDeserializer.class)
public class Query {
...
}

现在,当您在如下所示的控制器中使用它时,Spring将自动使用反序列化器来构建您想要的对象:

代码语言:javascript
复制
@RequestMapping(value = "/test", method = RequestMethod.PUT)
public String test(@RequestBody Query query) {}
票数 1
EN

Stack Overflow用户

发布于 2016-04-07 06:46:46

部分映射不起作用。可能有一个解决办法,但更容易的方法是引入包装器对象并更改json对象:

代码语言:javascript
复制
{
 "foo":"1",
 "bar":"2",
 "other":{
   "x":"3",
   "y":"4"
 }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36468188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档