我知道可以@JsonView(...)在SpringMVC中使用静态方法定义单个视图类来注释控制器方法。不幸的是,这意味着我可能需要的每种视图类型都需要一个不同的终结点。
@JsonView(...)
我看到其他人问过这个之前。尽管这种方法可能行得通,但Spring通常有很多方法可以完成相同的事情。如果您仅对某些内部知识有一些了解,有时解决方案可能会比最初出现的要简单得多。
我想有一个控制器端点,可以根据当前主体动态选择适当的视图。我是否可以返回Model带有包含适当视图类的属性或MappingJacksonValue直接包含实例的属性?
Model
MappingJacksonValue
我看到org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#writeInternal其中有一段代码确定了要使用的视图:
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选择正确视图的必要信息)来绕过此方法,则我遇到了麻烦。
org.springframework.web.servlet.mvc.method.annotation.JsonViewResponseBodyAdvice#beforeBodyWriteInternal
Jackson2HttpMessageConverter
任何帮助,不胜感激。
如果其他人想达成相同的目标,这实际上很简单。
您可以直接org.springframework.http.converter.json.MappingJacksonValue从控制器返回一个实例,该实例包含要序列化的对象和视图类。
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; }