This class has three public methods:
- save: This saves a table to the user session
- restore: This gets a table from the user session
- reset: This deletes any table that may be in the session
The code of the class is the following:
public class GameSessionSaver {
private static final String STATE_NAME = "GAME_STATE";
@Inject
private HtmlTools html;
@Inject
Table table;
@Inject
ColorManager manager;
public void save(HttpSession session) {
Map<String,String> params = convertTableToMap();
session.setAttribute(STATE_NAME,params);
}
public void reset(HttpSession session) {
session.removeAttribute(STATE_NAME);
}
public Map<String,String> restore(HttpSession session){
Map<String,String> map=
(Map<String,String>)
session.getAttribute(STATE_NAME);
if( map == null ){ map = new HashMap<>(); }
return map;
}
private Map<String,String> convertTableToMap() {
Map<String, String> params = new HashMap<>();
for (int row = 0; row < table.nrOfRows(); row++) {
for (int column = 0;
column < table.nrOfColumns(); column++) {
params.put(html.paramNameGuess(row,column),
table.getColor(row,column).toString());
}
params.put(html.paramNameFull(row),
""+table.getFull(row));
params.put(html.paramNamePartial(row),
""+table.getPartial(row));
}
return params;
}
}
When we save the session and convert the table to a map, we use a HashMap. The implementation in this case is important. The HashMap class implements the Serializable interface; therefore, we can be safe putting it to the session. This alone does not guarantee that everything in HashMap is Serializable. The keys and the values in our case are Strings, and fortunately, the String class also implements the Serializable interface. This way, the converted HashMap object can be safely stored in the session.
Also note that, although serialization can be slow, storing HashMap in a session is so frequent that it implements its own serialization mechanism. This implementation is optimized and avoids serialization being dependent on the internal structure of the map.
The best solution could be to implement these in a separate class. You have homework!
The reset method is not used from the handler. This is invoked from the Mastermind class, that is, the servlet class to reset the game when we start it:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
GameSessionSaver sessionSaver = new GameSessionSaver();
sessionSaver.reset(request.getSession());
doPost(request, response);
}
Without this, playing the game against the machine once would just display the finished game every time we want to start it again, until we exit the browser and restart it or explicitly delete the JSESSIONID cookie somewhere in the advanced menu of the browser. Calling reset does not delete the session. The session remains the same, and thus the value of JSESSIONID too, but the game is deleted from the session object that the servlet container maintains.