服务层如何获取Session信息?
有没有一种方法可以将 Http/Wicket 会话信息共享到服务层而不引入 servlet api/Wicket 依赖项?
我将提供一些背景信息来说明我为什么要问这个问题,以防万一我遗漏了一些内容并问了错误的问题。
我有几个实体,它们具有可验证的属性组。 可验证意味着存在指示验证值、进行验证的用户以及验证日期的字段。 这就是这些实体的建模方式:
@Embeddable
public class ValidationBean<T> implements Serializable {
private T validated;
private String user;
private Date date;
// Constructors, getters, setters ahead.
// ...
}
@Entity
@Table(name="SOME_TABLE")
public class SomeEntity implements Serializable, SomeInterface {
// Some attributes which conform validation group 1
public String attribute11;
public String attribute12;
public String attribute13;
private ValidationBean<Integer> validationBean1 = new ValidationBean<Integer>();
// Some attributes which conform validation group 2
public String attribute21;
private ValidationBean<String> validationBean2 = new ValidationBean<Integer>();
// Constructors, various attribute getters with JPA annotations
// ...
@Embedded
@AttributeOverrides(/*various overrides, each entity/validation group has its own validation column names...*/)
public ValidationBean<Integer> getValidationBean1() { return validationBean1; }
@Embedded
@AttributeOverrides(/*various overrides, each entity/validation group has its own validation column names...*/)
public ValidationBean<Integer> getValidationBean2() { return validationBean2; }
}
当 ValidationBean
的 user
和 date
字段在表示层中自动修改时,检测到 >validated
字段。
所有这些都工作正常。现在,我正在努力寻找一个优雅的&与当前建模集成以满足以下要求的通用解决方案:当验证组中的任何属性的值发生更改,并且相关的 ValidationBean.validated 没有更改时,user< /code> 和
date
还必须使用当前用户的 id 和当前日期进行修改。
在我看来,有两种选择:将该逻辑放入表示层或业务/服务层
将其放入表示层将具有效率优势。实体存储在会话中,因此不必再次查询数据库来检查字段更改。但不幸的是,某些实体的某些字段已通过 ajax 更新,因此很难判断该实体是否真的发生了变化。除了表示层不负责满足此要求之外。
将它放在服务层似乎是最好的选择,而且我已经找到了一种可能的方法来正确处理这个问题。我想出了
@PreUpdate< /代码>
。很容易在@Entities上实现一个@PreUpdate方法来将DB中的值与即将更新的值进行比较,并相应地修改相关的ValidationBeans。这里的问题,我认为这是一个常见问题,是在业务层中,我没有从哪里获取
用户
id。当前用户Id存储在Session中,Session属于表示层。
因此,任何关于如何将 http 会话信息共享到服务层(不一定是 Wicket 特定的)的提示、评论、建议,甚至是满足此要求的替代方案都将受到欢迎。
UDPATE:遵循gkamal的建议,我将尝试以侵入性较小的方式集成 spring-security,只是为了利用 SecurityContext。我也希望得到有关此事的提示。
Is there a way I can share Http/Wicket Session information to the service layer without introducing servlet api/Wicket dependency?
I'll provide some context to why am I asking this question, just in case I'm missing something and asking the wrong question.
I've got several entities that have groups of attributes that can be validatable.
Being validatable means there are fields indicating the validation value, the user who made the validation and the date it was validated in.
This is how these entities are modelled:
@Embeddable
public class ValidationBean<T> implements Serializable {
private T validated;
private String user;
private Date date;
// Constructors, getters, setters ahead.
// ...
}
@Entity
@Table(name="SOME_TABLE")
public class SomeEntity implements Serializable, SomeInterface {
// Some attributes which conform validation group 1
public String attribute11;
public String attribute12;
public String attribute13;
private ValidationBean<Integer> validationBean1 = new ValidationBean<Integer>();
// Some attributes which conform validation group 2
public String attribute21;
private ValidationBean<String> validationBean2 = new ValidationBean<Integer>();
// Constructors, various attribute getters with JPA annotations
// ...
@Embedded
@AttributeOverrides(/*various overrides, each entity/validation group has its own validation column names...*/)
public ValidationBean<Integer> getValidationBean1() { return validationBean1; }
@Embedded
@AttributeOverrides(/*various overrides, each entity/validation group has its own validation column names...*/)
public ValidationBean<Integer> getValidationBean2() { return validationBean2; }
}
ValidationBean
's user
and date
fields are automatically modified in the presentation layer when a change in the validated
field is detected.
All of this is working correctly. Now, I'm trying to find an elegant & general solution that integrates with the current modelling to the following requirement: When any of the attributes in a validation group gets its value changed, and the related ValidationBean.validated
doesn't change, user
and date
must also be modified with the current user's id and the current date.
There are, as I see it, two alternatives; putting that logic in the presentation layer, or in business/service layer
Putting it in the presentation layer would have an efficieny advantage. Entities are stored in session so that the DB doesn't have to be queried again to check for field changes. But unfortunately, some entities have some of their fields ajax-updated and it would be hard to tell if the entity really changed. Apart from not being the presentation layer's responsability to fulfill this requirement.
Putting it in the service layer seems the best alternative, and I've already found a possible way to handle this properly. I've come up with
@PreUpdate
. It would be easy to implement a@PreUpdate
method on the @Entities to compare the values in DB with the values about to be updated, and modify the relatedValidationBeans
accordingly. The problem here, and I suppose it's a common problem, is that in the business layer, I don't have where to get theuser
id from. The current user Id is stored in the Session, which belongs to the presentation layer.
So, any tips, comments, recommendations on how can I share http session information to the service layer (not necessarily Wicket-specific), or even alternatives to fulfill this requirement will be welcome.
UDPATE : Following gkamal's suggestion, I'll try to integrate spring-security in the less intrusive way I can, just to take advantage of SecurityContext. I'd also appreciate tips on this matter.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决此问题的常用方法是引入一个 SecurityContext 类,该类将当前用户的详细信息保存为静态线程局部变量。该变量由安全过滤器或其他过滤器初始化(从 httpsession),并在请求处理完成后清除。 SecurityContext 类本身是业务层的一部分,它提供了 set / get 方法,因此没有任何 Web 层依赖项。
The common approach used to solve this is to introduce a SecurityContext class that holds the details of the current user as a static thread local variable. The variable is initialized (from the httpsession) by the security filter or some other filter and cleared after the request processing is complete. The SecurityContext class will itself be part of the business layer which provides a set / get methods and hence doesn't have any web layer dependency.