我有这堂课:
@Component
@Scope("session")
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
@GenericGenerator(name = "incremental", strategy = "increment")
private Long userID;
@Column(nullable = false)
private String username;
@Column(nullable = false)
private String email;
@Column(nullable = false)
private String password;
// getters and setters
}
这个控制器:
@Controller
@SessionAttributes("user")
@Scope("request")
public class UserCreationWizard {
@Autowired
private User user;
@ModelAttribute("user")
private User createUser() {
return user;
}
@RequestMapping(value = "/new/users/page/", method = RequestMethod.GET)
public String begin(HttpServletRequest request) {
return "wizard";
}
@RequestMapping(value = "/new/users/page/{page}", method = RequestMethod.POST)
public String step(@ModelAttribute("user") User user,
@RequestParam("username") String username,
@RequestParam("email") String password,
@PathVariable() Integer page) {
return "wizard" + page;
}
@RequestMapping(value = "/new/users/page/end", params = "submit", method = RequestMethod.POST)
public String end(@RequestParam("password") String password) {
user.setPassword(password);
user.setActive(true);
user.setLastLoggedIn(Calendar.getInstance());
Session s = HibernateUtils.getSessionFactory().openSession();
Transaction t = s.beginTransaction();
try {
s.persist(user);
s.flush();
t.commit();
s.close();
} catch (HibernateException e) {
t.rollback();
}
return "wizard";
}
}
begin()
只是在用户创建向导中加载第一个视图(jsp)。它包含username
和email
的输入字段。在视图中,您进行POST表单提交,触发step()
。在第二个视图(向导+ page.jsp)中,您有一个password
字段和一个触发end()
的提交输入。
step()
中,我已经将User作为
一个ModelAttribute,我不需要为username和。设置它的字段
密码。它们会自动从RequestParams中获取
属性。但是在end()
中,我没有ModelAttribute,
我必须手动设置密码。 Spring如何管理这个?createUser()
方法,那么
应用程序失败,说它无法找到会话属性
“用户”。该方法如何作为方法链接到MethodAttribute
参数β我的一般问题是:春豆是否映射到他们的名字?例如。在这里,我在会话中将'user'作为用户和'user',将password作为requestparam,将'password'作为User成员变量。
答案 0 :(得分:1)
好的,很多问题。让我们看看,所有引用都是针对当前Spring MVC版本的文档。
1)您在user
属性中看到的行为在“Using @ModelAttribute on a method argument”部分进行了解释
方法参数上的@ModelAttribute指示参数应该 从模型中检索。如果模型中没有,则参数 应首先实例化,然后添加到模型中。一旦到场 在模型中,参数的字段应该从所有字段中填充 请求具有匹配名称的参数。这称为数据 Spring MVC中的绑定,一种非常有用的机制,可以帮助您避免使用 必须单独解析每个表单字段。
Spring是如何做到的?好吧,源代码是最终的答案,但并不难猜测:Spring知道参数是User
的一个实例,通过反射它可以读取类的方法,特别是它的 setters 。在这种情况下,它会找到setUsername()
和setEmail()
,这些方法的参数是String
,因此它与请求中的参数兼容。
(顺便说一下:@RequestParam("email") String password
可能是个错误。至少令人困惑)
2)方法createUser()
前面是注释@ModelAttribute("user")
。这由“Using @ModelAttribute on a method”
方法上的@ModelAttribute指示该方法的用途 添加一个或多个模型属性。
因此,此方法将与名称"user"
关联的对象放在模型上,然后可以通过其他方法(如step()
)用作参数。请注意,注释控制模型中对象使用的标识符。如果您将代码更改为
@ModelAttribute("strangeWeirdIdentifier")
private User createUser() { return user; }
应用程序将中断。但如果您将step()
签名更改为
public String step(@ModelAttribute("strangeWeirdIdentifier") User user,
@RequestParam("username") String username,
@RequestParam("email") String password,
@PathVariable() Integer page) {
3)1)和2)中描述的过程在请求期间将对象存储在模型中。使用类注释@SessionAttributes("user")
可以延长对象的生命周期,将其添加到当前Session
或等效的内容中。例如,您可以使用与Controller
方法相同的其他step()
中的对象。
最后要明确
希望这比官方文档更清晰,通常太简短,我会给你。