英文:
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 = "/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());
}
// Authentication with jwt token
@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("Incorrect username and password", 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 = "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;
// 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<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) {
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(","))
.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<Users, Integer> {
Optional<Users> 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 "New password cannot be the same as the old";
} else if (!newPassword.equals(newPassword1)) {
return "Passwords mismatches";
} else if (newPassword.length() < 8) {
return "New password too short";
} else if (!newPassword.matches(".*")) {
return "New password must contain at least 1 number";
} 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 "Password has been successfully changed";
}
} else {
return "Password is wrong";
}
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<Users> user = userRepository.findByUsername(username);
user.orElseThrow(() -> new UsernameNotFoundException("Not found: " + 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
{
"oldPassword":"admin",
"newPassword":"admin123",
"newPassword1":"admin123"
}
答案1
得分: 1
自从users
的id
为null,所以JPA将其视为新用户,这就是为什么会在数据库中创建一行新记录。所以只需在else
内部设置users
的id
。
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);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论