Springframework - 在null上找不到属性或字段

时间:2017-10-19 02:33:50

标签: java spring thymeleaf

我正在处理一个项目并继续收到错误。

<span style="font-style: italic;" th:text="${user != null} ? ${#strings.toUpperCase(user.username)} : 'user is null'"></span>

EL1007E: Property or field 'id' cannot be found on null

我对thyemeleaf和spring很新,所以仍然在学习,所以不确定你需要什么来帮助解决这个问题所以当我知道我需要提供什么时我会更新。

登录/新用户模式

的标头HTML

&#13;
&#13;
<body>
  <div th:fragment="navbar">
    <div class="container">
      <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
        <a class="navbar-brand active" href="https://inplaydesign.com/index.html">d|b</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
					<span class="navbar-toggler-icon"></span>
				</button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav mr-auto">
            <li class="nav-item">
              <a class="nav-link" href="https://blog.inplaydesign.com">blog</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="/gallery/gallery.html">gallery</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">shop</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="/faq/faq.html">f.a.q.</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="/contact/contact.html">contact</a>
            </li>
          </ul>
          <button type="button" class="btn btn-outline-dark">
						<i class="fa fa-shopping-cart"></i> Shopping Cart
					</button>
          <button sec:authorize="isAnonymous()" type="button" class="btn btn-outline-dark" data-toggle="modal" data-target="#accountAccess">
						<i class="fa fa-id-card"></i> Account
					</button>
          <a sec:authorize="isAuthenticated()" th:href="@{/myProfile}">
            <button type="button" class="btn btn-outline-dark">
							<i class="fa fa-id-card"></i> Account
						</button>
          </a>
          <a sec:authorize="isAuthenticated()" th:href="@{/logout}">
            <button type="button" class="btn btn-outline-dark">
							<i class="fa fa-power-off"></i> log-out
						</button>
          </a>
        </div>
      </nav>
    </div>
    <!-- Account modal -->
    <div class="modal fade" id="accountAccess" tabindex="-1" role="dialog" aria-hidden="true">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title">Account Login and Creation
            </h5>
          </div>
          <div class="modal-body">
            <ul class="nav nav-tabs" role="tablist">
              <li class="nav-item" th:classappend="${classActiveNewAccount}? 'active'">
                <a class="nav-link" data-toggle="tab" href="#tab-1" role="tab">Sign up</a>
              </li>
              <li class="nav-item" th:classappend="${classActiveLogin}? 'active'">
                <a class="nav-link active" data-toggle="tab" href="#tab-2" role="tab">User Login</a>
              </li>
              <li class="nav-item" th:classappend="${classActiveForgetPassword}? 'active'">
                <a class="nav-link" data-toggle="tab" href="#tab-3" role="tab">Forgot Password</a>
              </li>
            </ul>
            <div class="tab-content" style="margin-top: 10px;">
              <!-- New User -->
              <div class="tab-pane fade" id="tab-1" role="tabpanel" th:classappend="${classActiveNewAccount}? 'in active'">
                <form th:action="@{/newUser}" method="post">
                  <div class="container">
                    <div class="form-group">
                      <label for="email">Email Address</label>&nbsp;
                      <div class="alert alert-danger" th:if="${emailExists}">"Email already exists"</div>
                      <input type="email" class="form-control" id="email" name="email" placeholder="Enter Email Address" />
                    </div>
                    <div class="form-group">
                      <label for="NewUsername">Username</label>&nbsp;
                      <div class="alert alert-danger" th:if="${usernameExists}">"Username already exists"</div>
                      <input type="text" class="form-control" id="newUsername" name="NewUsername" tabindex="0" placeholder="Enter Username" />
                    </div>
                  </div>
                  <div class="modal-footer">
                    <button type="reset" class="btn btn-outline-dark btn-sm">
											<i class="fa fa-refresh"></i> Reset
										</button>
                    <button type="button" class="btn btn-outline-dark btn-sm">
											<i class="fa fa-user-plus"></i> Create New Account
										</button>
                  </div>
                </form>
              </div>

              <!-- login -->
              <div class="tab-pane fade show active" id="tab-2" role="tabpanel" th:classappend="${classActiveLogin}? 'active'">
                <div class="alert alert-danger" th:if="${param.error != null}">
                  <small>Please check your credentials and try again.</small>
                </div>
                <form th:action="@{/login}" method="post">
                  <div class="container">
                    <div class="form-group">
                      <label for="username">Username</label>
                      <input type="text" class="form-control" id="username" name="username" placeholder="Enter Username" />
                    </div>
                    <div class="form-group">
                      <label for="password">Password</label>
                      <input type="password" class="form-control" id="password" name="password" placeholder="Enter Password" />
                    </div>
                  </div>
                  <div class="modal-footer">
                    <button type="submit" class="btn btn-outline-dark btn-sm">
											<i class="fa fa-sign-in"></i> Log-In
										</button>
                  </div>
                </form>
              </div>

              <!-- Forgot password -->
              <div class="tab-pane fade" id="tab-3" role="tabpanel" th:classappend="${classActiveForgetPassword}? 'in active'">
                <div th:if="${emailNotExist}" class="alert alert-danger">Email does not exist</div>
                <div th:if="${forgetPasswordEmailSent}" class="alert alert-success">Please check your email for password reset token.</div>
                <form action="">
                  <div class="container">
                    <div class="form-group">
                      <label for="recoverEmail">User Email</label>
                      <input type="email" class="form-control" id="recoverEmail" placeholder="Enter Recovery Email" name="email" />
                    </div>
                  </div>
                  <div class="modal-footer">
                    <button type="submit" class="btn btn-outline-dark btn-sm">
											<i class="fa fa-external-link-square"></i> Submit
										</button>
                  </div>
                </form>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <div th:fragment="body-bottom-scripts">
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" type="text/javascript"></script>
    <script src="/js/bootstrap.min.js" type="text/javascript"></script>
  </div>
