【问题标题】:Initializing a Spring Session Bean using an HttpRequest (using annotations)使用 HttpRequest 初始化 Spring Session Bean(使用注解)
【发布时间】:2016-11-28 19:06:39
【问题描述】:

我正在尝试构建(或扩充)一个使用 Spring bean 并使用注释初始化的 web 应用程序。我有一个需要初始化的 bean,但该 bean 需要一个 HttpServletRequest 才能正确初始化(它是一个用户身份 bean)。

我浏览了文档,看到了我需要的部分,但这些部分似乎并没有组合成一个完整的解决方案。

伪例子:

@Configuration
public class MyConfig {
    @Bean
    public UserBean userBean() {
        // initialize with HttpRequest somehow?
    }
}

@Controller
public class MyController {
    @Resource
    UserBean userBean;

    @RequestMapping(value="/userId", method=RequestMethod.GET)
    public String getUserInfo() {
        // do stuff with the initialized user bean here
    }
}

注意有多个控制器类,所以我不确定可能会先遇到哪个。

我看到了两件可以做的事情:

  1. MyConfig 类中以惰性方式初始化bean。但我不确定如何访问HttpServletRequest 对象。
  2. getUserInfo() 方法中将bean 注入到会话中。但是类中的每个方法可能都需要相同的初始化逻辑,我不确定如何将初始化的 UserBean 注入到会话中,以便其他控制器可以访问相同的 UserBean。

任何帮助/建议/等。将不胜感激

【问题讨论】:

  • 请记住,如果解决方案是骇人听闻的,则强烈表明它是错误的。 HttpServletRequest 是一个请求对象是有原因的,您是否考虑过将其作为参数传递给 UserBean 的方法?
  • UserBean 对象实际上是使用 HttpServletRequest 对象初始化的,例如UserBean 用户 = UserBean.create(request);

标签: java spring spring-mvc session


【解决方案1】:

您缺少的部分似乎是“spring scoped beans”功能。

基本上,作用域 bean 是由 spring 管理(创建/销毁)的 bean,因此您无需担心这一点。您也不必担心初始化。 Spring 为您处理。

请试试这个。将Scope 定义添加到您的UserBean 并将HttpServletRequest 注入您的UserBean

@Bean
@Scope("request")
public UserBean userBean() {
    return new UserBean();
}

@Component
public class UserBean {

  @Inject
  HttpServletRequest request;

  @PostConstruct
  public void init(){
    // Access request object to initialize your object
  }
}

编辑

如果您无法修改 UserBean,您可以获取请求并在 java 配置中初始化 bean。例如:

HttpServletRequest 请求 = ((ServletRequestAttributes) RequestContextHolder

@Bean
@Scope("request")
public UserBean userBean() {
   HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
   return new UserBean(request);
}

【讨论】:

  • 实际代码中的 UserBean 对象(或更具体地说,它的类似物)位于我无法控制的库中。我忘了提那个。所以我不能用 Bean 或 Scope 对其进行注释。
  • 这似乎是解决它的方法,但这会将 UserBean 仅放在请求范围内吗?还是会坚持下去?
  • @EdwardSwing 范围具有预定义的生命周期。请求范围数据仅在请求存在时才存在。坚持是一个完全不同的故事。在这种情况下,您需要将数据存储集成到您的应用程序中以保存您的数据
【解决方案2】:

如果我理解正确,您正在尝试创建某种服务器端会话存储。

如果是这种情况,您最好的选择可能是使用 Servlet 环境附带的会话处理。根据 Spring 文档,@RequestMapping-annotated 方法可以采用 javax.servlet.http.HttpServletRequest 类型的参数。

在这个对象上,您可以使用getSession() 方法来获取用户的会话,或者如果不存在则生成一个新的。你的 UserBean-class 将不再是一个 bean,只是一个普通的对象。您可以使用setAttribute(String, Object)- 将其存储在会话中,并使用getAttribute(String)- 方法读取它。

无论您在哪个控制器中,此会话对象都应包含相同的 UserBean 对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-19
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    相关资源
    最近更新 更多