【问题标题】:Renaming JSON objects returned to ResponseBody in Spring MVC在 Spring MVC 中重命名返回到 ResponseBody 的 JSON 对象
【发布时间】:2013-09-26 08:06:21
【问题描述】:

假设我有一个这样的对象列表:LinkedList<JsonAssessment> jsonAssessments...。

返回这种方法:

@RequestMapping(value = "mapping", method = RequestMethod.POST)
public
@ResponseBody
List<JsonAssessment> doSomething(....) {
    .....
}

我正在对这个控制器进行 AJAX 调用,一切都按预期正常工作,但我不喜欢命名我的 JSON 被返回。在我看到的萤火虫中:

{"LinkedList":[{"assessmentName":"........

问题是如何重命名根元素LinkedList?有什么需要设置的吗?

编辑

我不想使用任何包装对象。

编辑

我的对象映射器:

public class JsonObjectMapper extends ObjectMapper {

    public JsonObjectMapper() {
        super();
        this.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
        this.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
        this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }

}

春季:3.2.4.RELEASE 杰克逊:2.1.2

编辑

此对象映射器在 MVC 消息转换器中声明:

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper" ref="jsonObjectMapper"/>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

这就是我尝试过的命名策略:

public class JsonPropertyNamingStrategy extends PropertyNamingStrategy {

    public static final MyNamingStrategy MY_NAMING_STRATEGY = new MyNamingStrategy();

    private static final LinkedHashMap<String, String> PROPERTIES = new LinkedHashMap<String, String>() {{
        put("LinkedList", "resultList");
    }};

    public static class MyNamingStrategy extends PropertyNamingStrategyBase {

        @Override
        public String translate(String propertyName) {
            if (propertyName == null) {
                return null;
            }

            if (PROPERTIES.containsKey(propertyName)) {
                return PROPERTIES.get(propertyName);
            }

            return propertyName;
        }

    }

}

我正在调试它,当涉及到翻译方法属性名称时,除了根元素之外都是。我拥有LinkedList 包含的所有内容,但LinkedList 不会使用此方法。

【问题讨论】:

  • 你在哪里连接这个 ObjectMapper?这是正在使用的还是 Spring 默认的仍在使用?另外,您对PropertyNamingStrategy 做了什么尝试?最后一部分还不是很清楚。 (你只提到它不起作用)。
  • 已编辑,请查看。
  • 查看 Jackson 的源代码 PropertyNamingStrategy 并没有帮助,因为它仅用于属性而不是根类型。从源代码来看,RootNameLookup 正在处理翻译,并且只允许通过使用注释来进行不同的命名,否则它将回退到类名。当使用 JAXB 注释时,杰克逊将使用这些注释作为元数据。

标签: java json spring spring-mvc


【解决方案1】:

与其直接返回 List,不如将其包装在 ResponseEntity 中,这样会在没有根元素的情况下为您提供响应

@RequestMapping(value = "mapping", method = RequestMethod.POST)
public
@ResponseBody ResponseEntity<List<JsonAssessment>> doSomething(....) {
.....
return new ResponseEntity(yourList);
}

这样你就没有根元素。如果你仍然想要一个根元素,你可以将它添加到Map。结果为以下 JSON "[{"assessmentName":"........]

@RequestMapping(value = "mapping", method = RequestMethod.POST)
public
@ResponseBody ResponseEntity<Map<String, List<JsonAssessment>>> doSomething(....) {
.....
Map results = new HashMap();
result.put("assesments", yourlist);
return new ResponseEntity(results);
}

应该输出{"assesments":[{"assessmentName":"........

虽然您仍然在此处包装对象,但它是在免费提供的对象中,您不必添加自己的自定义类。

这是我们在几个@Controllers 中使用的,我们使用的是 Spring 3.2 和 Jackson 2.2。

【讨论】:

  • 谢谢,但这不是我的解决方案。如果您将序列化功能指定为 JSON 对象映射器,则可以避免在所有方法中使用 ResponseEntity:this.configure(SerializationFeature.WRAP_ROOT_VALUE, false);(顺便说一句,默认为 false),然后它将返回您没有根元素的 JSON,它将是 {"assesments":[{"assessmentName":"........。但是我需要一个根元素,我只想在没有任何包装器的情况下重命名它。不幸的是,PropertyNamingStrategy 仍然不适合我。
  • 你是如何配置 ObjectMapper 的?发布您的配置...另外请说明您使用的是哪个 Spring 和 Jackson 版本。
  • 已编辑问题,请看一下。
  • 知道为什么return new ResponseEntity(results); 给出这个编译时错误 = incompatible types: Map cannot be converted to HttpStatus
【解决方案2】:

将列表放入包装类是一种常用的策略

【讨论】:

  • 不使用包装类还有其他策略吗?
【解决方案3】:

如果您使用的是 Jackson Mapper,您可以使用 Annotations 来定义类中的属性名称

@JsonProperty("foo")

或设置顺序

@JsonPropertyOrder({"foo", "bar"})

等等。

进一步查看Jackson Annotations

编辑: 抱歉,刚刚看到包装评论。我看到的唯一解决方案是使用这样的包装器:How to rename root key in JSON serialization with Jackson

【讨论】:

  • 还必须有一种使用 PropertyNamingStrategy 的方法,我面临的问题是 Spring MVC 处理它的方式与直接使用来自 JAXB 对象的 ObjectMapper 序列化某些东西不同。我的命名策略中没有得到“LinkedList”根元素属性名称,而从 JAXB 对象序列化时,我得到了对象的根元素。
猜你喜欢
  • 2017-11-07
  • 2018-01-11
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 2023-03-29
  • 2023-03-19
  • 2011-06-18
  • 1970-01-01
相关资源
最近更新 更多