2015-02-10 19 views
6

Tôi không muốn để lộ các lớp mô hình của tôi (thực thể jpa), thay vì tập con khác nhau của các thuộc tính của chúng với các đối tượng truyền dữ liệu khác nhau (DTO). Ý tưởng là DTO CrudRepository <-> JpaRepository <-> entities và tôi muốn hiển thị qua Spring Data REST số DTO CrudRepository.Làm cách nào để hiển thị kho lưu trữ Crud tùy chỉnh DTO với REST dữ liệu Spring?

Ví dụ:

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> { 
} 

Thực hiện:

@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 

} 

Trong ví dụ này tôi muốn để lộ GroupDtoDao với mùa xuân REST của dữ liệu.

Trong các hạt khác, tôi có thể tự động cả GroupDao và GroupDtoDao, do đó cả hai đều được quản lý theo ngữ cảnh của Spring. Nếu tôi không chú thích GroupDao với @RepositoryRestResource(exported = false) thì JpaRepository được hiển thị dưới dạng dịch vụ REST, vì vậy tôi cho rằng dữ liệu Spring REST được cấu hình tốt.

Làm thế nào tôi có thể yêu cầu nó hiển thị CrudRepository tùy chỉnh của tôi?

+0

Bạn đã bao giờ tìm ra điều này chưa? Tôi cũng thích câu trả lời nhưng không có giải pháp sạch. Ý tưởng tốt nhất của tôi là cung cấp một ObjectMapper JSON tùy chỉnh, và bên trong trình ánh xạ thực hiện ánh xạ tới DTO và viết ra DTO. – Jay

+0

Tôi chưa tìm thấy giải pháp tự động nào, tôi vẫn có CrudRestController tùy chỉnh kết thúc tốt các phương pháp DtoDaos của tôi –

Trả lời

2

a JIRA issue để làm rõ cách thực hiện việc này.

Hiện tại, nhóm SDR cho biết "Chúng tôi thường khuyên bạn chỉ nên sử dụng mixin Jackson để móc trong serializers tùy chỉnh, tùy chỉnh đầu ra, vv. Xem ví dụ Spring RESTBucks."

Các vấn đề liên quan