2016-09-19 36 views
0

everyone。Spring MVC应用下的共享HashMap

我正在用Spring MVC构建一个网站,并将控制器配置为单例。我想在整个应用程序下创建一个共享的HashMap。

也就是说:当一个新用户注册一个用户帐户时,我会给他发送确认码并将其放入HashMap中。用户可以将确认代码提交给其他页面,也许在其他浏览器会话中,因此必须通过不同的会话访问HaspMap。

我正在通过将它保存到数据库表中来实现此功能,但是我想知道如何在不使用数据库的情况下以这种方式执行此操作。

回答

0

在春天的上下文中创建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来避免创建新视图并轻松检查地图的内容。

+0

谢谢,这是一个非常明确的解决方案。 –

0

没什么,使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块来放置并获取密钥。

但是,一旦重新启动应用程序服务器后,您将无法获得这些信息。

+0

感谢您的回答,考虑到我使用Spring MVC,我选择了其他答案。祝你今天愉快。 –

0

我不会直接推荐分享地图。这几乎没有任何有效的理由存在。相反,我建议你抽象出用户帐户的逻辑。

这样你编程到接口,如果以后你需要改变你的实现(比如说去数据库而不是地图),你只需要替换你的实现类,其他东西都不需要改变。下面例子中的关键是你的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<>(); 
    } 
+0

感谢@amin,这是一个很好的解决方案,但考虑到我正在制作一个简单而轻便的项目,所以我选择了其他答案。祝你今天愉快。 –