我正在为一个电子商务网站项目编写一个SpringBoot应用程序,我在其中创建一个表单来更改用户帐户的当前密码。提交表单时出现以下两个错误。
An error happened during template parsing (template: "class path resource [templates/myprofile.html]")
Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "user.id" (template: "myprofile" - line 110, col 68)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "user.id" (template: "myprofile" - line 110, col 68)
Property or field 'id' cannot be found on object of type 'java.lang.Boolean' - maybe not public or not valid?
HomeController
@RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
public String updateUserInfo(
@ModelAttribute("user") user user,
@ModelAttribute("newPassword") String newPassword,
Model model
) throws Exception{
user currentUser = userService.findById(user.getId());
if(currentUser == null) {
throw new Exception ("User not found.");
}
if(userService.findByEmail(user.getEmail())!=null) {
if(userService.findByEmail(user.getEmail()).getId() != currentUser.getId()) {
model.addAttribute("emailExists", true);
return "myprofile";
}
}
if(userService.findByUsername(user.getUsername())!=null) {
if(userService.findByUsername(user.getUsername()).getId() != currentUser.getId()) {
model.addAttribute("usernameExists", true);
return "myprofile";
}
}
if(newPassword != null && !newPassword.isEmpty() && !newPassword .equals("")) {
BCryptPasswordEncoder passwordEncoder = SecurityUtility.passwordEncoder();
String dbPassword = currentUser.getPassword();
if(passwordEncoder.matches(user.getPassword(), dbPassword)) {
currentUser.setPassword(passwordEncoder.encode(newPassword));
}else {
model.addAttribute("invalidPassword", true);
return "myprofile";
}
}
currentUser.setFirstName(user.getFirstName());
currentUser.setLastName(user.getLastName());
currentUser.setUsername(user.getUsername());
currentUser.setEmail(user.getEmail());
userService.save(currentUser);
model.addAttribute("updateSuccess", true);
model.addAttribute("user", true);
model.addAttribute("classActiveEdit", true);
UserDetails userDetails = userSecurityService.loadUserByUsername(currentUser.getUsername());
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
return "myprofile";
}
myprofile.html
<form th:action="@{/updateUserInfo}" method="post" >
<input type="hidden" name="id" th:value="${user.id}" />
<div class="bg-info" th:if="${updateUserInfo}">User info updated</div>
<div class="form-group">
<div class="row">
<div class="col-xs-6">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName" name="firstName" th:value="${user.firstName}" />
</div>
<div class="col-xs-6">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName" name="lastName" th:value="${user.lastName}" />
</div>
</div>
</div>
<div class="form-group">
<label for="userName">Username</label>
<input type="text" class="form-control" id="userName" name="username" th:value="${user.username}" />
</div>
<div class="form-group">
<label for="currentPassword">Current Password</label>
<input type="password" class="form-control" id="currentPassword" name="password" th:value="${currentPassword}" />
</div>
<p style="color: #828282">Enter your current password to change the email address or password</p>
<div class="form-group">
<label for="email">Email Address</label>
<input type="text" class="form-control" id="email" name="email" th:value="${user.email}" />
</div>
<p style="color: #828282">A valid email address. All
emails from the system will be sent to this address.The
email address is not make public and will only be used if
you wish to receive a new password or wish to receive
certain notification</p>
<div class="form-group">
<label for="txtNewPassword">Password</label> <span id="checkPasswordMatch" style="color:red;"></span>
<input type="password" class="form-control" id="txtNewPassword" name="txtNewPassword" />
</div>
<div class="form-group">
<label for="txtConfirmPassword">Confirm Password</label>
<input type="password" class="form-control" id="txtConfirmPassword" />
</div>
<p style="color: #828282">To change the current user password, enter new password in both fileds </p>
<button id="updateUserInfobutton" type="submit" class="btn btn-primary">Save All</button>
</form>
用户类别
package com.eshop.domian;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
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.OneToMany;
import javax.persistence.OneToOne;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import com.eshop.security.UserRole;
import com.eshop.security.auth;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
public class user implements UserDetails{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id", nullable = false, updatable = false)
private Long id;
private String firstName;
private String lastName;
private String username;
private String password;
@Column(name="email", nullable = false, updatable = false)
private String email;
private String phone;
private boolean enabled=true;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "user")
private ShoppingCart shoppingCart;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserShipping> userShippingList;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private List<UserPayment> userPaymentList;
@OneToMany(mappedBy = "user", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JsonIgnore
private Set<UserRole> userRoles= new HashSet<>();
public long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
public ShoppingCart getShoppingCart() {
return shoppingCart;
}
public void setShoppingCart(ShoppingCart shoppingCart) {
this.shoppingCart = shoppingCart;
}
public List<UserShipping> getUserShippingList() {
return userShippingList;
}
public void setUserShippingList(List<UserShipping> userShippingList) {
this.userShippingList = userShippingList;
}
public List<UserPayment> getUserPaymentList() {
return userPaymentList;
}
public void setUserPaymentList(List<UserPayment> userPaymentList) {
this.userPaymentList = userPaymentList;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<>();
userRoles.forEach(ur -> authorities.add(new auth(ur.getRole().getName())));
return authorities;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean isEnabled()
{
return enabled;
}
}
用户服务
package com.eshop.service;
import java.util.Set;
import com.eshop.domian.UserBilling;
import com.eshop.domian.UserPayment;
import com.eshop.domian.UserShipping;
import com.eshop.domian.user;
import com.eshop.security.PasswordResetToken;
import com.eshop.security.UserRole;
public interface UserService {
PasswordResetToken getPasswordResetToken(final String token);
void createPasswordResetTokenForUser(final user user, final String token);
user findByUsername(String username);
user findByEmail(String email);
user findById(Long Id);
user createUser(user user, Set<UserRole> userRoles) throws Exception;
user save(user user);
void updateUserBilling(UserBilling userBilling, UserPayment userPayment, user user);
void setUserDefaultPayment(Long userPaymentId, user user);
void updateUserShipping(UserShipping userShipping, user user);
void setUserDefaultShipping(Long userShippingId, user user);
}
用户服务实施
package com.eshop.service.impl;
@Service
public class UserServiceImpl implements UserService{
private static final Logger LOG = LoggerFactory.getLogger(UserService.class);
@Autowired
private PasswordResetTokenRepository passwordResetTokenRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private UserPaymentRepository userPaymentRepository;
@Autowired
private UserShippingRepository userShippingRepository;
@Override
public PasswordResetToken getPasswordResetToken(final String token) {
return passwordResetTokenRepository.findByToken(token);
}
@Override
public void createPasswordResetTokenForUser(final user user, final String token) {
final PasswordResetToken myToken = new PasswordResetToken(token, user);
passwordResetTokenRepository.save(myToken);
}
@Override
public user findByUsername(String username) {
// TODO Auto-generated method stub
return userRepository.findByusername(username);
}
@Override
public user findById(Long id) {
return userRepository.findById(id).get();
}
@Override
public user findByEmail(String email) {
// TODO Auto-generated method stub
return userRepository.findByEmail(email);
}
}
答案 0 :(得分:0)
您在这里尝试访问id
模型属性的user
字段:
<input type="hidden" name="id" th:value="${user.id}" />
此处将user
模型属性设置为true
,因此它的类型为boolean
:
model.addAttribute("user", true);
由于类型为boolean
的变量没有名为id
的字段,尝试访问它会产生您看到的错误。我认为这是因为您不想将该模型属性设置为true
(也许您想将其设置为currentUser
?),或者您不想将id
字段设置为要访问的对象属于另一个模型属性。