![](/img/trans.png)
[英]How to return a custom List with few fields from a custom query with Spring Boot?
[英]How to return only few types from Class using spring boot?
我有一個包含用戶信息(包括密碼字段)的類。 當用戶登錄時,它將返回類中的所有內容,包括密碼。 除了密碼或僅保留在數據庫中的任何重要數據之外,我如何不從類中返回所有內容。
我嘗試使用Map,這也返回了我想要的方式,但我希望有比Map更容易或更快速的東西。
幾乎沒有建議使用JsonIgnore和暫態的答案。 如果使用這兩種方法,則無法登錄。 因為我需要密碼才能登錄。
我的POJO班
@Entity
public class Users {
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "firstname")
private String firstName;
@Column(name = "lastname")
private String lastName;
@Id
@Column(name = "username")
private String username;
@Column(name = "email")
private String email;
@Column(name = "role")
private String role;
@Column(name = "password")
private String password;
回購類
public interface UsersRepository extends CrudRepository<Users,
String> {
public Users findByUsername(String username);
}
這是Rest Api
@GetMapping("/users/{username}")
public Map<String, Object> usersCheck(@PathVariable String
username) {
Map<String, Object> addUser = new HashMap<>();
Users user = userRepo.findByUsername(username);
addUser.put("email", user.getEmail());
addUser.put("firstName",user.getFirstName());
"
"
return addUser;
}
有沒有比Map更好的方法。 任何建議都會有所幫助。
實際上,jpa查詢中有一種方法可以只返回特定字段,因此您可以在獲取結果時直接使用。
但是,如果您不想打擾findByUsername方法,而不僅僅是創建User類的對象並僅設置所需的字段。
您當前使用的方法也是可行的解決方案。
因此,有兩種方法可以解決此問題。
transient
。 這樣,當您獲取用戶對象時,密碼字段將為空白。
缺點 :暫時設置密碼將導致以下事實:您將無法通過應用程序中任何位置的實體獲取密碼。
@JsonIgnore
(來自jackson庫)。 這樣,當您返回Users對象的對象時,密碼字段將被忽略。 缺點 :這再次意味着,如果您想將密碼字段用作輸入或通過應用程序返回密碼字段,則將無法這樣做。 另外,不建議您返回POJO類的對象作為響應。
因此,您可以任意選擇一種方法,同時牢記每種方法的缺點。
除了已經提到的答復外,還有其他幾種方法,例如JsonIgnoreProperties,JsonIgnoreType,JsonFilter。 我更喜歡JsonIgnore來抑制輸出中的字段。
這是一個很好的例子的鏈接https://www.baeldung.com/jackson-ignore-properties-on-serialization
另外,您始終可以創建單獨的POJO類以返回期望值。
此處的典型最佳實踐是將密碼視為子資源 :從邏輯上講 ,它不是用戶資源的直接部分,而是與之相關的(例如,它可能在/users/{id}/password
具有自己的URL)。 當您具有JPA @OneToOne
關系時,Spring Data REST會自動處理此問題,但是您自己做就沒有問題。
此示例說明為什么不直接將@Entity
類用作JSON API表示不是一個好主意的原因,因為您可能希望在內部具有差異(包括將來進行更改而不會打擾客戶)。 而是使用數據傳輸對象 (DTO)作為您實體的“ JSON副本”。 諸如MapStruct之類的工具使在User
和UserDto
之間復制屬性變得非常簡單。
(最后,如果您確實出於某種奇怪的原因而需要返回裸露的Map
(確實如此),通常為了簡便起見Map.of("key", value)
最好使用Map.of("key", value)
。)
另一個解決方案是在存儲庫中創建帶有@Query注釋的方法,例如:
@Query("SELECT NEW MyEntity(M.firstName, M.lastName, M.email) FROM MyEntity M WHERE M.username = ?1")
public MyEntity getByUsername(String username);
然后在MyEntity類中創建一個與查詢的構造函數匹配的構造函數。
最后,在您的控制器中:
代替:
public Map<String, Object> usersCheck(@PathVariable String
username)
做:
public MyEntity usersCheck(@PathVariable String
username){
return userRepo.getByUsername(username);
}
直接返回將導致spring與Jackson序列化自然集成,因此默認情況下,您的響應將是json對象
我認為這種解決方案是您的理想選擇。
如果要從響應中排除密碼,請使用@JsonIgnore
注釋密碼字段。
如果你想在排除多個領域的User
實體然后創建一個UserDto
類,並在添加所需的字段UserDto
類。
使用ModelMapper
將User實體映射到UserDto
類。 最后,將此UserDto類作為響應對象返回。
例:
User user = new User();
UserDto userDto = new ModelMapper.map(user, UserDto.class);
這將僅包括UserDto中的字段
最簡單的方法是通過默認JSON庫(傑克遜)提供的注釋來控制序列化到JSON。
@JsonIgnore
@Column(name = "password")
private String password;
您也可以通過Jackson混合來執行此操作,以避免使用JSON處理指令“污染”實體。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.