【问题标题】:How can I save information for current user in Spring & Hibernate?如何在 Spring & Hibernate 中保存当前用户的信息?
【发布时间】:2023-03-11 03:22:01
【问题描述】:

我有一个 User 表和一个 UserInfo 表来保存用户的个人信息。我要做的是在登录后添加个人信息。具有 userId 列的表之间存在 OneToOne 关系,因此我将其定义如下:

UserInfo 类:

public class UserInfo {

//...

@OneToOne
@JoinColumn(name="user_id")
private User user;
// ...
}

用户类:

 public class User implements UserDetails {
// ...

 @OneToOne(mappedBy="user", cascade = CascadeType.ALL, fetch=FetchType.LAZY,optional=true)
 private UserInfo userInfo;

 ...
}

登录后,我想为当前用户添加一些用户信息到数据库中。但我不知道如何在控制器中保存用户信息?我应该像下面那样保存 User 对象吗?我已经搜索过了,有一种方法可以获取当前用户的信息:

(User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();

但是当我尝试在控制器中使用它时,它只会返回 null。如何为已登录的用户进行此类操作(添加个人信息)?

@RequestMapping(value = "/show", method = RequestMethod.POST)
public ModelAndView newUser(ModelMap model, Principal principal) {


    ModelAndView result = new ModelAndView("home");

    User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();


    UserInfo userinfo = new UserInfo();

    userinfo.setPlacesVisit(userinfo.getPlacesVisit());
    user.setUserInfo(userinfo);

    userService.save(user);

    String message = "Userinfo was successfully added.";
    result.addObject("message", message);

    return result;

}

【问题讨论】:

  • 你在使用 Spring Security 吗?
  • 是的,我正在使用 Spring Security。

标签: java mysql spring hibernate jsp


【解决方案1】:

而不是保存当前对象更新当前对象。在设置 UserInfo 之后首先在控制器中获取当前用户对象,然后更新数据库中的用户对象。

 @RequestMapping(value = "/show", method = RequestMethod.POST)
    public ModelAndView newUser(ModelMap model, Principal principal) {
        String userName=principal.getName(); // username or email using user login
        User user=userService.getUserByName(userName); // retrieve current user information
        UserInfo userinfo = new UserInfo();  // create userinfor object
        userinfo.setPlacesVisit(userinfo.getPlacesVisit());
            user.setUserInfo(userinfo);   // set userinfo to user
        userService.update(user);  // update user
         String message = "Userinfo was successfully added.";
             result.addObject("message", message);
        return result;

    }

【讨论】:

  • 我解决了这个问题,但现在的问题是,每当我更新配置文件时,它都会在 userinfo 表中插入一个新列。例如,如果我在每次保存这些信息时更新我的​​个人资料信息 5 次,它会创建一个新行。我怎样才能为相关用户保留一行?
  • 在休眠中使用 sessionFactory.getCurrentSession().update(object) 来更新 Object。
【解决方案2】:

您可以使用Principal 参数向用户检索:

public ModelAndView newUser(ModelMap model, Principal principal) {

  User activeUser = (User) ((Authentication) principal).getPrincipal();

}

SecurityContextHolder 是Spring Security 的一部分。如果你想使用这个组件,你必须为你的应用程序的登录设置 Spring Security,以便能够在你的 REST 控制器中检索当前用户 (javax.security.Principal)

Spring Security Documentation

【讨论】:

  • 我正在尝试使用 Principal 参数。但它为该行给出了此错误: java.lang.ClassCastException: java.lang.String cannot be cast to org.temp.model.User 并且出现了一种文件下载弹出窗口我不不知道是什么。你检查过我的控制器是不是其余的都是真的?我的意思是声明之类的东西。
  • 您的休息控制器设置为 POST。正常吗?也许你可以试试这个solution
【解决方案3】:

您可以使用会话来保存会话属性。在春季,您可以使用

ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
           HttpSession session = attr.getRequest().getSession();

【讨论】:

    【解决方案4】:

    您可以在会话中保存已登录的用户:

    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();
    request.getSession().setAttribute("key", user);
    

    如果您想获取当前登录的用户,只需:

    (User) user = ((HttpServletRequest) request).getSession().getAttribute("key")
    

    这个例子是在 JSF 中的,但我相信没有 JSF 也是可能的

    【讨论】:

    • 在 JSF 中创建带有 User 实例的 SessionScoped bean 更好。它会自动存储在会话中
    • 好吧,我实际上是在使用 JSP。
    猜你喜欢
    • 1970-01-01
    • 2022-12-23
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    相关资源
    最近更新 更多