将演示文稿(Struts)参数传递给(Spring)ApplicationContext并在Hibernate Interceptor中使用它们

Posted

技术标签:

【中文标题】将演示文稿(Struts)参数传递给(Spring)ApplicationContext并在Hibernate Interceptor中使用它们【英文标题】:Passing presentation (Struts) parameters to (Spring) ApplicationContext and use them in Hibernate Interceptor 【发布时间】:2011-09-16 11:32:28 【问题描述】:

很抱歉标题太长了,但我不知道有什么具体的方法。

我有什么:

我正在开发一个审计跟踪模块,它使用 Hibernate 拦截器来拦截 Hibernate 调用并添加审计日志条目。这很好用。

我的 Web 应用程序使用 Struts2 和 Spring。我的 Hibernate 拦截器可以访问 Spring 的 ApplicationContext。

我想要什么:

因为我想为每个审计日志条目“赋予意义”,所以我需要将在表示层 (Struts) 发出的每个请求的参数(例如字符串消息)传递给 Spring 的 ApplicationContext。这样,我可以访问 Hibernate Interceptor 中的参数并相应地记录它。

示例:

    Struts - 用户详细信息页面:setPassword(user1, mypass),生成一个 新消息“用户 1 更改了他/她的密码”。 此消息被注入到 Spring 的 ApplicationContext 中。 Hibernate Interceptor 拦截“更新”并从 Spring 的 ApplicationContext 获取上一条消息,并使用该消息创建一个新的日志条目。

你知道怎么做吗?

【问题讨论】:

【参考方案1】:

我假设您使用 Struts2 Spring 插件来集成两者。使用它时,您的 Struts 动作、拦截器由 Spring 对象工厂构建,因此可以从 Spring bean 的依赖注入中受益。

在 Spring 方面,一种方法可以(我没有尝试过)工作:像这样使用request scoped beans:

<bean id="myBean" class="com.foo.MyBean" scope="request"/>

Spring 容器通过使用 myBean bean 定义为每个 HTTP 请求创建一个新的 bean 实例。

在 Struts 方面(您的操作或自定义拦截器)您现在可以注入 Spring bean 并设置您的信息。您必须知道您的 bean 现在具有 state(您提供的信息)。

在 Hibernate 方面,您现在应该能够从上下文中获取 bean 并读取信息并记录它。

作为替代方案,您可能会考虑使用如here for the LOGBack logging framework 所述的 MDC(映射诊断上下文)。使用 MDC,您可以非常轻松地输入像 MDC.put("myKey", "myValue") 这样的值,并使用像 %XmyKey 这样的自定义模式记录它。此解决方案将完全绕过您的 Hibernate 拦截器。

【讨论】:

谢谢,这真的很有帮助。我成功使用了“请求”范围。【参考方案2】:

我以为 Hibernate 已经知道哪些字段是脏的,但我可能记错了。无论如何,我不确定这是解决此问题的最佳方法。

我会采用不同的方法并在服务/服务调用本身中执行此操作,而不是依赖 Hibernate 拦截器。 IMO Hibernate 拦截器在“概念”应用程序中太低了。 OTOH 服务已经充当了视图层和数据层之间的桥梁。

因为您 (a) 已经需要“手动”与服务层交互,并且 (b) Hibernate 拦截器对应用程序没有简单的看法(IMO 也不应该如此,但这只是 我的意见 :) 我会将审计提升到抽象层。

(我知道这不是一个答案和一个重定向,但评论太长了。)

【讨论】:

@anahnarciso 当然是这样,而且更干净,即使你使用了 AOP。将应用程序范围的行为与特定的实现联系起来几乎总是一个坏主意,并且会使测试变得更加困难。

以上是关于将演示文稿(Struts)参数传递给(Spring)ApplicationContext并在Hibernate Interceptor中使用它们的主要内容,如果未能解决你的问题,请参考以下文章

sh 使用并行运行并发作业,这里演示了如何将参数传递给每个worker。

将多个参数传递给rest API - Spring

通过 Postman 将文件作为参数传递给 Spring Web 服务

如何在spring hibernate中使用@NamedNativeQuery将参数传递给存储过程

Spring Cloud Netflix:通过 RequestInterceptor 将主机请求参数传递给 FeignClient

将命令行参数传递给在 Docker 中运行的 Java 应用程序(Spring Boot)