亲爱的stackoverflow社区,
我是一个新的与泛型和使用泛型正确的问题。我想做的是,静态方法可以将泛型对象作为参数。我的想法是,将实体对象作为参数传递,然后返回userdetailsimpl对象。所以我想让这个方法能够处理不同的实体类,而不是编写样板代码。为此,我写了一个简单的盒子类。
方框.java
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
现在,我尝试使用它在静态构建方法的userdetailsimp.java类中传递泛型对象作为参数:
package com.yildiz.tradilianz.security.services;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore;
public class UserDetailsImpl implements UserDetails {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String email;
@JsonIgnore
private String password;
private Collection<? extends GrantedAuthority> authorities;
public UserDetailsImpl(Long id, String username, String email, String password,
Collection<? extends GrantedAuthority> authorities) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
this.authorities = authorities;
}
public static UserDetailsImpl build(Box<Object> user) {
List<GrantedAuthority> authorities = user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority(role.getName().name()))
.collect(Collectors.toList());
return new UserDetailsImpl(
user.getId(),
user.getUsername(),
user.getEmail(),
user.getPassword(),
authorities);
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public Long getId() {
return id;
}
public String getEmail() {
return email;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
UserDetailsImpl user = (UserDetailsImpl) o;
return Objects.equals(id, user.id);
}
}
现在的问题是,传递的对象不知道我尝试访问的所有get()方法,如user.getid()、user.getroles()、user.getpassword()等。我希望泛型box类包含任何对象,但如何声明我需要从中访问的方法?
否则它将以“类型框的方法getroles()未定义”结束
我想作为泛型对象传递的是我的customer实体类,但如果它返回null,我想在userdetailsserviceimpl中测试retailer实体类是否工作,以此类推:
package com.yildiz.tradilianz.security.services;
import org.apache.commons.validator.routines.EmailValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yildiz.tradilianz.auth.User;
import com.yildiz.tradilianz.auth.UserRepository;
import com.yildiz.tradilianz.customer.Customer;
import com.yildiz.tradilianz.customer.CustomerDTO;
import com.yildiz.tradilianz.customer.CustomerRepository;
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
CustomerRepository customerRepository;
@Autowired
CustomerDTO customerDTO;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Check for username or email passed through username parameter
boolean valid = EmailValidator.getInstance().isValid(username);
if (valid == false) {
/*
* Build with UserDetailsImpl but if user for Customer class is null I want to try another repository and do
* something like this:
* Retailer user = retailerRepository.findByUsername(username); And if it is not null
* it should pass user Object which class is Retailer and so on.
*
*/
Customer user = customerRepository.findByUsername(username);
return UserDetailsImpl.build(user);
} else {
Customer user = customerRepository.findByEmail(username):
return UserDetailsImpl.build(user);
}
}
}
客户实体类
package com.yildiz.tradilianz.customer;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.hibernate.annotations.CreationTimestamp;
import com.yildiz.tradilianz.auth.ERole;
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotBlank
@Size(max = 20)
private String username;
@NotBlank
@Size(max = 120)
private String password;
@Column(nullable = false)
private String givenName;
@Column(nullable = false)
private String surname;
private String birthday;
private String streetAddress;
private String city;
private String postalCode;
@Column(updatable = false, nullable = false)
private String email;
private String phoneNumber;
@CreationTimestamp
private Timestamp timestamp;
private Double balance;
private Integer bonuspoints;
private String role;
protected Customer() {
}
public Customer(String username,String password, String givenName, String surname, String birthday, String streetAddress, String city,
String postalCode, String email, String phoneNumber, Double balance, Integer bonuspoints, String role) {
this.username = username;
this.password = password;
this.givenName = givenName;
this.surname = surname;
this.birthday = birthday;
this.streetAddress = streetAddress;
this.city = city;
this.postalCode = postalCode;
this.email = email;
this.phoneNumber = phoneNumber;
this.balance = balance;
this.bonuspoints = bonuspoints;
this.role = role;
}
@Override
public String toString() {
return ("Benutzername: "+username+ "Passwort: "+password+ "Vorname: " + givenName + " Nachname: " + surname +
" Geburtstag: " + birthday + " Straße: "+ streetAddress + " Stadt: " + city + " Postleitzahl: " +
postalCode + " E-Mail-Adresse: " + email+ " Telefonnummer: " + phoneNumber + "Kontostand: " + balance +
" Bonuspunkte: " + bonuspoints+" Rolle:"+role);
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public Long getId() {
return id;
}
public String getGivenName() {
return givenName;
}
public String getSurname() {
return surname;
}
public String getBirthday() {
return birthday;
}
public String getStreetAddress() {
return streetAddress;
}
public String getCity() {
return city;
}
public String getPostalCode() {
return postalCode;
}
public String getEmail() {
return email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public Timestamp getTimestamp() {
return timestamp;
}
public Integer getBonuspoints() {
return bonuspoints;
}
public Double getBalance() {
return balance;
}
public String getRole() {
return role;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public void setSurname(String surname) {
this.surname = surname;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
public void setCity(String city) {
this.city = city;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public void setEmail(String email) {
this.email = email;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public void setBalance(Double balance) {
this.balance = balance;
}
public void setBonuspoints(Integer bonuspoints) {
this.bonuspoints = bonuspoints;
}
public void setRole(String role) {
this.role = role;
}
}
**
你能告诉我怎么做吗?
1条答案
按热度按时间tv6aics11#
在build()方法中,传递的是box,因此它只知道类型为object。
public static UserDetailsImpl build(Box<Object> user)
当您尝试访问它时,您尝试从customer类型访问方法,它将不知道什么方法与customer对象关联(用户引用将只知道box类方法)所以,你需要做的是改变
Box<Object>
至Box<Customer>
然后使用在这里user.get()将返回基础类型对象,并且您可以访问它的方法。
或者您还可以做的是,如果您希望泛型类型是一个特定的示例类型,您可以将box类实现更改为(将t类型扩展到该类的示例),例如您的案例中的customer(您可以创建一个接口或抽象类,它将包含您尝试使用的方法)