java将泛型类定义为静态方法的参数,以传递实体对象

eulz3vhy  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(422)

亲爱的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;
    }

}

**

你能告诉我怎么做吗?

tv6aics1

tv6aics11#

在build()方法中,传递的是box,因此它只知道类型为object。 public static UserDetailsImpl build(Box<Object> user) 当您尝试访问它时,您尝试从customer类型访问方法,它将不知道什么方法与customer对象关联(用户引用将只知道box类方法)
所以,你需要做的是改变 Box<Object>Box<Customer> 然后使用

user.get().getId() etc.

在这里user.get()将返回基础类型对象,并且您可以访问它的方法。
或者您还可以做的是,如果您希望泛型类型是一个特定的示例类型,您可以将box类实现更改为(将t类型扩展到该类的示例),例如您的案例中的customer(您可以创建一个接口或抽象类,它将包含您尝试使用的方法)

public class Box< T extends Customer>

public class Box<T extends CustomerInterface>  etc.

相关问题