gpt4 book ai didi

java - 如何在 Guice 中使用@SessionScoped

转载 作者:搜寻专家 更新时间:2023-10-31 19:35:42 26 4
gpt4 key购买 nike

你好
我目前正在玩 Guice 和@SessionScoped。为了让它更有意义,我决定构建一个(非常简单的)身份验证过程。

下面,我将解释我所做的每一步。然后我会问你一些问题。

[1] 我创建了一个代表一个人( guest 或用户)的身份类:

@SessionScoped
public class Identity implements Serializable
{
private String uid;
private String name;

public boolean isAuthenticate()
{
return uid != null;
}

public void logout()
{
this.uid = null;
}

/*Setters-Getters*/
}

[2] 接下来,我创建了一个用于登录用户的身份验证类:

public class Authentication
{
@Override
public Identity authenticate(String login, String password)
{
/*some code*/

Identity identity = new Identity();
identity.setUid(user.getId());
return identity;
}
}

[3] 然后,在我的 Servlet 中,我登录用户:

@RequestScoped
public class LoginAction
{
@Inject
Injector injector;

protected void login(HttpServletRequest req, HttpServletResponse resp)
{
Identity identity = injector.getInstance(Identity.class);
Authentication auth = new Authentication();
identity = auth.authenticate("login","password");
}
}

[4] 最后,我创建了一个过滤器来显示用户是否已通过身份验证:

@Singleton
public class SecurityFilter implements Filter
{
@Inject
private Injector injector;

@Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
{
Identity identity = injector.getInstance(Identity.class);

if(identity.isAuthenticate())
{
System.err.println("USER");
}
else
{
System.err.println("GUEST");
}

chain.doFilter(request, response);
}
}

嗯,这段代码不起作用。我的身份的 uid 始终为“空”。

让我们开始提问:

a - 首先,为什么我的代码不起作用?
b - @SessionScoped 是否等同于在 HttpSession 中设置对象?
c - 如何在 (http)session 中使 Identity 对象(仅它)无效?
d - 通常,在什么情况下我们必须使用@SessionScoped?

感谢您的阅读,
等待您的答复。

最佳答案

[a] 您正在将 Identity 的新实例分配给 LoginAction 中的局部变量,而不是替换由 Guice 管理的实例。您可以通过在 Guice 管理的现有 Identity 实例上填充 uidname 字段来解决该问题。

例如,代替

identity = auth.authenticate("login","password"); 

你可以说:

Identity identity = injector.getInstance(Identity.class);
Authentication auth = new Authentication();
Identity authenticated = auth.authenticate("login","password");
identity.setUid(authenticated.getUid());
identity.setName(authenticated.getName());

有更简洁的方法来做到这一点,但您明白了。

[b]/[d] 是的:@SessionScoped 相当于在HttpSession 中设置一个变量,这就是你会使用的那种情况它。对于需要在 session 中保持唯一但又需要对每个请求都可用的对象,您将需要它。

[c] 我不太清楚你的意思,但如果你想根据用户是否登录重定向到应用程序中的不同位置,你的过滤器设计是一种常见的方法。

您可以做的一些改进:

  • 拥有管理 session 用户的IdentitySessionScoped 服务,并确保它在Identity 实例上同步。这样,如果用户快速连续发出两个请求,您就不会遇到并发问题。
  • 优先注入(inject) Provider 而不是注入(inject) Injector(示例 here )以将您的类与 Guice 分离。
  • Inject dependencies into your classes' constructors ,而不是注入(inject)字段。这允许更轻松的测试(通过在测试中提供模拟/ stub 依赖项)。

关于java - 如何在 Guice 中使用@SessionScoped,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5777211/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com