使用Spring Boot更新数据库中的数据

huangapple go评论73阅读模式
英文:

Update data in database using spring boot

问题

这是您提供的代码翻译部分:

@RestController
public class MainController {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private MyUserDetailsService myUserDetailsService;

    @Autowired
    private JwtUtil jwtTokenUtil;

    // 修改密码
    @RequestMapping(value = "/settings", method = RequestMethod.PUT)
    public String updatePassword(@AuthenticationPrincipal MyUserDetails myUserDetails,
                                       @RequestBody UserCredentialsPojo pojo,
                                       Users users) {
        return myUserDetailsService.changePassword(users, myUserDetails,
                                                    pojo.getNewPassword(), pojo.getNewPassword1(), pojo.getOldPassword());
    }

    // 使用 JWT 令牌进行身份验证
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception {
        try {
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword())
            );
        } catch (BadCredentialsException e) {
            throw new Exception("用户名或密码错误", e);
        }

        final UserDetails userDetails = myUserDetailsService
                .loadUserByUsername(authenticationRequest.getUsername());

        final String jwt = jwtTokenUtil.generateToken(userDetails);

        return ResponseEntity.ok(new AuthenticationResponse(jwt));
    }
}

@Entity
@Table(name = "users")
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Integer id;

    @Column(name = "username", length = 255)
    private String username;

    @Column(name = "firstname", length = 255)
    private String firstname;

    @Column(name = "lastname", length = 255)
    private String lastname;

    @Column(name = "password", length = 255)
    private String password;

    @Column(name = "roles", length = 255)
    private String roles;

    @Column(name = "email", length = 255)
    private String email;

    @Column(name = "lastLoginDate", length = 255)
    private String lastLoginDate;

    @Column(name = "registrationDate", length = 255)
    private String registrationDate;

    @Column(name = "lastLoginIp", length = 255)
    private String lastLoginIp;

    @Column(name = "balance")
    private Integer balance;

    @Column(name = "status")
    private Integer status;

    @Column(name = "birthDate", length = 255)
    private String birthDate;

    @Column(name = "departmentId")
    private Integer departmentId;

    @Column(name = "facultyId")
    private Integer facultyId;

    @Column(name = "advisorId")
    private Integer advisorId;

    // 获取器和设置器,没有构造函数...
}

public class MyUserDetails implements UserDetails {
    private Integer id;
    private String username;
    private String firstname;
    private String lastname;
    private String password;
    private List<GrantedAuthority> authorities;
    private String email;
    private String lastLoginDate;
    private String registrationDate;
    private String lastLoginIp;
    private Integer balance;
    private Integer status;
    private String birthDate;
    private Integer departmentId;
    private Integer facultyId;
    private Integer advisorId;

    public MyUserDetails(Users user) {
        // 构造函数内容...
    }

    public MyUserDetails() {
    }

    // 获取器和设置器...
}

public interface UserRepository extends JpaRepository<Users, Integer> {
    Optional<Users> findByUsername(String username);
}

@Service
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    // 修改用户密码
    public String changePassword(Users users, MyUserDetails myUserDetails, String newPassword, String newPassword1, String oldPassword) {
        // 密码修改逻辑...
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 加载用户信息逻辑...
    }
}
{
    "oldPassword":"admin",
	"newPassword":"admin123",
	"newPassword1":"admin123"
}
英文:

I'm trying to change password of current logged in user. Any idea, why is it adding another row with the same columns except password that has been changed? May be i'm using the wrong method?

There is my controller MainController.java

@RestController
public class MainController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private MyUserDetailsService myUserDetailsService;
@Autowired
private JwtUtil jwtTokenUtil;
// Change the password
@RequestMapping(value = &quot;/settings&quot;, method = RequestMethod.PUT)
public String updatePassword(@AuthenticationPrincipal MyUserDetails myUserDetails,
@RequestBody UserCredentialsPojo pojo,
Users users) {
return myUserDetailsService.changePassword(users, myUserDetails,
pojo.getNewPassword(), pojo.getNewPassword1(), pojo.getOldPassword());
}
// Authentication with jwt token
@RequestMapping(value = &quot;/login&quot;, method = RequestMethod.POST)
public ResponseEntity&lt;?&gt; createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword())
);
} catch (BadCredentialsException e) {
throw new Exception(&quot;Incorrect username and password&quot;, e);
}
final UserDetails userDetails = myUserDetailsService
.loadUserByUsername(authenticationRequest.getUsername());
final String jwt = jwtTokenUtil.generateToken(userDetails);
return ResponseEntity.ok(new AuthenticationResponse(jwt));
}
}

UsersEntity.java

@Entity
@Table(name = &quot;users&quot;)
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = &quot;id&quot;)
private Integer id;
@Column(name = &quot;username&quot;, length = 255)
private String username;
@Column(name = &quot;firstname&quot;, length = 255)
private String firstname;
@Column(name = &quot;lastname&quot;, length = 255)
private String lastname;
@Column(name = &quot;password&quot;, length = 255)
private String password;
@Column(name = &quot;roles&quot;, length = 255)
private String roles;
@Column(name = &quot;email&quot;, length = 255)
private String email;
@Column(name = &quot;lastLoginDate&quot;, length = 255)
private String lastLoginDate;
@Column(name = &quot;registrationDate&quot;, length = 255)
private String registrationDate;
@Column(name = &quot;lastLoginIp&quot;, length = 255)
private String lastLoginIp;
@Column(name = &quot;balance&quot;)
private Integer balance;
@Column(name = &quot;status&quot;)
private Integer status;
@Column(name = &quot;birthDate&quot;, length = 255)
private String birthDate;
@Column(name = &quot;departmentId&quot;)
private Integer departmentId;
@Column(name = &quot;facultyId&quot;)
private Integer facultyId;
@Column(name = &quot;advisorId&quot;)
private Integer advisorId;
// Getters and setters without constructor..

