简体   繁体   English

我如何使用一个 controller 中定义的变量跨多个不同的 controller 使用?

[英]How do i use variable defined in one controller be used across multiple different controller?

I have one controller as:我有一个 controller 作为:

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    protected int userId; // I need to use it across many other controllers. HOW?

    @GetMapping("/")
    private String viewHomePage(Model model) {
        
        return "eAccounts";
    }

    @GetMapping("/dashboard")
    private String getDashboardPage() {
        return "dashboard";
    }

    @GetMapping("/signup")
    private String getSignupPage(Model model) {
        User user = new User();
        model.addAttribute("user", user);
        return "signup";
    }

    @PostMapping("/verifySignup")
    private String verifySignup(@ModelAttribute("user") User user, Model model, HttpServletRequest request) {
    if (userService.verifySignup(user) == 1) {
        userId = user.getId();// save user id for later use
        return "redirect:/dashboard";
    }

    return "signup";
    }
}

And there are multiple controllers (eg, assetController, liabilityController, etc):并且有多个控制器(例如,assetController、liabilityController 等):

@Controller
public class AssetController {
    @Autowired
    private AssetService assetService;

    @GetMapping("/assets")
    public String getAssetsPage(Model model) {
        model.addAttribute("listAssets", assetService.getAllAssets(userId)); // here i need to use userId, and at many more places
        return "assets";
    }
}

I don't want to merge all my controllers code in one single controller. I just need to save userId whenever user signs up or login in the website, and then use it across many other controllers.我不想将我所有的控制器代码合并到一个 controller 中。我只需要在用户注册或登录网站时保存userId ,然后在许多其他控制器上使用它。 Any clean solution will be appreciated.任何干净的解决方案将不胜感激。

The default scope for beans in Spring is singleton . Spring 中 bean 的默认 scope 是singleton Since I don't see anything in your code which changes that, I would assume that your controllers are singleton.因为我在你的代码中没有看到任何改变它的东西,所以我假设你的控制器是 singleton。

You don't want to create instance variables, which depend on sessions, in singleton classes.您不想在 singleton 类中创建依赖于会话的实例变量。 It is a bad idea to have this protected int userId instance variable.拥有这个protected int userId实例变量是个坏主意。 For example, if you have two users browsing your application in the same time, one user might retrieve information using the other user's userid .例如,如果您有两个用户同时浏览您的应用程序,一个用户可能会使用另一个用户的userid检索信息。

