2009-09-03 22 views
13

¿Bajo qué circunstancias exactas se borran @SessionAttributes? Descubrí un comportamiento confuso al tratar de usar dos modelos en una página.¿Cuándo se eliminan @SessionAttributes en SpringMVC? (Con código de ejemplo)

Cuando hago un GET seguido por un poste usando este controlador ...

@Controller 
@RequestMapping("/myPage*") 
@SessionAttributes(value = {"object1", "object2"}) 
public class MyController { 

    @RequestMapping(method = RequestMethod.GET) 
    public String get(Model model) { 
     model.addAttribute("object1", new Object1()); 
     model.addAttribute("object2", new Object2()); 
     return "myPage"; 
    } 

    @RequestMapping(method = RequestMethod.POST) 
    public String post(@ModelAttribute(value = "object1") Object1 object1) { 
     //do something with object1 
     return "myPage"; 
    } 
} 

... objeto2 se limpia del modelo. Ya no existe como @SessionAttribute y no se puede acceder en mi página de vista.

Sin embargo, si la firma del segundo método se modifica para esto ...

public String post(@ModelAttribute(value = "object1") Object1 object1, 
        @ModelAttribute(value = "object2") Object2 object2) { 

... entonces objeto2 no ser anulado desde el modelo y está disponible en mi página de vista.

el Javadoc para @SessionAttributes dice:

... atributos serán eliminados una vez el controlador indica la finalización de su conversación sesión.

Pero no veo cómo he indicado la finalización de la sesión de conversación en el primer ejemplo, pero no en el segundo ejemplo.

¿Alguien puede explicar este comportamiento o es un error?

+0

Este problema ha sido resuelto en la primavera 3.0RC1. Ver http://jira.springsource.org/browse/SPR-6084 Gracias Juergen! –

Respuesta

14

usted indica la finalización de la conversación llamando

SessionStatus.setComplete

public void post(...., SessionStatus status) { 
    status.setComplete(); 
} 

Dicho esto, no veo por qué debe ser perdiendo un atributo de modelo y no a la inversa.

¿Ha intentado hacer algo como:

@ModelAttribute("object1") 
public Object object1() { return new Object(); } 

@ModelAttribute("object2") 
public Object object2() { return new Object(); } 

Y ver cómo se compara a poner los atributos en el modelo con la mano.

+1

Probé tu sugerencia, ¡y sorprendentemente funciona! Ahora estoy realmente confundido. ¿Por qué hay una diferencia al establecer el atributo de modelo manualmente y configurarlo usando @ModelAttribute? –

+2

Desgraciadamente hice un boo-boo. De la referencia (3.0.0.M3): "Nota: los métodos anotados de @ModelAttribute se ejecutarán antes del método del manejador anotado @RequestMapping". Entonces, la razón por la que funciona es que los métodos object1 y object2 se ejecutan antes que los métodos get y post. Esto realmente puede ser lo que quieres, pero sospecho que no. – ptomli

+0

Sí, me di cuenta de eso justo después de publicar mi comentario. Podría plantear esto con Spring ya que no veo ninguna explicación razonable para este comportamiento. –

1

Puede eliminar sola ModelAttribute nivel de sesión como esto:

Dado ModelMap model, HttpSession session y lo hace:

if (categoryId != null) 
    model.addAttribute("categoryId", categoryId); 
else { 
    model.remove("categoryId"); 
    session.removeAttribute("categoryId"); 
} 
Cuestiones relacionadas