Thymeleaf registration page - Error during executi

2019-05-08 03:58发布

问题:

I'm making a registration page for a website. I understand that in order for a new User to be created, an id is required, so we have the field:

<input type="hidden" th:field="{*id} />

However, when I go to the page, I get the error I mentioned in this post's title.

Here is the form in question:

<form th:action="@{/users/register}" th:object="${user}" class="form-signin" method="POST">
    <h2 class="form-signin-heading">Register</h2>
    <input type="hidden" th:field="*{id}" />
    <label for="inputUsername" class="sr-only">Username*</label>
    <input type="text" th:field="*{username}" name="username" id="inputUsername" class="form-control" placeholder="Username" required="required" autofocus="autofocus" />
    <label for="inputEmail" class="sr-only">Email Address*</label>
    <input type="text" th:field="*{email}" name="email" id="inputEmail" class="form-control" placeholder="Email address" required="required" autofocus="autofocus" />
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" th:field="*{password}" name="password" id="inputPassword" class="form-control" placeholder="Password" required="required" />
    <label for="inputConfirmPassword" class="sr-only">Confirm Password</label>
    <input type="password" th:field="${confirmPassword}" name="confirmPassword" id="inputConfirmPassword" class="form-control" placeholder="Confirm password" required="required" />
    <button class="btn btn-lg btn-primary btn-block" type="submit">Register</button>
</form>

Here is my UserController:

@RequestMapping("/register")
public String registerAction(Model model) {
    model.addAttribute("user", new User());
    model.addAttribute("confirmPassword", "");
    return "views/users/register";
}

@RequestMapping(value="/register", method = RequestMethod.POST)
public String doRegister(User user) {
    User savedUser = userService.save(user);
    return "redirect:/"; //redirect to homepage
}

And the first part of the User entity:

@Entity
@Table(name = "users")
public class User {

// Default constructor require by JPA
public User() {}

@Column(name = "id")
@Id @GeneratedValue
private Long id;

public void setId(long id) {
    this.id = id;
}

public long getId() {
    return id;
}

From what I can see, there's nothing wrong here so I'm stuck.

I'm following this example: https://github.com/cfaddict/spring-boot-intro

Any ideas?

回答1:

The problem is the way you have declared your id property. The field uses a reference type Long which is null. The getter uses a primitive long. When Spring accesses the id field it tries to unbox a null value causing an error. Change your domain class to be

@Entity
@Table(name = "users")
public class User {

    // Default constructor required by JPA
    public User() {}

    @Id
    @Column(name = "id")
    @GeneratedValue
    private Long id;

    public void setId(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }
}


回答2:

I don't know if you have a class like this

@Controller
@RequestMapping("/users")
public class MyController{

    @RequestMapping("/register")
    public String registerAction(Model model) {
        model.addAttribute("user", new User());
        model.addAttribute("confirmPassword", "");
        return "views/users/register";
    }

    @RequestMapping(value="/register", method = RequestMethod.POST)
    public String doRegister(User user) {
        User savedUser = userService.save(user);
        return "redirect:/"; //redirect to homepage
    }
}

becouse if you don't have the @RequestMapping("/users") this is a problem becous if you dont have this annotation in you class the correct actione in the thymeleaf templace should be "@{/register}" other wise yon don't have the endpoint pubblished in other words with the methods that you posted you should have a template like this:

<form th:action="@{/register}" th:object="${user}" class="form-signin" method="POST">
    <h2 class="form-signin-heading">Register</h2>
    <input type="hidden" th:field="*{id}" />
    .... should be as you written
    <input type="password" th:field="*{confirmPassword}" id="inputConfirmPassword" class="form-control" placeholder="Confirm password" required="required" />
    <button class="btn btn-lg btn-primary btn-block" type="submit">Register</button>
</form>

reading beter the your html you probably should have th:field="*{confirmPassword}" and not th:field="${confirmPassword}". another think that in my opinion don't works is that you repeate name attribute. The my advice is don't repeate and let to thymeleaf the work of build the correct attribute for databinding.