2017-07-15 58 views
1

我正在为某些社交网络后端设计使用Spring引导的API。我目前的模型是这样的:从API模型设计DTO

public class User { 

    private long id; 
    private String handle; 
    private String name; 
    private List<User> followers; 
    private List<User> following; 

    // Getters setters etc 

现在,我创建了与上述结构非常相似的DTO。我的问题是,有时候我想要返回上面的内容(这很好),但有时候,我不想那样。

例如,当某人只是在寻找的用户追随者感兴趣,我不希望包括追随者和之后(我在idhandlename只是兴趣,所以计算所有这些用户的followersfollowing会令人难以置信的资源浪费)。

在我当前的实现中,这些字段返回值为null,我认为这不是一个好主意。我应该创建一个单独的DTO没有那些列表只有id,handlename?还是有更优雅的方式来做到这一点?

+1

我觉得是更优雅,如果你创建你的API另一层在那里你可以提出一个要求用户通过ID只得到部分值,不具有意义,如果你获取所有值仅用于从DTO响应中获取一个值。 –

回答

3

这是一个有争议的问题。如果你不想创建单独的dto,有几种方法可以做到这一点。这取决于您要使用的数据访问方式:

使用Spring数据JPA可以在投影中返回实体。你只需要一个额外的构造函数添加到您的实体:

public interface UserRepository extends JpaRepository<User, Long> { 
    @Query("select new User(u.id,u.name) from User u") 
    List<User> findAllUserItems(); 
} 

或者相同的使用JPA EntityManger:

public List<User> findAllUserItems() { 
     return entityManager.createQuery("select new User(u.id,u.name) from User u", User.class) 
       .getResultList(); 
    } 

如果你想知道不必要的空字段,并且您使用杰克逊,可配置忽略空字段。春季启动:

spring.jackson.default-property-inclusion=non_null 

或者与Java的配置:

@Bean 
    public Jackson2ObjectMapperBuilder objectMapperBuilder() { 
     Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); 
     builder.serializationInclusion(JsonInclude.Include.NON_NULL); 
     return builder; 
    } 

或者不春天启动项目:

@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
    @Override 
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
     converters.add(converter()); 
    } 

    @Bean 
    public HttpMessageConverter converter() { 
     ObjectMapper objectMapper = new ObjectMapper(); 
     objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 
     return new MappingJackson2HttpMessageConverter(objectMapper); 
    } 
} 

另外,如果你打算使用Hibernate的Session。为了直接映射到DTO你可以使用AliasToBeanResultTransformer

public List<UserDto> findAllUserItems() { 
      return session.createQuery("select u.id as id,u.name as name from User u") 
        .setResultTransformer(Transformers.aliasToBean(UserDto.class)) 
        .list(); 
} 
0

假设你可以这样尝试。

@Entity 
public class User implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id; 

    @ManyToOne 
    private User parent; 

    @OneToMany(mappedBy="parent") 
    private List<User> followers; 

    @OneToMany(mappedBy="parent") 
    private List<User> following; 

    // Getters, Setters etc.... 
} 

此外这个post可能会有所帮助。

+1

这是如何准确回答问题的? OP想知道如何防止某些字段在使用DTO的REST API中返回,而您的解决方案只是一个实体? – g00glen00b