How to expose custom DTO crud repository with Spring data REST?

泄露秘密 提交于 2019-12-23 08:50:11

问题


I don't want to expose my model classes (jpa entities), rather different subset of their attributes with different data transport objects (DTOs). The idea is DTO CrudRepository <-> JpaRepository <-> entities, and I want to expose via Spring Data REST the DTO CrudRepository.

Example:

Entity:

@Entity
@Table(name = "groups")
public class Group {

    private Long id;
    private String name;
    private Set<User> users;
    // other attributes

    @Id
    @GeneratedValue
    @Column(name = "group_id")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "name", nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @OneToMany(mappedBy = "group")
    public Set<User> getUsers() {
        return users;
    }

    public void setUsers(Set<User> users) {
        this.users = users;
    }

    // other getters and setters

}

JpaRepository:

@RepositoryRestResource(exported = false)
public interface GroupDao extends JpaRepository<Group, Long> {
}

DTO:

public class GroupWithoutRelationsDto {

    private Long id;
    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @NotBlank
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

DTO CrudRepository:

public interface GroupDtoDao extends CrudRepository<GroupWithoutRelationsDto, Long> {
}

Implementation:

@Repository
public class GroupDtoDaoImpl extends GenericDtoDao<GroupWithoutRelationsDto, Group, Long> implements GroupDtoDao {

    @Autowired
    private GroupDao groupDao;

    @Override
    protected CrudRepository<Group, Long> getModelDao() {
        return groupDao;
    }

    @Override
    protected <S extends GroupWithoutRelationsDto> Long getDtoId(S dto) {
        return dto.getId();
    }

    @Override
    protected Long getModelId(Group model) {
        return model.getId();
    }

    @Override
    protected <S extends GroupWithoutRelationsDto> S modelToDto(Group model, S dto) {
        dto.setId(model.getId());
        dto.setName(model.getName());
        return dto;
    }

    @Override
    protected <S extends GroupWithoutRelationsDto> Group dtoToModel(S dto, Group model) {
        model.setId(dto.getId());
        model.setName(dto.getName());
        return model;
    }

    @Override
    protected Group newModel() {
        return new Group();
    }

    @Override
    protected GroupWithoutRelationsDto newDto() {
        return new GroupWithoutRelationsDto();
    }

}

GenericDtoDao:

@NoRepositoryBean
public abstract class GenericDtoDao<D, M, ID extends Serializable> implements CrudRepository<D, ID> {

    protected abstract CrudRepository<M, ID> getModelDao();

    protected abstract <S extends D> ID getDtoId(S dto);

    protected abstract ID getModelId(M model);

    protected abstract <S extends D> S modelToDto(M model, S dto);

    protected abstract <S extends D> M dtoToModel(S dto, M model);

    protected abstract M newModel();

    protected abstract D newDto();

    @Override
    public D findOne(ID id) {
        return modelToDto(getModelDao().findOne(id), newDto());
    }

    @Override
    public <S extends D> S save(S entity) {
        Assert.notNull(entity, "The entity must not be null!");
        if (getDtoId(entity) == null) {
            return create(entity);
        }
        return update(entity);
    }

    protected <S extends D> S create(S entity) {
        Assert.notNull(entity, "The entity must not be null!");
        if (getDtoId(entity) != null) {
            Assert.isTrue(!exists(getDtoId(entity)), "The entity ID must be null or not exist!");
        }
        return modelToDto(getModelDao().save(dtoToModel(entity, newModel())), entity);
    }

    protected <S extends D> S update(S entity) {
        Assert.notNull(entity, "The entity must not be null!");
        M model = getModelDao().findOne(getDtoId(entity));
        Assert.notNull(model, "The entity must exist!");
        return modelToDto(getModelDao().save(dtoToModel(entity, model)), entity);
    }

    // other CrudRepository methods

}

In this example I want to expose GroupDtoDao with Spring data REST.

In other beans I can autowire both GroupDao and GroupDtoDao, so both are managed by Spring's context. If I don't annotate GroupDao with @RepositoryRestResource(exported = false) the JpaRepository is exposed as REST service, so I suppose Spring data REST is well configured.

How can I tell it to expose my custom CrudRepository?


回答1:


There is a JIRA issue to clarify how to do this.

For now, the SDR team says "We generally recommend to just use Jackson mixins to hook in custom serializers, customize output etc. See the Spring RESTBucks for an example."



来源:https://stackoverflow.com/questions/28428573/how-to-expose-custom-dto-crud-repository-with-spring-data-rest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!