这个问题我已经纠结了一段时间了。我想为show和update操作使用相同的条纹ActionBean。但是,我还不能想出如何以一种干净的方式实现这一点,从而允许当前用户对对象所有权进行可靠的绑定、验证和验证。
例如,假设我们的action bean接受一个postingId。该帖子属于已登录的用户。我们可能会有这样的东西:
@UrlBinding("/posting/{postingId}")
@RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean现在,对于show操作,我们可以定义:
private int postingId; // assume the parameter in @UrlBinding above was renamed
private Posting posting;现在使用@After(stages = LifecycleStage.BindingAndValidation)来获取Posting。我们的@After函数可以验证当前登录的用户是否拥有该帖子。我们必须使用@After,而不是@Before,因为postingId事先不会绑定到参数。
但是,对于update函数,您希望使用@Before而不是@After将Posting对象绑定到Posting变量,以便将返回的表单条目应用于现有onto对象之上,而不是应用到一个空的存根上。
定制的TypeConverter<T>在这里可以很好地工作,但是因为会话不能从TypeConverter接口获得,所以很难在绑定期间验证对象的所有权。
我能看到的唯一解决方案是使用两个单独的action bean,一个用于show,另一个用于update。但是,如果这样做,<stripes:form>标记及其下游标记将无法正确填充表单的值,因为beanclass或action标记必须映射回相同的ActionBean。
据我所知,Stripes模型只有在操作简单(非POJO)参数时才能保持一致。在任何其他情况下,您似乎都会遇到从数据存储绑定对象并用从客户端发送的更新覆盖它的问题。
我一定是漏掉了什么。经验丰富的Stripes用户的最佳实践是什么?
发布于 2013-01-15 08:15:44
在我看来,授权与对象水合是正交的。我的意思是,您应该将对象水合的关注点(在本例中,使用postingId并将其转换为Posting)与确定用户是否有权在该对象上执行操作(如显示、更新、删除等)分开。
对于对象水合,我使用TypeConverter<T>,并且我水合对象而不考虑会话用户。然后在我的ActionBean里,我在二传手周围有一个守卫,所以...
public void setPosting(Posting posting) {
if (accessible(posting)) this.posting = posting;
}accessible(posting)看起来像这样..。
private boolean accessible(Posting posting) {
return authorisationChecker.isAuthorised(whoAmI(), posting);
}那么您的show()事件方法将如下所示...
public Resolution show() {
if (posting == null) return NOT_FOUND;
return new ForwardResolution("/WEB-INF/jsp/posting.jsp");
}另外,当我使用Stripes时,我经常在相同的Stripes ActionBean中有多个事件(比如“显示”或“更新”)。对我来说,在相关名词周围分组操作(动词)是有意义的。
使用干净的URL,您的ActionBean注释将如下所示...
@UrlBinding("/posting/{$event}/{posting}")
@RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean...where {$event}是事件方法的名称(即"show“或"update")。注意,我使用的是{posting},而不是{postingId}。
为了完整起见,下面是您的update()事件方法可能的样子……
public Resolution update() {
if (posting == null) throw new UnauthorisedAccessException();
postingService.saveOrUpdate(posting);
message("posting.save.confirmation");
return new RedirectResolution(PostingsAction.class);
}https://stackoverflow.com/questions/13977413
复制相似问题