Spring MVC Controller中JsonView的动态选择 [英] Dynamic Selection Of JsonView in Spring MVC Controller

查看:50
本文介绍了Spring MVC Controller中JsonView的动态选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道可以使用 @JsonView(...) 注释控制器方法以在 Spring MVC 中静态定义单个视图类.不幸的是,这意味着对于我可能拥有的每种类型的视图,我都需要一个不同的端点.

I am aware that it is possible to annotate controller methods with @JsonView(...) to statically define a single view class in Spring MVC. Unfortunately this means that I need a different endpoint for every type of view I might possibly have.

我看到其他人之前问过这个问题.虽然这种方法可能有效,但 Spring 通常有很多方法可以做同样的事情.有时,如果您只是对某些内部结构有所了解,那么解决方案可能比最初看起来简单得多.

I see other people have asked this before. While this approach may work, Spring often has many ways of doing the same thing. Sometimes the solution can be much more simple than it first appears if you just have a bit of knowledge about some of the internals.

我想要一个控制器端点,它可以根据当前主体动态选择适当的视图.我是否可以直接返回带有包含适当视图类或 MappingJacksonValue 实例的属性的 Model ?

I'd like to have a single controller endpoint that can dynamically select the appropriate view based on the current principal. Is it possible for me to return a Model with an attribute that contains the appropriate view class or perhaps a MappingJacksonValue instance directly?

我在 org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal 中看到有一段代码决定使用什么视图:

I see in org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal there is a snippet of code that determines what view to use:

if (value instanceof MappingJacksonValue) {
            MappingJacksonValue container = (MappingJacksonValue) object;
            value = container.getValue();
            serializationView = container.getSerializationView();
        }

这似乎来自 org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice#beforeBodyWriteInternal 但我无法确定是否有办法绕过它只需返回一个特定值,该值包含 Jackson2HttpMessageConverter 选择正确视图所需的信息.

Which appears to come from org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice#beforeBodyWriteInternal but I'm having trouble working out if there is a way I could bypass this just simply by returning a particular value that contains the necessary information for the Jackson2HttpMessageConverter to pick the right view.

非常感谢任何帮助.

推荐答案

万一其他人也想达到同样的效果,其实很简单.

On the off chance someone else wants to achieve the same thing, it actually is very simple.

您可以直接从控制器返回一个org.springframework.http.converter.json.MappingJacksonValue 实例,该实例包含要序列化的对象和视图类.

You can directly return aorg.springframework.http.converter.json.MappingJacksonValue instance from your controller that contains both the object that you want to serialise and the view class.

这将由 org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal 方法获取并使用适当的视图.

This will be picked up by the org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal method and the appropriate view will be used.

它的工作原理是这样的:

It works something like this:

@RequestMapping(value = "/accounts/{id}", method = GET, produces = APPLICATION_JSON_VALUE)
public MappingJacksonValue getAccount(@PathVariable("id") String accountId, @AuthenticationPrincipal User user) {
    final Account account = accountService.get(accountId);
    final MappingJacksonValue result = new MappingJacksonValue(account);
    final Class<? extends View> view = accountPermissionsService.getViewForUser(user);
    result.setSerializationView(view);
    return result;
}

这篇关于Spring MVC Controller中JsonView的动态选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