SpringMVC应用程序下的共享HashMap
各位 我正在用SpringMVC构建一个网站,并将控制器配置为单例。我想在整个应用程序下创建一个共享HashMap 也就是说:当一个新用户注册了一个用户帐户时,我会向他发送确认代码并将其放入HashMap中。用户可以将确认代码提交到其他页面,可能是在其他浏览器会话中,因此HaspMap必须可以由不同的会话访问SpringMVC应用程序下的共享HashMap,spring,spring-mvc,session,servlets,hashmap,Spring,Spring Mvc,Session,Servlets,Hashmap,各位 我正在用SpringMVC构建一个网站,并将控制器配置为单例。我想在整个应用程序下创建一个共享HashMap 也就是说:当一个新用户注册了一个用户帐户时,我会向他发送确认代码并将其放入HashMap中。用户可以将确认代码提交到其他页面,可能是在其他浏览器会话中,因此HaspMap必须可以由不同的会话访问 我是通过将其保存到数据库表中来实现此功能的,但我想知道如何在不使用数据库的情况下以这种方式实现此功能 没什么,将HashMap设置为静态并在任何类中声明时初始化 public class
我是通过将其保存到数据库表中来实现此功能的,但我想知道如何在不使用数据库的情况下以这种方式实现此功能 没什么,将
HashMap
设置为静态并在任何类中声明时初始化
public class AnyClass{
public static Map<?> sessionMap = new HashMap<?>; //use anywhere in the project
}
公共类AnyClass{
publicstaticmap sessionMap=newhashmap;//在项目中的任意位置使用
}
在其他类中,使用AnyClass.sessionMap.put(key,value)
或AnyClass.sessionMap.get(key)
。直到您明确删除该键,或者直到您停止/重新启动该映射将包含这些信息的服务器
使用同步
块放置和获取密钥
但是,一旦重新启动应用服务器,您将无法获取这些信息。在spring上下文中将HashMap
创建为bean。如果使用基于XML的配置,可以通过以下方式进行:
<util:map id="theMap" />
要进行测试,请按如下方式访问:
http://host:port/context/sharedMap/put.service?key=keyOne&value=keytwo
Result: {"keyOne":"keytwo"}
http://host:port/context/sharedMap/put.service?key=keyTwo&value=valuetwo
Result: {"keyOne":"keytwo","keyTwo":"valuetwo"}
我只是使用了一个@ResponseBody
,以避免创建新视图并轻松检查地图内容。我不建议直接共享地图。几乎没有任何正当的理由存在。相反,我建议您抽象出用户帐户逻辑
这样,您就可以对接口进行编程,如果以后需要更改实现(比如转到数据库而不是映射),您只需替换实现类,而无需更改任何其他内容。下面示例中的关键是您的MapUserRepository是一个单例,因此它内部的映射在技术上是一个单例。您可能还希望根据您的用例使用ConcurrentHashMap
@Controller
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@RequestMapping(path = "/username", method = RequestMethod.POST)
public ResponseEntity<String> registerUser(@PathParam("username") String username) {
String confirmCode = userRepository.addUser(username);
return new ResponseEntity<String>(confirmCode, HttpStatus.OK);
}
}
@Controller
@RequestMapping("/another")
public class AnotherController {
@Autowired
private UserRepository userRepository;
public ResponseEntity<String> registerUser(@RequestParam("confimCode") String confirmCode) {
User user = userRepository.getUserByConfirmationCode(confirmCode);
// do something with the user or handle not found error.
return new ResponseEntity<String>("another operation", HttpStatus.OK);
}
}
public interface UserRepository {
public String addUser(String username);
public User getUserByConfirmationCode(String confirmationCode);
}
public class User {
public User(String username) {
this.username = username;
}
private final String username;
}
@Component
public class MapUserRepository implements UserRepository {
@Override
public String addUser(String username) {
// maybe check if the user name already exists.
String confirmation = "generate some code";
this.mapUsers.put(confirmation, new User(username));
// handle possible errors.
return confirmation;
}
@Override
public User getUserByConfirmationCode(String confirmationCode) {
// possibly handle errors if confirmation code is not valid.
return this.mapUsers.get(confirmationCode);
}
private final Map<String, User> mapUsers = new HashMap<>();
}
@控制器
@请求映射(“/users”)
公共类用户控制器{
@自动连线
私有用户存储库用户存储库;
@RequestMapping(path=“/username”,method=RequestMethod.POST)
公共响应注册器(@PathParam(“用户名”)字符串用户名){
字符串confirmCode=userRepository.addUser(用户名);
返回新的响应属性(确认码,HttpStatus.OK);
}
}
@控制器
@请求映射(“/other”)
公共类另一控制器{
@自动连线
私有用户存储库用户存储库;
公共响应注册器(@RequestParam(“confimCode”)字符串confirmCode){
User User=userRepository.getUserByConfirmationCode(confirmCode);
//对“用户”或“句柄未找到”错误执行某些操作。
返回新的响应状态(“另一个操作”,HttpStatus.OK);
}
}
公共接口用户存储库{
公共字符串addUser(字符串用户名);
公共用户getUserByConfirmationCode(字符串确认码);
}
公共类用户{
公共用户(字符串用户名){
this.username=用户名;
}
私有最终字符串用户名;
}
@组成部分
公共类MapUserRepository实现UserRepository{
@凌驾
公共字符串addUser(字符串用户名){
//可能需要检查用户名是否已经存在。
String confirmation=“生成一些代码”;
this.mapUsers.put(确认,新用户(用户名));
//处理可能的错误。
返回确认;
}
@凌驾
公共用户getUserByConfirmationCode(字符串确认码){
//如果确认代码无效,可能会处理错误。
返回此.mapUsers.get(确认码);
}
private final Map mapUsers=new HashMap();
}
谢谢@amin,这是一个很好的解决方案,但考虑到我正在做一个简单而轻松的项目,所以我选择了另一个答案。祝你今天愉快。谢谢你的回答,考虑到我使用的是SpringMVC,我选择了另一个答案。祝您有个美好的一天。
@Controller
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@RequestMapping(path = "/username", method = RequestMethod.POST)
public ResponseEntity<String> registerUser(@PathParam("username") String username) {
String confirmCode = userRepository.addUser(username);
return new ResponseEntity<String>(confirmCode, HttpStatus.OK);
}
}
@Controller
@RequestMapping("/another")
public class AnotherController {
@Autowired
private UserRepository userRepository;
public ResponseEntity<String> registerUser(@RequestParam("confimCode") String confirmCode) {
User user = userRepository.getUserByConfirmationCode(confirmCode);
// do something with the user or handle not found error.
return new ResponseEntity<String>("another operation", HttpStatus.OK);
}
}
public interface UserRepository {
public String addUser(String username);
public User getUserByConfirmationCode(String confirmationCode);
}
public class User {
public User(String username) {
this.username = username;
}
private final String username;
}
@Component
public class MapUserRepository implements UserRepository {
@Override
public String addUser(String username) {
// maybe check if the user name already exists.
String confirmation = "generate some code";
this.mapUsers.put(confirmation, new User(username));
// handle possible errors.
return confirmation;
}
@Override
public User getUserByConfirmationCode(String confirmationCode) {
// possibly handle errors if confirmation code is not valid.
return this.mapUsers.get(confirmationCode);
}
private final Map<String, User> mapUsers = new HashMap<>();
}