【问题标题】:How to exclude certain modelAttributes in JSON output (using ContentNegotiatingViewResolver)如何在 JSON 输出中排除某些 modelAttributes(使用 ContentNegotiatingViewResolver)
【发布时间】:2012-11-27 23:50:56
【问题描述】:

我有一个 Spring MVC 3.1.0 项目,并且我已经配置了一个 ContentNegotiatingViewResolver bean 来为给定的端点(使用 org.springframework.web.servlet.view.json.MappingJacksonJsonView)自动生成 JSON 输出。

我有一些控制器方法可以向 JSP 页面(通过 model.addAttribute("foo", fooService.getFoo());)添加我不想出现在 JSON 输出中的数据。

我尝试在我的服务方法getFoo()(返回Map<String, String>)中添加@JsonIgnore 注释,但它不起作用。当我点击那个控制器时,我仍然看到 foo 对象在我的 JSON 输出中被编组。

谁能提出另一种实现这一点的方法或告诉我为什么JsonIgnore 注释不起作用?

【问题讨论】:

    标签: json spring-mvc jackson


    【解决方案1】:

    MappingJacksonJsonView 将模型的所有内容序列化为一个 json - 您已放置在模型对象中的所有对象,因此您是否使用@JsonIgnore 标记了其中一个服务方法无关紧要,只要由于调用model.addAttribute("foo"..,它最终会出现在它所做的模型中,它将被序列化。修复可能只是不添加模型属性,或者使用@ResponseBody,这将使您能够控制正在序列化的特定响应对象。

    另一个选项是指定您在配置MappingJacksonJsonView 时将使用的确切键:

    <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" name="jsonView">
    <property name="modelKeys">
       <set>
        <value>model1</value>
        <value>model2</value>
       </set>
    </property>
    </bean>
    

    【讨论】:

    • 这个特定页面并没有从 JSON 视图中获得很大好处,所以我可以完全排除它。但这需要创建一个具有显式映射的新控制器方法来捕获 JSON 请求,然后简单地返回 404(丑陋)。我可以尝试以编程方式捕获 JSON 版本(查看 HttpServletRequest 内部)并在 model.addAttribute() 周围添加 if 语句?也丑陋...'希望有一些简单的 @JsonIgnore 可用。
    • 我确实看到了modelKeys 选项,但我的模型/控制器太多,无法以可维护的方式使用它。
    【解决方案2】:

    扩展 MappingJackson2JsonView 类并覆盖 filterMap(Map model) 方法。 在 filterMap 方法中过滤掉你需要排除的具有 modelAttributes 名称的键。

    public class MappingJackson2JsonViewExt extends MappingJackson2JsonView {
        private static final Set<String> EXCLUDED_KEYS = new HashSet<>();
    
        public static void excludeModelKey(final String key) {
            EXCLUDED_KEYS.add(key);
        }
    
        @Override
        protected Object filterModel(final Map<String, Object> model) {
            final Map<String, Object> filteredModel = model.entrySet().stream()
                    .filter(e -> {
                        final String key = e.getKey();
                        return !EXCLUDED_KEYS.contains(key);
                    })
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
    
            return super.filterModel(filteredModel);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-06
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-04
      • 1970-01-01
      相关资源
      最近更新 更多