2013-07-01 1 views
0

вот код, который может воспроизвести этот вопрос:Spring Жизненный цикл выпуска: аннотацию @SessionAttributes делает атрибуты сеанса живут дольше, чем на самой сессии

@Controller 
public class FirstController { 
    @RequestMapping(value = "firstpage", method = GET) 
    public String myHander(HttpSession httpSession) { 
     if (httpSession.getAttribute("someClass") == null) { 
      httpSession.setAttribute("someClass", new SomeClass()); 
     } 
     return "firstpage"; 
    } 
} 

первый контроллер помещает что-то в сессии, если он еще не существует ,

@Controller 
@SessionAttributes(types = SomeClass.class) 
public class SecondController { 

    @RequestMapping(value = "secondpage", method = GET) 
    public String myHandler(SomeClass someClass, HttpSession httpSession) { 
     //asking spring for the SomeClass parameter, that's why we put it in the annotation. 
     System.out.print(someClass.hashCode()); 

     httpSession.invalidate(); 

     return "secondpage"; 
    } 
} 

Второй контролер убивает сессию.

и в обоих файлах JSP, у меня есть следующий код, который печатает хэш-код объекта сеанса и хэш-код атрибута сеанса:

session hash: 
<%= session.hashCode() %> 
<br/> 
someclass hash: 
<%= session.getAttribute("someClass").hashCode() %> 

теперь, если я запустить приложение и посетить «Firstpage», я получу это:

сессии хэш: 1838367636

SomeClass хэш: 1075505853

, а затем я посетить "SecondPage", и получите это:

сессии Хэш: 842656294

SomeClass хэш: 1075505853

мы можем увидеть, что сама сессия изменяется , потому что второй контроллер убивает сеанс. но атрибут сеанса (типа SomeClass) остается неизменным.

тогда, если я попытаюсь пересмотреть «вторую страницу», объект сеанса будет меняться каждый раз, но атрибут сеанса останется прежним.

Почему атрибут сеанса (который должен быть присоединен к сеансу) имеет более длительный жизненный цикл, чем сам сеанс?

PS: полный код здесь: https://github.com/cuipengfei/One-hundred-thousand-why/tree/master/20130701SessionAttributesLifeCycle/SpringMVC

вы можете запустить его с МВН причалу: работать, чтобы воспроизвести проблему.

ответ

1

documentation для этой аннотации не особо ясно, но я понимаю, что он используется для обмена значениями между методами в том же контроллере. Как я прочитал следующее:

Это, как правило, список имен атрибутов модели или типов атрибутов модели, которые должны быть прозрачно хранить в сессии или какое-разговорном хранении, выступающий в качестве форм-бэку фасоли между последующими запросами

Я интерпретирую это как означающее, что каждый вызов метода контроллера будет завернут вызовом (1) загрузить атрибуты сеанса перед входом и (2) сохранить их при выходе. Который будет иметь поведение, которое вы видите.

Это армированный (IMO) следующий в Javadoc аннотации в:

Для постоянных атрибутов сеанса, например, объект аутентификации пользователя, использовать традиционный метод session.setAttribute вместо

Если они говорят вам использовать стандартные функции для изменения сеанса, он указывает мне, что аннотация не просто способ доступа элементов в сеансе.

И для конечной точки данных: если эта аннотация была способ управления данными сеанса, почему есть бонусы с сессией?