我如何使用一个控制器中定义的变量跨多个不同的控制器使用?
How do i use variable defined in one controller be used across multiple different 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";
}
}
并且有多个控制器(例如,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";
}
}
我不想将所有控制器代码合并到一个控制器中。
我只需要在用户注册或登录网站时保存 userId,然后在许多其他控制器上使用它。任何干净的解决方案将不胜感激。
与其将其保存为 UserController 的局部变量,不如将其保存在另一个 Bean 中,例如在 UserService 中,所有控制器将对其执行@Autowired 并获取用户 ID 信息。
您可以使用会话,
session 将在自定义时间段内存储来自用户的自定义值的值,持续时间可以是应用程序启动的时间。
要存储,您可以像这样设置控制器:
@RequestMapping(method = RequestMethod.GET)
public String testMestod(HttpServletRequest request){
User user= (User)request.getSession().setAttribute("userId",value);
return "test";
}
要获取值,您可以使用此方法:
User user= (user)session.getAttribute("userId");
更多信息link
https://www.techgeeknext.com/spring-boot/spring-boot-session-management
Spring 中 bean 的默认作用域是 singleton。因为我在你的代码中没有看到任何改变它的东西,所以我假设你的控制器是单例的。
您不想在单例中创建依赖于会话的实例变量 类。使用这个 protected int userId
实例变量是个坏主意。例如,如果您有两个用户同时浏览您的应用程序,一个用户可能会使用另一个用户的 userid
.
检索信息
通常推荐的获取用户信息的方法是使用SecurityContext
(来自另一个的用法示例。我们可以从SecurityContextHolder
检索SecurityContext
.
其他解决方案是在端点注入 Authentication
或 Principal
,例如:
@Controller
public class MyController {
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
}
这两种解决方案都假定我们已经使用 Spring 安全性正确实施了身份验证。
假设您希望在会话的多个控制器之间共享用户 ID。
在这种情况下,您可以使用会话范围的 bean 来存储 userId
。将为每个会话创建会话作用域 bean 的新实例,并且它将在该会话中保持活动状态。一旦会话失效,会话范围的 bean 将自动销毁。请参考下面的示例,了解如何创建会话范围的 bean 及其用法:
会话作用域 bean:
@Getter
@Setter
@NoArgsConstructor
@Component
@SessionScope //scope of this bean is session
public class UserDetails {
private String userId;
}
将会话作用域的 bean 注入您的控制器:
用户控制器
@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";
}
}
资产控制器
@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";
}
}
有关 session scoped beans 的更多信息,请参阅 spring 文档。
注意:请确保您没有在活动会话之外访问会话范围的 bean。
我有一个控制器:
@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";
}
}
并且有多个控制器(例如,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";
}
}
我不想将所有控制器代码合并到一个控制器中。 我只需要在用户注册或登录网站时保存 userId,然后在许多其他控制器上使用它。任何干净的解决方案将不胜感激。
与其将其保存为 UserController 的局部变量,不如将其保存在另一个 Bean 中,例如在 UserService 中,所有控制器将对其执行@Autowired 并获取用户 ID 信息。
您可以使用会话, session 将在自定义时间段内存储来自用户的自定义值的值,持续时间可以是应用程序启动的时间。
要存储,您可以像这样设置控制器:
@RequestMapping(method = RequestMethod.GET)
public String testMestod(HttpServletRequest request){
User user= (User)request.getSession().setAttribute("userId",value);
return "test";
}
要获取值,您可以使用此方法:
User user= (user)session.getAttribute("userId");
更多信息link https://www.techgeeknext.com/spring-boot/spring-boot-session-management
Spring 中 bean 的默认作用域是 singleton。因为我在你的代码中没有看到任何改变它的东西,所以我假设你的控制器是单例的。
您不想在单例中创建依赖于会话的实例变量 类。使用这个 protected int userId
实例变量是个坏主意。例如,如果您有两个用户同时浏览您的应用程序,一个用户可能会使用另一个用户的 userid
.
通常推荐的获取用户信息的方法是使用SecurityContext
(来自另一个SecurityContextHolder
检索SecurityContext
.
其他解决方案是在端点注入 Authentication
或 Principal
,例如:
@Controller
public class MyController {
@RequestMapping(value = "/username", method = RequestMethod.GET)
@ResponseBody
public String currentUserName(Principal principal) {
return principal.getName();
}
}
这两种解决方案都假定我们已经使用 Spring 安全性正确实施了身份验证。
假设您希望在会话的多个控制器之间共享用户 ID。
在这种情况下,您可以使用会话范围的 bean 来存储 userId
。将为每个会话创建会话作用域 bean 的新实例,并且它将在该会话中保持活动状态。一旦会话失效,会话范围的 bean 将自动销毁。请参考下面的示例,了解如何创建会话范围的 bean 及其用法:
会话作用域 bean:
@Getter
@Setter
@NoArgsConstructor
@Component
@SessionScope //scope of this bean is session
public class UserDetails {
private String userId;
}
将会话作用域的 bean 注入您的控制器:
用户控制器
@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";
}
}
资产控制器
@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";
}
}
有关 session scoped beans 的更多信息,请参阅 spring 文档。
注意:请确保您没有在活动会话之外访问会话范围的 bean。