Java 在Spring 4.0中未使用@SessionAttributes调用SessionAttributeStore实现中的StoreAttribute方法
我正在尝试使用Spring4.0在不同的选项卡中使用不同的模型。我在这里使用duckranger概述的解决方案-> 我的控制器如下所示:Java 在Spring 4.0中未使用@SessionAttributes调用SessionAttributeStore实现中的StoreAttribute方法,java,spring,session,spring-mvc,browser-tab,Java,Spring,Session,Spring Mvc,Browser Tab,我正在尝试使用Spring4.0在不同的选项卡中使用不同的模型。我在这里使用duckranger概述的解决方案-> 我的控制器如下所示: @Controller @RequestMapping("/counter") @SessionAttributes("mycounter") public class CounterController { @ModelAttribute("mycounter") public MyCounter populateCounter(){
@Controller
@RequestMapping("/counter")
@SessionAttributes("mycounter")
public class CounterController {
@ModelAttribute("mycounter")
public MyCounter populateCounter(){
return new MyCounter(0);
}
@RequestMapping(method = RequestMethod.GET)
public String get(@ModelAttribute("mycounter") MyCounter mycntr) {
return "counter";
}
// Obtain 'mycounter' object for this user's session and increment it
@RequestMapping(method = RequestMethod.POST)
public String post(@ModelAttribute("mycounter") MyCounter myCounter) {
myCounter.increment();
return "redirect:/counter";
}
}
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Counter</title>
</head>
<body>
<p>${mycounter.count}</p>
<form action="counter" method="post">
<input type="submit">
</form>
</body>
</html>
root-context.xml:
<bean id="requestMappingHandlerAdapter"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="sessionAttributeStore">
<ref bean="conversationalSessionAttributeStore" />
</property>
</bean>
<bean id="conversationalSessionAttributeStore"
class="de.telekom.cldb.admin.security.ConversationalSessionAttributeStore">
<property name="keepAliveConversations" value="10" />
<property name="requestMappingHandlerAdapter">
<ref bean="requestMappingHandlerAdapter" />
</property>
</bean>
SessionAttributeStore的实现与duckranger的代码完全相同:
public class ConversationalSessionAttributeStore implements SessionAttributeStore, InitializingBean {
@Inject
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
private static final Logger logger = Logger.getLogger(ConversationalSessionAttributeStore.class);
private int keepAliveConversations = 10;
public final static String CID_FIELD = "_cid";
public final static String SESSION_MAP = "sessionConversationMap";
@Override
public void storeAttribute(WebRequest request, String attributeName, Object attributeValue) {
Assert.notNull(request, "WebRequest must not be null");
Assert.notNull(attributeName, "Attribute name must not be null");
Assert.notNull(attributeValue, "Attribute value must not be null");
String cId = getConversationId(request);
if (cId == null || cId.trim().length() == 0) {
cId = UUID.randomUUID().toString();
}
request.setAttribute(CID_FIELD, cId, WebRequest.SCOPE_REQUEST);
logger.debug("storeAttribute - storing bean reference for (" + attributeName + ").");
store(request, attributeName, attributeValue, cId);
}
@Override
public Object retrieveAttribute(WebRequest request, String attributeName) {
Assert.notNull(request, "WebRequest must not be null");
Assert.notNull(attributeName, "Attribute name must not be null");
if (getConversationId(request) != null) {
if (logger.isDebugEnabled()) {
logger.debug("retrieveAttribute - retrieving bean reference for (" + attributeName + ") for conversation (" + getConversationId(request) + ").");
}
return getConversationStore(request, getConversationId(request)).get(attributeName);
} else {
return null;
}
}
@Override
public void cleanupAttribute(WebRequest request, String attributeName) {
Assert.notNull(request, "WebRequest must not be null");
Assert.notNull(attributeName, "Attribute name must not be null");
if (logger.isDebugEnabled()) {
logger.debug("cleanupAttribute - removing bean reference for (" + attributeName + ") from conversation (" + getConversationId(request) + ").");
}
Map<String, Object> conversationStore = getConversationStore(request, getConversationId(request));
conversationStore.remove(attributeName);
// Delete the conversation store from the session if empty
if (conversationStore.isEmpty()) {
getSessionConversationsMap(request).remove(getConversationId(request));
}
}
/**
* Retrieve a specific conversation's map of objects from the session. Will create the conversation map if it does not exist.
*
* The conversation map is stored inside a session map - which is a map of maps. If this does not exist yet- it will be created too.
*
* @param request
* - the incoming request
* @param conversationId
* - the conversation id we are dealing with
* @return - the conversation's map
*/
private Map<String, Object> getConversationStore(WebRequest request, String conversationId) {
Map<String, Object> conversationMap = getSessionConversationsMap(request).get(conversationId);
if (conversationId != null && conversationMap == null) {
conversationMap = new HashMap<String, Object>();
getSessionConversationsMap(request).put(conversationId, conversationMap);
}
return conversationMap;
}
/**
* Get the session's conversations map.
*
* @param request
* - the request
* @return - LinkedHashMap of all the conversations and their maps
*/
private LinkedHashMap<String, Map<String, Object>> getSessionConversationsMap(WebRequest request) {
@SuppressWarnings("unchecked")
LinkedHashMap<String, Map<String, Object>> sessionMap = (LinkedHashMap<String, Map<String, Object>>) request.getAttribute(SESSION_MAP, WebRequest.SCOPE_SESSION);
if (sessionMap == null) {
sessionMap = new LinkedHashMap<String, Map<String, Object>>();
request.setAttribute(SESSION_MAP, sessionMap, WebRequest.SCOPE_SESSION);
}
return sessionMap;
}
/**
* Store an object on the session. If the configured maximum number of live conversations to keep is reached - clear out the oldest conversation. (If max number is configured as 0 - no removal will happen)
*
* @param request
* - the web request
* @param attributeName
* - the name of the attribute (from @SessionAttributes)
* @param attributeValue
* - the value to store
*/
private void store(WebRequest request, String attributeName, Object attributeValue, String cId) {
LinkedHashMap<String, Map<String, Object>> sessionConversationsMap = getSessionConversationsMap(request);
if (keepAliveConversations > 0 && sessionConversationsMap.size() >= keepAliveConversations && !sessionConversationsMap.containsKey(cId)) {
// clear oldest conversation
String key = sessionConversationsMap.keySet().iterator().next();
sessionConversationsMap.remove(key);
}
getConversationStore(request, cId).put(attributeName, attributeValue);
}
public int getKeepAliveConversations() {
return keepAliveConversations;
}
public void setKeepAliveConversations(int numConversationsToKeep) {
keepAliveConversations = numConversationsToKeep;
}
/**
* Helper method to get conversation id from the web request
*
* @param request
* - Incoming request
* @return - the conversationId (note that this is a request parameter, and only gets there on form submit)
*/
private String getConversationId(WebRequest request) {
String cid = request.getParameter(CID_FIELD);
if (cid == null) {
cid = (String) request.getAttribute(CID_FIELD, WebRequest.SCOPE_REQUEST);
}
return cid;
}
@Override
public void afterPropertiesSet() throws Exception {
requestMappingHandlerAdapter.setSessionAttributeStore(this);
}
public RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {
return requestMappingHandlerAdapter;
}
public void setRequestMappingHandlerAdapter(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {
this.requestMappingHandlerAdapter = requestMappingHandlerAdapter;
}
}
公共类ConversationalSessionAttributeStore实现SessionAttributeStore,初始化Bean{
@注入
私有RequestMappingHandlerAdapter RequestMappingHandlerAdapter;
私有静态最终记录器Logger=Logger.getLogger(ConversationalSessionAttributeStore.class);
私有int keepAliveConversations=10;
公共最终静态字符串CID_字段=“_CID”;
公共最终静态字符串SESSION\u MAP=“sessionConversationMap”;
@凌驾
public void storeAttribute(WebRequest请求、字符串attributeName、对象attributeValue){
Assert.notNull(请求,“WebRequest不能为null”);
Assert.notNull(attributeName,“属性名不能为null”);
Assert.notNull(attributeValue,“属性值不能为null”);
字符串cId=getConversationId(请求);
如果(cId==null | | cId.trim().length()==0){
cId=UUID.randomUUID().toString();
}
setAttribute(CID_字段、CID、WebRequest.SCOPE_请求);
debug(“storeAttribute-为(“+attributeName+”)存储bean引用);
存储(请求、属性名称、属性值、cId);
}
@凌驾
公共对象检索属性(WebRequest请求,字符串属性名){
Assert.notNull(请求,“WebRequest不能为null”);
Assert.notNull(attributeName,“属性名不能为null”);
if(getConversationId(请求)!=null){
if(logger.isDebugEnabled()){
debug(“retrieveAttribute-检索会话(“+getConversationId(request)+”)的(“+attributeName+”)的bean引用);
}
返回getConversationStore(请求,getConversationId(请求)).get(attributeName);
}否则{
返回null;
}
}
@凌驾
公共void cleanupAttribute(WebRequest请求,字符串attributeName){
Assert.notNull(请求,“WebRequest不能为null”);
Assert.notNull(attributeName,“属性名不能为null”);
if(logger.isDebugEnabled()){
debug(“cleanupAttribute-从对话(“+getConversationId(请求)+”)中删除(“+attributeName+”)的bean引用);
}
Map conversationStore=getConversationStore(请求,getConversationId(请求));
会话存储。删除(attributeName);
//如果会话存储为空,请从会话中删除会话存储
if(conversationStore.isEmpty()){
getSessionConversationsMap(请求).remove(getConversationId(请求));
}
}
/**
*从会话中检索特定会话的对象映射。如果会话映射不存在,将创建该会话映射。
*
*会话映射存储在会话映射中,会话映射是映射的映射。如果会话映射还不存在,也将创建会话映射。
*
*@param请求
*-传入的请求
*@param-conversationId
*-我们正在处理的对话id
*@return-对话地图
*/
私有映射getConversationStore(WebRequest请求,字符串conversationId){
Map conversationMap=getSessionConversationsMap(请求).get(会话ID);
if(conversationId!=null&&conversationMap==null){
conversationMap=新HashMap();
getSessionConversationsMap(请求).put(会话ID,会话映射);
}
返回会话图;
}
/**
*获取会话的对话映射。
*
*@param请求
*-请求
*@return-LinkedHashMap所有对话及其地图
*/
私有LinkedHashMap getSessionConversationsMap(WebRequest请求){
@抑制警告(“未选中”)
LinkedHashMap sessionMap=(LinkedHashMap)request.getAttribute(SESSION\u MAP,WebRequest.SCOPE\u SESSION);
if(sessionMap==null){
sessionMap=newlinkedhashmap();
setAttribute(会话映射、会话映射、WebRequest.SCOPE会话);
}
返回sessionMap;
}
/**
*在会话上存储对象。如果已达到所配置的要保留的最大实时会话数,请清除最早的会话。(如果最大会话数配置为0,则不会进行删除)
*
*@param请求
*-网络请求
*@param attributeName
*-属性的名称(来自@SessionAttributes)
*@param attributeValue
*-要存储的值
*/
私有无效存储(WebRequest请求、字符串attributeName、对象attributeValue、字符串cId){
LinkedHashMap sessionConversationsMap=getSessionConversationsMap(请求);
如果(keepAliveConversations>0&&sessionConversationsMap.size()>=keepAliveConversations&&sessionConversationsMap.containsKey(cId)){
//清除最旧的对话
String key=sessionConversationsMap.keySet().iterator().next();
sessionConversationsMap.remove(键);
}
getConversationStore(请求,cId).put(attributeName,attributeValue);
}
public int getKeepAliveConversations(){
返回keepAliveConversations;
}
公共无效设置keepaliveconversations(int numconversationstokep){
keepAliveConversations=numconversationstokep;
}
/**
*用于从web请求获取会话id的帮助器方法
*
*@param请求
*-传入请求
*@return-会话ID(注意