everyone。Spring MVC应用下的共享HashMap
我正在用Spring MVC构建一个网站,并将控制器配置为单例。我想在整个应用程序下创建一个共享的HashMap。
也就是说:当一个新用户注册一个用户帐户时,我会给他发送确认码并将其放入HashMap中。用户可以将确认代码提交给其他页面,也许在其他浏览器会话中,因此必须通过不同的会话访问HaspMap。
我正在通过将它保存到数据库表中来实现此功能,但是我想知道如何在不使用数据库的情况下以这种方式执行此操作。
everyone。Spring MVC应用下的共享HashMap
我正在用Spring MVC构建一个网站,并将控制器配置为单例。我想在整个应用程序下创建一个共享的HashMap。
也就是说:当一个新用户注册一个用户帐户时,我会给他发送确认码并将其放入HashMap中。用户可以将确认代码提交给其他页面,也许在其他浏览器会话中,因此必须通过不同的会话访问HaspMap。
我正在通过将它保存到数据库表中来实现此功能,但是我想知道如何在不使用数据库的情况下以这种方式执行此操作。
在春天的上下文中创建HashMap
作为bean。如果您使用基于XML的配置,你可以这样来做:
<util:map id="theMap" />
然后,你可以通过使用@Autowired
或@Resource(name="theMap")
引用它:
@Controller
@RequestMapping("/sharedMap")
public class MapConsumerController {
@Resource(name="theMap")
private Map theMap;
@RequestMapping("/put.service")
public @ResponseBody Map<?,?> put(String key, String value){
this.theMap.put(key, value);
return this.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
来避免创建新视图并轻松检查地图的内容。
没什么,使HashMap
为静态并初始化当您在任何类声明。
public class AnyClass{
public static Map<?> sessionMap = new HashMap<?>; //use anywhere in the project
}
在其他类使用AnyClass.sessionMap.put(key,value)
或AnyClass.sessionMap.get(key)
.Till您明确remove
键或直到你stop/restart
服务器在此地图将包含这些信息。
使用Synchronize
块来放置并获取密钥。
但是,一旦重新启动应用程序服务器后,您将无法获得这些信息。
感谢您的回答,考虑到我使用Spring MVC,我选择了其他答案。祝你今天愉快。 –
我不会直接推荐分享地图。这几乎没有任何有效的理由存在。相反,我建议你抽象出用户帐户的逻辑。
这样你编程到接口,如果以后你需要改变你的实现(比如说去数据库而不是地图),你只需要替换你的实现类,其他东西都不需要改变。下面例子中的关键是你的MapUserRepository是一个单例,因此它内部的Map在技术上是一个单例。您可能还想根据您的用例使用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<>();
}
感谢@amin,这是一个很好的解决方案,但考虑到我正在制作一个简单而轻便的项目,所以我选择了其他答案。祝你今天愉快。 –
谢谢,这是一个非常明确的解决方案。 –