2009-09-03 33 views
13

Theo hoàn cảnh chính xác nào thì @SessionAttributes bị xóa? Tôi đã phát hiện một số hành vi khó hiểu khi cố gắng sử dụng hai mô hình trong một trang.Khi nào @SessionAttributes trong SpringMVC bị xóa? (Với mẫu mã)

Khi tôi làm một GET theo sau là một POST sử dụng bộ điều khiển này ...

@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"; 
    } 
} 

... object2 bị xóa khỏi mẫu. Nó không còn tồn tại dưới dạng @SessionAttribute và không thể truy cập được trên trang xem của tôi nữa.

Tuy nhiên, nếu chữ ký của phương pháp thứ hai được sửa đổi để này ...

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

... sau đó object2 không được xóa khỏi mô hình và có sẵn trên trang điểm của tôi.

Các javadoc cho @SessionAttributes nói:

... thuộc tính sẽ được gỡ bỏ một lần xử lý chỉ hoàn thành phiên đàm thoại của nó.

Nhưng tôi không thấy cách tôi đã chỉ ra hoàn thành phiên đàm thoại trong ví dụ đầu tiên nhưng không phải trong ví dụ thứ hai.

Có ai có thể giải thích hành vi này hoặc là lỗi không?

+0

Vấn đề này đã được giải quyết trong mùa xuân 3.0RC1. Xem http://jira.springsource.org/browse/SPR-6084 Cảm ơn Juergen! –

Trả lời

14

Bạn chỉ hoàn thành cuộc trò chuyện bằng cách gọi

SessionStatus.setComplete

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

Điều đó nói rằng, tôi không thấy lý do tại sao bạn nên mất một mô hình thuộc tính và không phải là khác.

Các bạn đã thử làm một cái gì đó như:

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

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

Và xem làm thế nào mà so sánh để đặt các thuộc tính trong mô hình bằng tay.

+1

Tôi đã thử đề xuất của bạn - và đáng ngạc nhiên là nó hoạt động! Bây giờ tôi thực sự bối rối. Tại sao có sự khác biệt để thiết lập thuộc tính mô hình theo cách thủ công và thiết lập nó bằng cách sử dụng @ModelAttribute? –

+2

Tôi đã thực hiện một boo-boo. Từ tham chiếu (3.0.0.M3): "Lưu ý: @ModelAttribute phương thức chú thích sẽ được thực hiện trước phương thức xử lý chú giải @RequestMapping đã chọn". Vì vậy, lý do hoạt động là các method object1 và object2 được thực hiện trước cả hai phương thức get và post. Điều này thực sự có thể là những gì bạn muốn, nhưng tôi nghi ngờ không. – ptomli

+0

Có, tôi nhận ra rằng ngay sau khi tôi đăng bình luận của mình. Tôi có thể nâng cao điều này với Spring vì tôi không thấy bất kỳ lời giải thích hợp lý nào về hành vi này. –

1

Bạn có thể loại bỏ đơn ModelAttribute mức phiên như thế này:

Với ModelMap model, HttpSession session và bạn làm:

if (categoryId != null) 
    model.addAttribute("categoryId", categoryId); 
else { 
    model.remove("categoryId"); 
    session.removeAttribute("categoryId"); 
} 
Các vấn đề liên quan