我需要从我的剩余资源中记录所有更新操作并存储到数据库日志表中。
这个想法是存储如下信息:
- 登录用户
- 关于更新/保存实体的操作描述
- 更新的字段和参考键
我的应用程序与 Java EE8 兼容,它使用 REST / EJB 和 CDI 的东西。
起初我想在 EJB 端处理所有这些东西,但是暴露的服务不需要在方法签名上登录用户,所以添加它会导致强制..
有什么方法可以发送用户信息,通常由 webrequest 检索(我们使用会话令牌模型身份验证)并通过 EJB 注入?
我需要从我的剩余资源中记录所有更新操作并存储到数据库日志表中。
这个想法是存储如下信息:
我的应用程序与 Java EE8 兼容,它使用 REST / EJB 和 CDI 的东西。
起初我想在 EJB 端处理所有这些东西,但是暴露的服务不需要在方法签名上登录用户,所以添加它会导致强制..
有什么方法可以发送用户信息,通常由 webrequest 检索(我们使用会话令牌模型身份验证)并通过 EJB 注入?
如前所述, SessionContext.getCallerPrincipal().getName() 不起作用,因为身份验证机制不提供它。
经过一些尝试,我发现了这个:
在 EJB 方面
@RequestScoped
public class UserInfo {
private String userId;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
if (this.userId != null) throw new UncheckedException("cannot infer userid twice");
this.userId = userId;
}
}
在 REST 方面
@Inject
UserInfo userInfo;
void userAuthenticated(...) {
String userId = ... // get userid from access token through **WebRequest** object
userInfo.setUserId(userId);
}
边注
老实说,我更愿意在UserInfo构造函数上注入用户 ID ,但我不允许这样做,因为WebRequest对象不属于 EJB 上下文
替代方式
使用响应过滤器将所有日志记录过程移动到 REST 端。
示例代码:
@Provider
public class LoggingFilter implements ContainerResponseFilter {
@Context
HttpServletRequest webRequest;
@Context
ResourceInfo resinfo;
@Inject
LoggingService loggingService;
@Override
public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) {
final Method resourceMethod = resinfo.getResourceMethod();
if (resourceMethod.isAnnotationPresent(Loggable.class) && containerResponseContext.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL) {
// get all method's info and log to database ...
}
}
如果您的会话管理设置正确,您可以通过以下方式注入会话上下文:
@Resource
SessionContext sessionContext;
然后:
sessionContext.getCallerPrincipal().getName()
是您的登录用户。