在我的Spring 4驱动的portlet中,我有一个包含日期字段的数据对象。在JSP视图中,我有两个单独的字段,日期(dd / mm / yyyy)和时间(hh / mm)。我的控制器中的操作处理程序使用@ModelAttribute
- 注释:
@ActionMapping(params = "action=update")
public void onUpdate(@Valid @ModelAttribute("myObject") MyObject myObject,
BindingResult bindingResult, ActionResponse response, SessionStatus status)
{
if (!bindingResult.hasErrors())
myObjectService.save(myObject);
else
// provide 'myObject' in the view which displays validation errors
}
我需要合并日期和时间才能验证表单数据onUpdate()
收到myObject
,因为在MyObject
中只有一个java.util.Calendar
- 字段用于完整的日期。
理念1解决此需求
现在我想,我还可以将日期分成MyObject
中的两个单独的字段,并提供一个按需合并值的getter:
@Column(name = "begin")
public Calendar getBegin()
{
// return calendar object built from this.beginDate and this.beginTime
}
但我认为这不是一个好主意有几个原因(见这个问题:Hibernate Annotations - Which is better, field or property access?) 我希望模型对象成为数据库记录的镜像,因此它应该在被分配之前进行验证。
创意2
另一个方法是,在设置日期或时间时,根据需要在myObject
中创建或修改日历对象:
@Column(name = "begin")
@Temporal(TemporalType.TIMESTAMP)
private Calendar begin;
public void setBeginDate(String value)
{
// assign a new calendar object to "begin", if "begin" is null
// set only day, month and year components on this calendar object
}
public void setBeginTime(String value)
{
// see "setBeginDate", do the same with hours and minutes
}
这里的问题是,如果只有一个字段“date”或“time”有效,则会创建一个新的日历对象。视图中的字段用当前日期或当前时间填充(取决于哪个值是正确的)
我甚至可以通过向模型添加另一个私有isValidDate
- 标志来解决此问题。但我认为这是一个不干净的解决方案。
结论
我认为控制器myObject
与实际模型对象myObject
之间存在很大差异。 <{1}}应该是模型对象,只要经过验证和“映射”即可。
所以我的问题在这里:
myObject
视为一个坏主意?@ModelAttribute
- 实例之前是否有方法映射和验证表单数据?答案 0 :(得分:0)
编辑:@initBinder
反之亦然(1个字段 - > N个属性)
我不知道框架是否可以开箱即用(N字段 - > 1属性),而不会进入绑定管道。
以下两个简单的解决方案可以解决这个问题:
以旧的“Struts”方式执行,并创建一个MyObjectForm
对象,您将在视图中专门使用该对象,然后将其在控制器中转换为MyObject
。
您仍然可以在技术上合理的服务层@Valid
使用MyObjectService
。
如果MyObject
不包含许多属性,请忘记@ModelAttribute
+控制器层验证,并为每个字段使用@RequestParam
。服务层验证仍在使用中。
你当然可以通过使用Spring MVC的内部工具手动将你的表单数据“绑定”到你的对象上,但最终它会像我的第二点,更令人困惑的管道。