如何动态删除json响应中的字段? [英] How to dynamically remove fields from a json response?

查看:107
本文介绍了如何动态删除json响应中的字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用spring来创建一个非常好的api,到目前为止一直很好,我的问题是如何动态模拟转换的字段?

I'm using spring to create a restful api, so far so good, my question is how to model the fields that go to the response dynamically?

多数民众赞成我正在使用的控制器:

Thats the controller that i'm using:

@Controller

public class AlbumController {

@Autowired
private MusicService musicService;

@RequestMapping(value = "/albums", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Collection<Resource<Album>> getAllAlbums() {

    Collection<Album> albums = musicService.getAllAlbums();
    List<Resource<Album>> resources = new ArrayList<Resource<Album>>();
    for (Album album : albums) {
        resources.add(this.getAlbumResource(album));
    }
    return resources;

}

@RequestMapping(value = "/album/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Resource<Album> getAlbum(@PathVariable(value = "id") String id) {

    Album album = musicService.getAlbum(id);
    return getAlbumResource(album);

}

private Resource<Album> getAlbumResource(Album album) {

    Resource<Album> resource = new Resource<Album>(album);


    // Link to Album
    resource.add(linkTo(methodOn(AlbumController.class).getAlbum(album.getId())).withSelfRel());
    // Link to Artist
    resource.add(linkTo(methodOn(ArtistController.class).getArtist(album.getArtist().getId())).withRel("artist"));
    // Option to purchase Album
    if (album.getStockLevel() > 0) {
        resource.add(linkTo(methodOn(AlbumController.class).purchaseAlbum(album.getId())).withRel("album.purchase"));
    }

    return resource;

}

@RequestMapping(value = "/album/purchase/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Resource<Album> purchaseAlbum(@PathVariable(value = "id") String id) {

    Album a = musicService.getAlbum(id);
    a.setStockLevel(a.getStockLevel() - 1);
    Resource<Album> resource = new Resource<Album>(a);
    resource.add(linkTo(methodOn(AlbumController.class).getAlbum(id)).withSelfRel());
    return resource;

}
}

模型:

public class Album {

private final String id;
private final String title;
private final Artist artist;
private int stockLevel;

public Album(final String id, final String title, final Artist artist, int stockLevel) {
    this.id = id;
    this.title = title;
    this.artist = artist;
    this.stockLevel = stockLevel;
}

public String getId() {
    return id;
}

public String getTitle() {
    return title;
}

public Artist getArtist() {
    return artist;
}

public int getStockLevel() {
    return stockLevel;
}

public void setStockLevel(int stockLevel) {
    this.stockLevel = stockLevel;
}
}


推荐答案

我我也在努力解决这个问题。

I'm struggling with this requirement, too.

以下代码是使用 @ beerbajay 在您的问题评论中:

The following code is a workaround using the JsonViews already mentioned by @beerbajay in the comment to your question:

http://wiki.fasterxml.com/JacksonJsonViews

我正在使用Spring Boot 1.2.3。

I'm using Spring Boot 1.2.3.

package demo;

public class Views {

    static interface Public {}

    static interface Internal extends Public {}
}



Album.java



Album.java

package demo;

import com.fasterxml.jackson.annotation.JsonView;

public class Album {

    @JsonView(Views.Public.class)
    private String id;

    @JsonView(Views.Public.class)
    private String title;

    @JsonView(Views.Public.class)
    private String artist;

    @JsonView(Views.Internal.class)
    private String secret;

    public Album(String id, String title, String artist, String secret) {
        this.id = id;
        this.title = title;
        this.artist = artist;
        this.secret = secret;
    }

}



AlbumController.java



AlbumController.java

package demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;

@RestController
public class AlbumController {

    @Autowired
    ObjectMapper mapper;

    @RequestMapping(value = "/album", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public String getAlbum() throws JsonProcessingException {
        Album foo = new Album("1", "foo", "John Doe", "secretProperty");

        // replace the following value with runtime logic of your choice,
        // e.g. role of a user
        boolean forInternal = false;

        ObjectWriter viewWriter;
        if (forInternal) {
            viewWriter = mapper.writerWithView(Views.Internal.class);
        } else {
            viewWriter = mapper.writerWithView(Views.Public.class);
        }

        return viewWriter.writeValueAsString(foo);
    }
}

所以关键是要使用jackson的 ObjectMapper ObjectWriter 生成字符串你对象的json表示。

So the key is to use jackson's ObjectMapper and ObjectWriter to generate a string of the json representation of your object.

对我来说感觉有点难看,但是很有效。
当然,问题仍然是如何在定义多个 RequestMapping 时进行扩展。

Feels kind of ugly to me, but works. Certainly the question remains how this scales when defining more than one RequestMapping.

这篇关于如何动态删除json响应中的字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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