最近我正在使用spring开发一个小的restfulapi,我发现了modeldattribute注解。
我注意到它有一些非常有趣的行为,主要是您可以将它粘贴到一个方法上,并在调用给定请求的处理程序之前调用它,从而允许您在数据绑定到处理程序方法的参数之前执行任何操作。
我们想到的一个用法是默认值:
@ModelAttribute("defaultEntity")
public Entity defaultEntity() {
final var entity = new Entity();
entity.setName("default name");
return entity;
}
@PostMapping("/entity")
public Entity createNewEntity(@Valid @ModelAttribute("defaultEntity") Entity entity) {
dao.saveEntity(entity);
return entity;
}
在这种情况下,当post请求到达/entity时,首先发生的事情是 defaultEntity
将被调用,创建一个预先填充了一些默认值的实体。然后,spring将传入的数据绑定到其中(可能会覆盖默认值或保持原样),然后将其传递到 createNewEntity
处理程序。我觉得这真的很不错。
另一个令人惊讶的事实是,带注解的方法实际上可以采用与handler方法大致相同的方式获取参数。进行部分实体更新的简单方法如下:
// first fetch the original entity from the database
@ModelAttribute("originalEntity")
public Entity originalEntity(@PathVariable("id") long id ) {
return dao.getEntity(id);
}
// then let Spring bind data to the entity and validate it
@PostMapping("/entity/{id}")
public Entity updateEntity(@Valid @ModelAttribute("originalEntity") Entity entity) {
// and finally we save it
dao.saveEntity(entity);
return entity;
}
同样,这是出人意料的简单。
更令人惊讶的是,不同的模型属性可以相互依赖,因此如果需要,您可以拥有一个复杂的多阶段怪物:
// first fetch the original entity from the database
@ModelAttribute("originalEntity")
public Entity originalEntity(@PathVariable("id") long id ) {
return dao.getEntity(id);
}
// then let Spring bind data to the entity, validate it and do some processing to it
@ModelAttribute("boundAndValidatedEntity")
public Entity boundAndValidatedEntity(@Valid @ModelAttribute("originalEntity") Entity entity) {
processEntity(entity);
return entity;
}
// finally check that the entity is still valid and then save it
@PostMapping("/entity/{id}")
public Entity updateEntity(@Valid @ModelAttribute(value = "boundAndValidatedEntity", binding = false) Entity entity) {
dao.saveEntity(entity);
return entity;
}
显然,并非所有的模型属性都必须是同一类型的,有些属性可能依赖于来自不同位置的多个参数。它就像一个控制器中的迷你di容器。
但是,也有一些缺点:
据我所知,它只适用于查询参数,无法使它适用于其他类型的请求参数,例如请求主体或路径变量
所有的 ModelAttribute
-将始终调用单个控制器中带注解的方法,这些方法可以
对性能有影响
因为spring需要能够收集方法的所有参数(这可能是不可能的,例如当它们引用当前请求中不存在的路径变量时)
所以,虽然 ModelAttribute
由于这些问题,它本身似乎并没有太大的用处,我觉得它背后的主要思想——本质上允许您在绑定/验证方法参数之前控制方法参数的构造,同时能够轻松访问其他请求参数——是可靠的,可能非常有用。
所以,我的问题很简单——在spring中有什么东西本质上可以像modelattribute一样工作,但没有我提到的缺点吗?或者在第三方图书馆?或者我可以自己写这样的东西?
暂无答案!
目前还没有任何答案,快来回答吧!