I`ve ran into a problem with controller/vm data transfer and could not find any solution. Ive got a User (see class below)
package com.Entity;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.*;
import java.util.Date;
@Entity
@Transactional
@Table(name = "USERS")
public class User {
private Long id;
private UserType type;
private String email;
private String password;
private String name;
private String tel;
private Date regDate;
private Date lastActive;
private Agent office;
//Constructors
public User(){
}
public User(UserType type, String email, String password, String name, String tel, Agent office) {
this.type = type;
this.email = email;
this.password = password;
this.name = name;
this.tel = tel;
this.regDate = new Date();
this.lastActive = null;
this.office = office;
}
//Getters
@Id
@SequenceGenerator(name = "USERID_SEQ", sequenceName = "USERID_SEQ",allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERID_SEQ")
@Column(name = "ID")
public Long getId() {
return id;
}
@Column(name = "TYPE")
public UserType getType(){
return type;
}
@Column(name = "EMAIL")
public String getEmail() {
return email;
}
@Column(name = "PASSWORD")
public String getPassword() {
return password;
}
@Column(name = "NAME")
public String getName() {
return name;
}
@Column(name = "TEL")
public String getTel() {
return tel;
}
@Column(name = "DATE_REG")
public Date getRegDate() {
return regDate;
}
@Column(name = "LAST_ACTIVE")
public Date getLastActive() {
return lastActive;
}
@ManyToOne (targetEntity = Agent.class, fetch = FetchType.EAGER)
@JoinColumn(name = "OFFICEID")
public Agent getOffice() {
return office;
}
// Setters
}
Controller for it
package com.Controllers;
import com.Entity.AgentType;
import com.Entity.User;
import com.Services.AgentService;
import com.Services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
//TODO: TEST CONTROLLER SUBJECT TO DELETE
@Controller
public class ViewController {
@Autowired
private UserService userService;
@Autowired
private AgentService agentService;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public ModelAndView listUsersPage(){
List<User>list = userService.getAll();
return new ModelAndView("fragments/userss.vm","users",list);
}
@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
public ModelAndView edit(@PathVariable Long id){
return new ModelAndView("fragments/edit.vm",
"user", (User)userService.getById(id));
}
//FUNCTIONAL
@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
public ModelAndView delete(@PathVariable Long id){
userService.delete(userService.getById(id));
return new ModelAndView("redirect:/list");
}
@RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView update(User user){
User user1 = user;
//userService.update(user1);
return new ModelAndView("redirect:/list");
}
//Model Attributes
@ModelAttribute
public void userTypesList(Model model){
model.addAttribute("types", userService.getPositions());
}
@ModelAttribute
public void officesList(Model model){
model.addAttribute("offices", agentService.getAllByType(AgentType.OFFICE));
}
}
and a pages (.vm) to add new or edit existing users(just one example the edit page):
<title>EDIT USER</title>
<body>
<form method="post" action="/update">
id:
<input type="text" name="id" path="id" value="$user.id"/> <br>
Type:
<select name="type" path="type">
<option hidden selected>$user.type</option>
#foreach($type in $types)
<option value="$type">$type</option>
#end
</select> <br>
e-mail:
<input type="text" name="email" path="email" value="$user.email"/> <br>
Password:
<input type="text" name="password" path="password" value="$user.password"/> <br>
Name:
<input type="text" name="name" path="name" value="$user.name"/> <br>
Tel:
<input type="text" name="tel" path="tel" value="$user.tel"/> <br>
Reg Date:
<input type="date" name="regDate" path="regDate" value="$user.regDate"/> <br>
Last Active:
<input type="date" name="lastActive" path="lastActive" value="$user.lastActive"/> <br>
Office:
<select name="office" path="office">
<option hidden selected value="$user.office">$user.office.name</option>
#foreach($office in $offices)
<option value="$office">$office.name</option>
#end
</select> <br>
<input type="submit" value="Update"/>
</form>
</body>
The problem is that I cant manage to save the updated User via /update(User user). I
ve tried different ways, but still no success.
Whis this code I`m getting HTTP Status 400 – Bad Request. The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).
Could you please help me out? What is wrong with it?
In your code you are missing a couple of things. Frist of all, you miss the model attribute specified in the form:
<form method="post" action="/update" modelAttribute="user">
Second, you are missing the model attribute specified in the post method:
@RequestMapping(value = "/update", method = RequestMethod.POST)
public ModelAndView update(@ModelAttribute("user") User user){
User user1 = user;
userService.update(user1);
return new ModelAndView("redirect:/list");
}
If you need further details, you can read Getting Started with Forms in Spring MVC