</body>
&#13;
&#13;
&#13;

&#13;
&#13;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.digitalblasphemy.domain.User;
import com.digitalblasphemy.domain.security.PasswordResetToken;
import com.digitalblasphemy.domain.security.Role;
import com.digitalblasphemy.domain.security.UserRole;
import com.digitalblasphemy.service.UserService;
import com.digitalblasphemy.service.impl.UserSecurityService;
import com.digitalblasphemy.utility.MailConstructor;
import com.digitalblasphemy.utility.SecurityUtility;

@Controller
public class HomeController {

  @Autowired
  private JavaMailSender mailSender;

  @Autowired
  private MailConstructor mailConstructor;

  @Autowired
  private UserService userService;

  @Autowired
  private UserSecurityService userSecurityService;

  @RequestMapping("/")
  public String index() {
    return "index";
  }

  @RequestMapping("/myAccount")
  public String myAccount() {
    return "myAccount";
  }

  @RequestMapping("/login")
  public String login(Model model) {
    model.addAttribute("classActiveLogin", true);
    return "myProfile";
  }

  @RequestMapping("/forgetPassword")
  public String forgetPassword(
    HttpServletRequest request,
    @ModelAttribute("email") String email,
    Model model
  ) {
    model.addAttribute("classActiveForgetPassword", true);
    User user = userService.findByEmail(email);

    if (user == null) {
      model.addAttribute("emailNotExist", true);
      return "index";
    }

    String password = SecurityUtility.randomPassword();

    String encryptedPassword = SecurityUtility.passwordEncoder().encode(password);
    user.setPassword(encryptedPassword);

    userService.save(user);

    String token = UUID.randomUUID().toString();
    userService.createPasswordResetTokenForUser(user, token);

    String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();

    SimpleMailMessage newEmail = mailConstructor.constructResetTokenEmail(appUrl, request.getLocale(), token, user, password);

    mailSender.send(newEmail);

    model.addAttribute("forgetPasswordEmailSent", "true");

    return "index";
  }

