2013-06-13 28 views
5

Vì mục đích đơn giản, các đoạn mã này sẽ được rút ngắn. Mục đích của việc này là lấy tham số GET, thiết lập nó trên phiên làm việc và chuyển hướng trở lại GET với tham số url đã được loại bỏ. Về cơ bản, URI dọn dẹp. Nếu có một cách tốt hơn/đơn giản hơn để làm điều này, tôi sẽ rất vui khi nghe nó.Tại sao SessionAttributes bị xóa khi chuyển hướng GET?

Tôi có một bộ điều khiển được định nghĩa như vậy:

@Controller 
@RequestMapping("/path/page.xhtml") 
@Scope(BeanDefinition.SCOPE_PROTOTYPE) 
@SessionAttributes({ "myParam1", "myParam2" }) 
public class MyController { 

    @RequestMapping(method = RequestMethod.GET, params = { "urlParam2" }) 
    public String handleUriParam(@RequestParam(value = "urlParam2", required = false) 
           final Long urlParam2, 
           final RedirectAttributes redirs) { 
    // at this point, myParam1 is set on the session. 
    // now set the param as a flash attrib with the name of the session variable 
    redirs.addFlashAttribute("myParam2", urlParam2); 
    return "redirect:/path/page.xhtml"; 
    } 

    @RequestMapping(method = RequestMethod.GET, params = {}) 
    public String doGetStuff(ModelMap model) { 
    // do stuff using myParam1 and myParam2. 
    // problem is, myParam2 is on the session, but myParam1 is not! 
    } 

} 

Giống như mã nói, bằng cách nào đó myParam1 đang được un-set khi chuyển hướng xảy ra. Tôi có thể sửa lỗi này bằng cách chuyển một phương thức ModelMap đến phương thức handleUrlParam và thêm theo cách thủ công myParam1 vào thuộc tính flash, nhưng điều đó dường như đánh bại mục đích trong đầu tôi.

Tại sao SessionAttributemyParam1 bị xóa sau khi chuyển hướng?

Có cách nào tốt hơn để lấy tham số khỏi URI và đặt chúng vào phiên không?

CẬP NHẬT

Vì vậy, có vẻ như bất cứ khi nào bạn sử dụng RedirectAttributes ở tất cả, bạn phải chắc chắn rằng bạn đặt bất kỳ SessionAttribute s bạn muốn thực hiện vào chuyển hướng trên FlashAttributes nếu không họ sẽ bị mất. Tôi tưởng tượng điều này xảy ra bởi vì SessionAttribute s được kéo ra khỏi ModelMap (được thay thế bằng FlashAttributes khi được sử dụng). Đây có phải là lỗi trong Mùa xuân hoặc hành vi có chủ ý không? Nếu đó là cố ý, ai đó có thể giải thích tại sao? Tôi nghĩ rằng SessionAttribute s có nghĩa là để ở trên cho đến khi loại bỏ bằng cách hoàn thành phiên đàm thoại.

Similar StackOverflow post here.

Phụ Lục

Trong ánh sáng của câu trả lời chấp nhận cung cấp, tôi vẫn bối rối như thế nào tôi có thể xóa các thông số URI khi đặt chúng vào phiên làm việc của người dùng. Một tùy chọn mà tôi đã xem xét là tạo một trình bao bọc cho các đối tượng bán nguyên thủy (java.lang.Integer, java.lang.String) Tôi đang cố gắng lưu trữ vì chúng sẽ không được đặt trên chuỗi URI, nhưng điều này có vẻ như bị hack tôi. Nếu ai đó có cách tốt hơn để chấp nhận các tham số GET, lưu trữ chúng trên phiên của người dùng và xóa chúng khỏi thanh địa chỉ của người dùng (yêu cầu chuyển hướng), tôi sẽ sẵn sàng sử dụng nó.

+0

Tôi không biết bạn đang làm gì sai, nhưng tôi vừa sao chép cấu hình của bạn và nó hoạt động như mong đợi. Cả hai thuộc tính đều kết thúc trên phiên làm việc (có thể là kỳ lạ đối với phiên thứ hai vì nó được cho là thuộc tính flash). –

+0

Rất tiếc. Tôi về cơ bản đã cho và thiết lập cả hai như là thuộc tính flash và nó hoạt động tốt. Nó đánh bại mục đích của việc sử dụng '@ SessionAttribute', nhưng đối với các yêu cầu' GET' thông thường, nó hoạt động như mong đợi. Cảm ơn vì đã điều tra việc này. – Andy

+0

Một cái gì đó tôi chỉ nghĩ rằng đó là khác nhau từ cấu hình của hầu hết mọi người là việc sử dụng 'BeanDefinition.SCOPE_PROTOTYPE'. Bạn đã sử dụng nó và vẫn nhận được hành vi chính xác? Tôi tò mò nếu việc tạo/sử dụng một đối tượng Controller mới có thể là một phần của vấn đề ở đây. Do những kẻ đánh chặn và cấu trúc bộ điều khiển của chúng tôi, chúng tôi phải sử dụng những vật thể mới mẻ, nhưng đó chỉ là một suy nghĩ về việc liệu nó có thể đổ lỗi cho hành vi kỳ quặc của tôi hay không. – Andy

Trả lời

5

Vì vậy, tôi đã xem xét mã và Internet để tìm hiểu lý do tại sao nó không hoạt động.

Mùa xuân có hai bản đồ mô hình hoàn toàn riêng biệt - một cho bản đồ hiển thị chế độ xem chuẩn và một bản đồ khác khi chuyển hướng được phát hành. Điều này có thể được quan sát thấy trong ModelAndViewContainer.

Hiện tại thuộc tính phiên tồn tại được thực hiện based on the result from mavContainer#getModel(). Đối với các kịch bản chuyển hướng, điều này trả về mô hình chuyển hướng. Do đó bất cứ điều gì bạn đặt trên tiêu chuẩn Model/ModelMap bị mất.

Điều này có ý nghĩa khi nói về các thuộc tính mô hình chuẩn. Mô hình là có chủ yếu để vượt qua các đối tượng để xem. Khi sử dụng chuyển hướng, bạn đang xử lý một tình huống hoàn toàn khác. Bạn muốn chuyển các đối tượng thông qua chuyển hướng HTTP - do đó chuỗi được tách riêng và flash dựa trên mô hình.

Tuy nhiên cảm giác của tôi là họ quên thuộc tính phiên khi designing this feature. Có một số tốt đẹp discussion in Spring's Jira, tuy nhiên không ai trong số họ địa chỉ vấn đề cụ thể này.

Vì vậy, có ... đây có thể là chủ đề cho Jira của Spring. Và nó có thể được phân loại là lỗi vì điều này ngăn cản bất kỳ ai thiết lập thuộc tính mô hình phiên khi sử dụng chuyển hướng. Buộc Spring lưu trữ thuộc tính phiên của bạn qua RedirectAttributes#addFlashAttribute là IMO là lỗi và loại lỗi trên lỗi riêng của mình.

+0

Mặc dù tôi đồng ý với nhận xét của bạn về việc đó là bản hack, tôi vẫn phải xóa thông số URI khỏi thanh địa chỉ của người dùng. Có cách nào ít "hacky" hơn để làm điều này hơn là tôi hiện đang thử không? – Andy

+0

Ngoài ra, cảm ơn bạn đã xem xét điều này. Lời giải thích của bạn rất kỹ lưỡng và có ý nghĩa hoàn hảo. :) – Andy

Các vấn đề liên quan