Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

json view - Dynamic Selection Of JsonView in Spring MVC Controller

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.

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.

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?

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();
        }

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.

Any help much appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

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.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...