2016-09-19 62 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,這是一個很好的解決方案,但考慮到我正在製作一個簡單而輕便的項目,所以我選擇了其他答案。祝你今天愉快。 –