Here is MyUserDetails that extends UserDetails MyUserDetails.java.

public class MyUserDetails implements UserDetails {
private Integer id;
private String username;
private String firstname;
private String lastname;
private String password;
private List&lt;GrantedAuthority&gt; authorities;
private String email;
private String lastLoginDate;
private String registrationDate;
private String lastLoginIp;
private Integer balance;
private Integer status;
private String birthDate;
private Integer departmentId;
private Integer facultyId;
private Integer advisorId;
public MyUserDetails(Users user) {
this.id = user.getId();
this.username = user.getUsername();
this.firstname = user.getFirstname();
this.lastname = user.getLastname();
this.password = user.getPassword();
this.authorities = Arrays.stream(user.getRoles().split(&quot;,&quot;))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
this.email = user.getEmail();
this.lastLoginDate = user.getLastLoginDate();
this.registrationDate = user.getRegistrationDate();
this.lastLoginIp = user.getLastLoginIp();
this.balance = user.getBalance();
this.status = user.getStatus();
this.birthDate = user.getBirthDate();
this.departmentId = user.getDepartmentId();
this.facultyId = user.getFacultyId();
this.advisorId = user.getAdvisorId();
}
public MyUserDetails() {
}
// Getters and setters..

UsersRepository.java

public interface UserRepository extends JpaRepository&lt;Users, Integer&gt; {
Optional&lt;Users&gt; findByUsername(String username);
}

MyUserDetailsService.java

@Service
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
// Change user password
public String changePassword(Users users, MyUserDetails myUserDetails, String newPassword, String newPassword1, String oldPassword) {
if (oldPassword.equals(myUserDetails.getPassword())) {
if (oldPassword.equals(newPassword)) {
return &quot;New password cannot be the same as the old&quot;;
} else if (!newPassword.equals(newPassword1)) {
return &quot;Passwords mismatches&quot;;
} else if (newPassword.length() &lt; 8) {
return &quot;New password too short&quot;;
} else if (!newPassword.matches(&quot;.*&quot;)) {
return &quot;New password must contain at least 1 number&quot;;
} else {
users.setFirstname(myUserDetails.getFirstname());
users.setLastname(myUserDetails.getLastname());
users.setPassword(newPassword);
users.setRoles(String.valueOf(myUserDetails.getAuthorities()));
users.setEmail(myUserDetails.getEmail());
users.setLastLoginDate(myUserDetails.getLastLoginDate());
users.setRegistrationDate(myUserDetails.getRegistrationDate());
users.setLastLoginIp(myUserDetails.getLastLoginIp());
users.setBalance(myUserDetails.getBalance());
users.setStatus(myUserDetails.getStatus());
users.setBirthDate(myUserDetails.getBirthDate());
users.setFacultyId(myUserDetails.getFacultyId());
users.setAdvisorId(myUserDetails.getAdvisorId());
users.setUsername(myUserDetails.getUsername());
users.setDepartmentId(myUserDetails.getDepartmentId());
userRepository.save(users);
return &quot;Password has been successfully changed&quot;;
}
} else {
return &quot;Password is wrong&quot;;
}
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional&lt;Users&gt; user = userRepository.findByUsername(username);
user.orElseThrow(() -&gt; new UsernameNotFoundException(&quot;Not found: &quot; + username));
return user.map(MyUserDetails::new).get();
}
}

Users table

+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+
| id | firstname | lastname | password | roles     | email  | lastLoginDate | registrationDate | lastLoginIp | balance | status | birthDate | facultyId | advisorId | username | departmentId |
+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+
|  2 | damir     | esenov   | admin    | student   | damir  | NULL          | NULL             | NULL        |    NULL |   NULL | NULL      | 1         | 1         | admin    | 1            |
|  3 | rapkat    | baudunov | rapkat   | NULL      | rapkat | NULL          | NULL             | NULL        |    NULL |   NULL | NULL      | NULL      | NULL      | rapkat   | NULL         |
| 15 | damir     | esenov   | admin123 | [student] | damir  | NULL          | NULL             | NULL        |    NULL |   NULL | NULL      | 1         | 1         | admin    | 1            |
+----+-----------+----------+----------+-----------+--------+---------------+------------------+-------------+---------+--------+-----------+-----------+-----------+----------+--------------+

My request in PostMan (I've changed the request to PUT method)
Postman

{
&quot;oldPassword&quot;:&quot;admin&quot;,
&quot;newPassword&quot;:&quot;admin123&quot;,
&quot;newPassword1&quot;:&quot;admin123&quot;
}

答案1

得分: 1

自从usersid为null,所以JPA将其视为新用户,这就是为什么会在数据库中创建一行新记录。所以只需在else内部设置usersid

users.setId(myUserDetails.getId());

更好的解决方案:

如果你只需要更改密码,就不需要设置所有字段。首先根据id获取用户,然后设置密码并保存。

users = userRepository.findById(myUserDetails.getId()).get();
users.setPassword(newPassword);
userRepository.save(users);
英文:

Since id for users is null so JPA treats as new user that why create a new row in database. So just set id of users inside else

users.setId(myUserDetails.getId());

Better solution:

You don't need to set all the field if you need only to change password.
First get the user by id then set the password and save.

users = userRepository.findById(myUserDetails.getId()).get();
users.setPassword(newPassword);
userRepository.save(users);

huangapple
  • 本文由 发表于 2020年5月3日 18:13:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/61572777.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定