我正在使用spring创建一个宁静的api,到目前为止,我的问题是如何动态建模响应的字段?
那就是我正在使用的控制器:
@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; } }
我也在为此要求而苦苦挣扎。
我正在使用Spring Boot 1.2.3。
package demo; public class Views { static interface Public {} static interface Internal extends Public {} }
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; } }
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); } }
因此,关键是使用杰克逊的ObjectMapper和ObjectWriter生成对象的json表示形式的 字符串 。
对我来说有点丑陋,但是有效。当然,问题仍然在于定义多个时如何缩放RequestMapping。
RequestMapping