C Brand C Brand - 6 months ago 19
Java Question

Spring binds form data to multiple (wrong) objects

I experience a weired error where the form data is bound to a completely wrong object upon submission.

I am using spring with thymeleaf and have the following form:

<form method="post" th:action="@{/backend/user/create}"
th:object="${userInCreation}" id="userCreateForm">
<input th:field="*{firstName}" />Create user</button>
</form>


The object I want to bind to is

public class UserInCreation implements Serializable {

private String firstName;

public UserInCreation() {}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}
}


Binding happens in the controller

@Controller
@RequestMapping("/backend/user")
public class UserController {

@RequestMapping(value = "/create", method = RequestMethod.GET)
public String createUserForm(UserInCreation userInCreation) {
return "backend/user/create";
}

@RequestMapping(value = "/create", method = RequestMethod.POST)
public String createUser(@Valid UserInCreation userInCreation, BindingResult result, Model model) {
return "backend/user/index";
}
}


This works fine, despite a big issue: The data I type into the firstName field is also bound to the Spring-Security Principal, which I make available as a ModelAttribute:

@ModelAttribute("currentAuthor")
public User getCurrentAuthor(Principal principal, HttpSession session) {
User author = (User) ((Authentication) principal).getPrincipal();
return author;
}


The class
User
also has a field firstName, and this is changed. So when I type "Some name" into the form and submit, suddenly the first name of the principal will be "Some name". Any thoughts?

Answer

I found out what the problem is. Actually, I had a function of the type

@ModelAttribute("foo")
public Foo xyz(@ModelAttribute("bar") Bar bar) {
  ...
}

This is against the specification, but it seemed to work at first. But it also seems to mess up the data binding system completely.