  @RequestMapping(value = "/newUser", method = RequestMethod.POST)
  public String newUserPost(
    HttpServletRequest request,
    @ModelAttribute("email") String userEmail,
    @ModelAttribute("username") String username,
    Model model
  ) throws Exception {
    model.addAttribute("classActiveNewAccount", true);
    model.addAttribute("email", userEmail);
    model.addAttribute("username", username);

    if (userService.findByUsername(username) != null) {
      model.addAttribute("usernameExists", true);

      return "index";
    }

    if (userService.findByEmail(userEmail) != null) {
      model.addAttribute("emailExists", true);

      return "index";
    }

    User user = new User();
    user.setUsername(username);;
    user.setEmail(userEmail);

    String password = SecurityUtility.randomPassword();

    String encryptedPassword = SecurityUtility.passwordEncoder().encode(password);
    user.setPassword(encryptedPassword);

    Role role = new Role();
    role.setRoleId(1);
    role.setName("ROLE_USER");
    Set < UserRole > userRoles = new HashSet < > ();
    userRoles.add(new UserRole(user, role));
    userService.createUser(user, userRoles);

    String token = UUID.randomUUID().toString();
    userService.createPasswordResetTokenForUser(user, token);

    String appUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();

    SimpleMailMessage email = mailConstructor.constructResetTokenEmail(appUrl, request.getLocale(), token, user, password);

    mailSender.send(email);

    model.addAttribute("emailSent", "true");

    return "myAccount";
  }

  @RequestMapping("/newUser")
  public String newUser(
    Locale locale,
    @RequestParam("token") String token,
    Model model) {

    PasswordResetToken passToken = userService.getPasswordResetToken(token);

    if (passToken == null) {
      String message = "Invalid Token.";
      model.addAttribute("message", message);
      return "redirect:/badRequest";
    }

    User user = passToken.getUser();
    String username = user.getUsername();

    UserDetails userDetails = userSecurityService.loadUserByUsername(username);

    Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());

    SecurityContextHolder.getContext().setAuthentication(authentication);

    model.addAttribute("user", user);

    model.addAttribute("classActiveEdit", true);
    return "myProfile"; //possibly change to index page
  }
}
&#13;
&#13;
&#13;

我在我的Application.java文件中创建了一个用于测试目的的用户。

&#13;
&#13;
@Override
public void run(String...args) throws Exception {
  User user1 = new User();
  user1.setFirstName("Kyle");
  user1.setLastName("Drew");
  user1.setUsername("kd");
  user1.setPassword(SecurityUtility.passwordEncoder().encode("p"));
  user1.setEmail("kd@me.com");
  Set < UserRole > userRoles = new HashSet < > ();
  Role role1 = new Role();
  role1.setRoleId(1);
  role1.setName("ROLE_USER");
  userRoles.add(new UserRole(user1, role1));

  userService.createUser(user1, userRoles);
}
&#13;
&#13;
&#13;

这是调试后变量的图片。

variables

3 个答案:

答案 0 :(得分:2)

您可以通过检查user是否为空来避免此异常。

<span style="font-style: italic;" th:text="${user != null} ? ${#strings.toUpperCase(user.username)} : 'user is null'"></span>

但是,更好的方法是确保在未初始化的情况下将user添加到模型中。

答案 1 :(得分:0)

在放入模型

之前,请确保您的用户对象不为null

答案 2 :(得分:0)

我想出了这个问题。在SecurityConfig.Java文件中,我没有.loginPage指向正在创建异常的正确位置。

&#13;
&#13;
http
  .csrf().disable().cors().disable()
  .formLogin().failureUrl("/login?error").defaultSuccessUrl("/")
  .loginPage("/login").permitAll()
  .and()
  .logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
  .logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
  .and()
  .rememberMe();
}
&#13;
&#13;
&#13;