Java Spring Data JPA и REST API: исключить поля вложенного объекта JSON

В настоящее время я использую Spring Data JPA 2.2.1 с Spring Boot Web 2.2.1 для службы REST API.

Вызов метода получения / категорий возвращает следующий JSON, который фактически является желаемым результатом:

[
    {
        "category1": "A",
        "category2": "B",
        "subcategories": []
    },
    {
        "category1": "A",
        "category2": "B",
        "subcategories": [{
                "field1": "A",
                "field2": "B",
                "field3": "C",
                "field4": "D"
        }]
    },
.........
.........
]

Сущности:

@Entity
@Table(name = "category")
@Getter @Setter
public class Category {

    @JsonIgnore
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String category1;
    private String category2;
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    private List<Subcategory> subcategories;
}
@Entity
@Table(name = "subcategory")
@Getter @Setter
public class Subcategory {

    @JsonIgnore
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @JsonIgnore
    private int parent;
    private String field1;
    private String field2;
    private String field3;
    private String field4;
}

Контроллер:

@RestController
public class MyController {

    private final DataService dataService;

    @Autowired
    public MyController(DataService dataService) {
        this.dataService = dataService;
    }

    @GetMapping("/categories")
    public List<Category> getAllCategories() {
        return dataService.getAllCategories();
    }

Репозиторий

public interface MyRepository extends JpaRepository<Category, Long> {
    List<MyRepository> findAll();
}

DataService

@Component
public class DataService {
    private MyRepository myRepository;

    @Autowired
    public DataService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    public List<Category> getAllCategories() { return myRepository.findAll(); }

Теперь я хочу добавить новый вызов к своему API, / limitedCategories, который не возвращает все поля. Например, «категория 2» родительского объекта и «поле 4» вложенного объекта должны быть исключены.

Проблема:

  • Мне не удается вручную выбрать нужные поля в моем репозитории JPA, а также я не знаю, как работать с вложенным объектом.
  • Простая идея просто использовать findAll и исключить эти поля с помощью @JsonIgnore невозможна, поскольку моему первому запросу все еще нужны эти поля.
  • При использовании аннотации @Query в моем репозитории для получения только желаемых полей я не могу найти способ получить вложенные поля для моего JSON.

Заранее спасибо.

Я использую Spring Data JPA 2.2.1 с Spring Boot Web 2.2.1.


person Community    schedule 18.11.2019    source источник
comment
Сущности представляют собой то, что вы хотите сохранить в таблицах базы данных. Используйте другой класс (DTO) для представления того, что вы хотите вернуть как JSON из вашей конечной точки. Преобразуйте свои сущности в экземпляры этого класса DTO.   -  person JB Nizet    schedule 19.11.2019


Ответы (1)


Если вы используете Jackson API, я рекомендую вам использовать функцию @JsonView.

Например

class Person {
   // it will be add always
   Integer id;

   // it will be add only for PutFirstName case
   @JsonView(Views.PutFirstName.class)
   String firstName;

   // it will be add only for PutLastName case
   @JsonView(Views.PutLastName.class)
   String lastName;
} 

class Views {
   static class PutFirstName{}
   static class PutLastNastName{}
}

// Controller 
@JsonView(Views.PutFirstName.class)
@GetMapping
Person getFirstName(){
     // result : {id,firstName}
}

@JsonView(Views.PutLastName.class)
@GetMapping
Person getLastName(){
    // result : {id, lastName}
}
person zouari    schedule 19.11.2019