Usually the recommended way to get user information is to use the SecurityContext (example of usage from another question . We can retrieve the SecurityContext from the SecurityContextHolder .通常推荐的获取用户信息的方法是使用SecurityContext (来自另一个问题的用法示例。我们可以从SecurityContextHolder SecurityContext

Other solution would be to inject an Authentication or a Principal at the endpoints, such as:其他解决方案是在端点注入AuthenticationPrincipal ,例如:

@Controller
public class MyController {

    @RequestMapping(value = "/username", method = RequestMethod.GET)
    @ResponseBody
    public String currentUserName(Principal principal) {
        return principal.getName();
    }
}

Both of these solutions assume that we have correctly implemented authentication with Spring Security.这两种解决方案均假定我们已使用 Spring 安全性正确实施身份验证。

Assuming you want share the user id across multiple controllers for a session.假设您希望在 session 的多个控制器之间共享用户 ID。

In this case you can use session scoped bean to store userId .在这种情况下,您可以使用 session 作用域 bean 来存储userId New instance of session scoped bean will be created for each session and it will remain active for that session. Session scoped bean will be automatically destroyed once session is invalidated.将为每个 session 创建 session 作用域 bean 的新实例,它将为该 session 保持活动状态。一旦 session 失效,Session 作用域 bean 将自动销毁。 Please refer below example for how to create session scoped bean and its usage:请参考下面的示例,了解如何创建 session scoped bean 及其用法:

Session scoped bean: Session 作用域 bean:

@Getter
@Setter
@NoArgsConstructor
@Component
@SessionScope //scope of this bean is session
public class UserDetails {
    private String userId;
}

Inject session scoped bean to your controllers:将 session 作用域 bean 注入您的控制器:

UserController用户控制器

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private UserDetails userDetails; //adding session scoped bean

    @GetMapping("/")
    private String viewHomePage(Model model) {

        return "eAccounts";
    }

    @GetMapping("/dashboard")
    private String getDashboardPage() {
        return "dashboard";
    }

    @GetMapping("/signup")
    private String getSignupPage(Model model) {
        User user = new User();
        model.addAttribute("user", user);
        return "signup";
    }

    @PostMapping("/verifySignup")
    private String verifySignup(@ModelAttribute("user") User user, Model model, HttpServletRequest request) {
        if (userService.verifySignup(user) == 1) {
            userDetails.setUserId(user.getId());// save user id in session scoped bean
            return "redirect:/dashboard";
        }

        return "signup";
    }
}

AssetController资产控制器

@Controller
public class AssetController {
    @Autowired
    private AssetService assetService;

    @Autowired
    private UserDetails userDetails;

    @GetMapping("/assets")
    public String getAssetsPage(Model model) {
        model.addAttribute("listAssets", assetService.getAllAssets(userDetails.getUserId())); //get user id from session scoped bean

        return "assets";
    }
}

Please refer spring docs for more information on session scoped beans .有关session 作用域 bean的更多信息,请参阅 spring 文档。

Note: Please make sure you are not accessing session scoped bean outside the active session.注意:请确保您没有访问活动 session 之外的 session 作用域 bean。

Instead of saving it as a local variable of UserController, save it in another Bean for example in UserService, and all controllers will do @Autowired to it and will get the user id info.不要将它保存为 UserController 的局部变量,而是将它保存在另一个 Bean 中,例如在 UserService 中,所有控制器都会对其执行 @Autowired 并获取用户 ID 信息。

You can use sessions, sessions will store value for custom values from an user for a custom period of time the duration could be the time as the application is up.您可以使用会话,会话将在自定义时间段内存储来自用户的自定义值的值,持续时间可以是应用程序启动的时间。

to store you can set a controler like that:存储你可以像这样设置一个控制器:

@RequestMapping(method = RequestMethod.GET)
public String testMestod(HttpServletRequest request){
   User user= (User)request.getSession().setAttribute("userId",value);
   return "test";
}

and to get the value you can use this method:并获得您可以使用此方法的值:

User user= (user)session.getAttribute("userId");

more info on this link https://www.techgeeknext.com/spring-boot/spring-boot-session-management有关此链接的更多信息https://www.techgeeknext.com/spring-boot/spring-boot-session-management

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Postman 测试控制器的方法,该方法在 Spring 应用程序中将一个(或多个)对象作为参数? - How do I test with Postman a Controller's method which has one (or multiple) objects as parameters in a Spring Application? 如何使用 Java/JavaFX MVC 跨多个 Controller 持久化用户 model 的单个实例? - How would one persist a single instance of a User model across multiple Controller with Java/JavaFX MVC? 如何在 Spring 中使用来自不同包的 rest 控制器? - How can I use a rest controller from a different package in Spring? 如何在JavaFX中使用来自另一个Controller的变量 - How can I use a variable from another Controller in JavaFX 如何在播放模板中声明变量并在控制器中访问它? - How do I declare a variable in play template and access it in controller? 我如何更改我在不同类中定义的变量 - How do i change a variable that i have defined in a different class 如何将用户对象从一个控制器传递到另一个JavaFX控制器? - How to pass the User object from one Controller to the different JavaFX Controller? 如何在SpringMVC中将一个控制器中的会话变量访问到另一个控制器? - How to access the session variable in one controller to the other controller in SpringMVC? 如何在Spring MVC中访问另一个控制器中一个控制器的请求参数? - How to access the request parameter of one controller in a different controller in Spring MVC? 如何在多个类别中使用扫描仪? - How do I use a scanner across multiple classes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM