복붙노트

[SPRING] json 응답에서 필드를 동적으로 제거하는 방법은 무엇입니까?

SPRING

json 응답에서 필드를 동적으로 제거하는 방법은 무엇입니까?

나는 봄을 사용하여 편안한 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;
}
}

해결법

  1. ==============================

    1.나는이 요구 사항에 대해서도 고심하고있다.

    나는이 요구 사항에 대해서도 고심하고있다.

    다음 코드는 @beerbajay가 이미 언급 한 JsonViews를 사용하여 문제를 해결할 수있는 해결 방법입니다.

    http://wiki.fasterxml.com/JacksonJsonViews

    나는 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);
        }
    }
    

    따라서 핵심은 jackson의 ObjectMapper와 ObjectWriter를 사용하여 객체의 json 표현 문자열을 생성하는 것입니다.

    나는보기 흉하지만 일을합니다. 확실히 하나 이상의 RequestMapping을 정의 할 때 이것이 어떻게 확장되는지에 대한 질문은 여전히 ​​남아 있습니다.

  2. from https://stackoverflow.com/questions/29838960/how-to-dynamically-remove-fields-from-a-json-response by cc-by-sa and MIT license