Skip to main content
 首页 » 编程设计

spring-mvc之Spring MVC Controller 中JsonView的动态选择

2024年11月01日28wayfarer

我知道可以用@JsonView(...)注释 Controller 方法以在Spring MVC中静态定义单个 View 类。不幸的是,这意味着我可能需要的每种 View 类型都需要一个不同的终结点。

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

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

我在org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal中看到一小段代码,用于确定要使用的 View :

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

这似乎来自 org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice#beforeBodyWriteInternal,但是我无法解决是否有一种方法可以简单地通过返回一个包含 Jackson2HttpMessageConverter选择正确 View 的必要信息的特定值来绕过此操作。

任何帮助,不胜感激。

请您参考如下方法:

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

您可以直接从 Controller 返回一个org.springframework.http.converter.json.MappingJacksonValue实例,该实例同时包含要序列化的对象和 View 类。

这将由org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal方法拾取,并将使用适当的 View 。

它的工作原理如下:

@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; 
}