2016-09-02 2 views
4

У меня есть пользователи Entity:Исключить столбец из набора результатов в контроллере | Весна данных JPA

public class SpringUsers implements Serializable { 
    private String password; 
    // other fields omitted 
    @Basic 
    @Column(name = "password") 
    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 
} 

И его хранилище:

public interface SpringUsersRepository extends CrudRepository<SpringUsers, Integer> { 
    SpringUsers findByUsername(String username); 
    List<SpringUsers> findByUserId(Integer userId); 
} 

И у меня есть метод контроллера, который должен получить список всех зарегистрированных пользователей с одинаковым USERID (это для внутреннего использования), как в настоящее время проверку подлинности пользователя:

public List<SpringUsers> getRegisteredUsers() { 
    CustomUserDetails authenticatedUserDetails = getCustomUserDetails(); 
    List<SpringUsers> registered = springUsersRepository.findByUserId(
     authenticatedUserDetails.getUserMyId()); 
    return registered.stream().map(v -> { 
     v.setPassword(null); 
     return v; 
    }).collect(Collectors.toList()); 
} 

Я не хочу, чтобы передать пароль (даже если он зашифрован) в веб-интерфейсе - поэтому я передаю пользователям и устанавливаю пароль равным нулю, как вы можете видеть выше.

Однако, мне интересно, если нет возможности просто не включать пароль пользователя в результат запроса в первую очередь?


Version Info:

Spring загрузки 1.4.0 & Hibernate 5.0.9.Final

ответ

5

Вы можете использовать @Query, чтобы выборочно включать некоторые поля:

// Include all fields you wanna query for using u.x syntax 
// AFAIK there is no exclusion syntatic sugar 
@Query("select u.id, u.username from SpringUsers u where u.id = ?1") 
List<SpringUsers> findByUserId(Integer userId); 

Также вас может использовать Projections. Сначала определим проекцию, вводя интерфейс проекции:

interface NoPasswordUser { 
    Long getId(); 
    String getUsername(); 
    // Do not include getPassword(); 
} 

Затем используйте его в хранилище:

public interface SpringUsersRepository extends CrudRepository<SpringUsers, Integer> { 
    NoPasswordUser findByUsername(String username); 
    List<NoPasswordUser> findByUserId(Integer userId); 
} 

Во всяком случае, это лучше не подвергать свои объекты через REST или любой удаленный интерфейс. Вы можете использовать DTO в этом отношении, этот post может быть полезен в этой области.

+1

Yap, Проецирование похоже на путь --- Я сделаю это, если не найду другого решения. Спасибо за совет! – baao

1

Я не думаю, что есть способ просто игнорировать некоторые поля при получении объекта из db, поскольку эти объекты не будут находиться в согласованном состоянии - их данные будут отличаться от данных в базе данных. Существуют и другие варианты (пользовательский запрос, прогнозы).

Одним из вариантов является использование constructor expressions и заполнить некоторые POJO только с необходимыми данными в запросе непосредственно

select new my.company.SafeUser(u.username, u.email) from User u 

Во всяком случае, я думаю, вы должны отправить DTOs в веб-интерфейсе, и в нем разоблачить только те атрибуты, которые необходимо на интерфейсе. У этого подхода есть много преимуществ, погода вы их инициализируете, как в примере выше, или в цикле результатов.

Смежные вопросы