一尘不染

Spring MVC控制器中JsonView的动态选择

spring-mvc

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

我看到其他人问过这个之前。尽管这种方法可能行得通,但Spring通常有很多方法可以完成相同的事情。如果您仅对某些内部知识有一些了解,有时解决方案可能会比最初出现的要简单得多。

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

我看到org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal其中有一段代码确定了要使用的视图:

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

似乎是这样,org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice#beforeBodyWriteInternal但是如果有一种方法我可以简单地通过返回一个特定值(包含用于Jackson2HttpMessageConverter选择正确视图的必要信息)来绕过此方法,则我遇到了麻烦。

任何帮助,不胜感激。


阅读 569

收藏
2020-06-01

共1个答案

一尘不染

如果其他人想达成相同的目标,这实际上很简单。

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

该方法将对此进行拾取,org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal并将使用适当的视图。

它的工作原理如下:

@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;
}
2020-06-01