在我的 Spring 4 驱动的 portlet 中,我有一个包含日期字段的数据对象。在 JSP View 中,我有两个单独的字段:日期 (dd/mm/yyyy) 和时间 (hh/mm)。我的 Controller 中的操作处理程序使用 @ModelAttribute
-annotation 接收表单数据:
@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
}
这里的问题是,如果只有“日期”或“时间”字段之一有效,则会创建一个新的日历对象。 View 中的字段填充当前日期或当前时间(取决于哪个值是正确的)
我什至可以通过向模型添加另一个私有(private) isValidDate
标志来解决这个问题。但我认为这是一个不干净的解决方案。
结论
我认为 Controller 的 myObject
和作为实际模型对象的 myObject
之间存在很大差异。一旦经过验证和“映射”,myObject
就应该是一个模型对象。
这是我的问题:
- 您认为最后一点是否表明使用
@ModelAttribute
通常是一个坏主意? - 或者是否有一种方法可以在创建
MyObject
实例之前映射和验证表单数据? - 如果没有,您建议如何解决该问题?
最佳答案
编辑:@initBinder
反过来也可以(1 个字段 -> N 个属性)
我不知道框架是否可以开箱即用地执行您想要的操作(N 个字段 -> 1 个属性),而无需进入绑定(bind)管道。
以下是解决该问题的两个简单解决方案:
按照旧的“Struts”方式进行操作,创建一个将在 View 中专用的
MyObjectForm
对象,然后在 Controller 中将其转换为MyObject
。 您仍然可以在服务层MyObjectService
使用您的@Valid
,这在技术上是合理的。如果
MyObject
不包含几十个属性,请忘记@ModelAttribute
+ Controller 层验证,只需使用@RequestParam
每个领域。服务层验证仍在进行中。
你当然可以破解一些东西,允许你使用 Spring MVC 的内部设施手动将表单数据“绑定(bind)”到你的对象,但最终它会像我的第二点一样,有更多令人困惑的管道。 p>
关于java - Spring Controller 预处理@ModelAttribute请求参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22906565/