如何动态删除json响应中的字段? [英] How to dynamically remove fields from a json response?
问题描述
我正在使用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屋!