2010-04-24 38 views

Trả lời

16

Như đã đề cập bởi muanis, kể từ mùa xuân 3.1, cách tiếp cận tốt nhất là sử dụng RedirectAttributes. Tôi đã thêm i18n vào mẫu được đưa ra trong blog. Vì vậy, đây sẽ là một mẫu hoàn chỉnh.

@RequestMapping("/users") 
@Controller 
public class UsersController { 

      @Autowired 
      private MessageSource messageSource; 

      @RequestMapping(method = RequestMethod.POST, produces = "text/html") 
      public String create(@Valid User user, BindingResult bindingResult, Model uiModel, HttpServletRequest httpServletRequest, Locale locale, RedirectAttributes redirectAttributes) { 
       ... 
       ... 
       redirectAttributes.addFlashAttribute("SUCCESS_MESSAGE", messageSource.getMessage("label_user_saved_successfully", new String[] {user.getUserId()}, locale)); 
       return "redirect:/users/" + encodeUrlPathSegment("" + user.getId(), httpServletRequest); 
      } 
    ... 
    ... 
} 

Thêm thông điệp thích hợp vào gói tin nhắn của bạn, nói messages.properties.

label_user_saved_successfully=Successfully saved user: {0} 

Chỉnh sửa tập tin jspx bạn sử dụng thuộc tính có liên quan

<c:if test="${SUCCESS_MESSAGE != null}"> 
    <div id="status_message">${SUCCESS_MESSAGE}</div> 
</c:if> 
+0

cách giữ ** messageSource ** trong bộ điều khiển? – ManuPK

+0

// Autowire messageSource. Câu trả lời gốc được sửa đổi để phản ánh thay đổi này. @Autowired tin nhắn riêngThông báo nguồnSource; – krishnakumarp

+1

Tôi thường không hiển thị thông báo flash trong bộ điều khiển mà chỉ lưu trữ mã thông báo trong ngữ cảnh flash. Độ phân giải thông điệp i18n'ed sau đó được thực hiện trong khung nhìn hiển thị thông báo flash. –

0

Bạn nên giữ đơn giản và sử dụng mã trạng thái HTTP 1.1 cụ thể. Vì vậy, cho một cuộc gọi thành công, bạn sẽ trả về 200 OK. Và ở phía máy khách nếu bạn muốn hiển thị một thông báo cụ thể cho người dùng khi bộ điều khiển trả về 200, thì bạn sẽ hiển thị nó ở đó.

+0

Nhưng nếu tôi muốn hiển thị thông điệp khác nhau phụ thuộc vào bối cảnh, làm thế nào tôi sẽ biết những gì nhắn sẽ hiển thị nếu tôi chỉ có 200 OK message? – olegflo

+0

Vấn đề là bạn chỉ trả lại 200 khi trạng thái là ok. Nếu một cái gì đó không được tìm thấy trở lại 404, nếu lỗi máy chủ trả về 500, nếu không trả lại 403. –

0

Nếu bạn có nghĩa là trang được tải lại sau một số POST, bạn có thể bao gồm một lá cờ trong chế độ xem của bạn (JSP hoặc vận tốc hoặc bất kỳ thứ gì bạn sử dụng). Ví dụ. một cái gì đó như thế này

<c:if test="${not empty resultMessage}"> 
<spring:message code="${resultMessage}" /> 
</c:if> 

Và gói tin nhắn của bạn phải chứa một thông điệp cho mã đó.

Nếu bạn làm một AJAX POST để gửi một số dữ liệu (ví dụ trang không được nạp lại và bạn cần để hiển thị một message) bạn có thể

1) làm cho bạn JS tập tin năng động (JSP hay Velocity, một lần nữa) và chèn <spring:message> thẻ đó (tôi không thực sự thích tùy chọn này)

hoặc

2) làm theo những lời khuyên từ this link và sử dụng @ResponseBody để trả về một đối tượng trạng thái để JS của bạn. Bên trong đối tượng bạn đánh dấu là @ResponseBody, bạn có thể đặt cả trạng thái và tin nhắn. Ví dụ. sử dụng các gói tin nhắn của bạn như trong this case.

0

Phương tiện hiển thị thông điệp đơn giản nhất trên JSP của bạn là có đối tượng có phạm vi (có thể phiên, có thể yêu cầu) chứa các thông báo mà bạn muốn hiển thị. Ví dụ: bạn có thể làm như sau:

... java stuff ... 
List messages = new ArrayList(); 
messages.add("some message"); 
messages.add("some other message"); 
request.addAttribute("NotableMessages", messages); 
... java stuff ... 

... jsp and JSTL stuff ... 
<c:if test="not empty NotableMessages"> 
<ul> 
<c:forEach items="${NotableMessages}" var="item"> 
<li>${item}</li> 
</c:forEach> 
</ul> 
</c:if> 
... jsp stuff ... 
0

Cùng với mã trạng thái thích hợp, bạn luôn có thể đặt tiêu đề với thông điệp cụ thể bạn muốn. Tất nhiên, điều này thực sự chỉ là một ý tưởng tốt nếu bạn có quyền kiểm soát cách bộ điều khiển sẽ được sử dụng (ví dụ, không có bên thứ ba).

8

Cách tiếp cận đã được chứng minh là sử dụng phạm vi flash đặc biệt cho các tin nhắn sẽ được giữ lại cho đến khi yêu cầu GET tiếp theo.

Tôi thích sử dụng một phiên scoped đối tượng flash:

public interface Flash { 
    void info(String message, Serializable... arguments); 
    void error(String message, Serializable... arguments); 
    Map<String, MessageSourceResolvable> getMessages(); 
    void reset(); 
} 

@Component("flash") 
@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) 
public class FlashImpl implements Flash { 
    ... 
} 

Một MVC chặn đặc biệt sẽ đọc các giá trị flash từ các đối tượng flash và đặt chúng trong phạm vi yêu cầu:

public class FlashInterceptor implements WebRequestInterceptor { 
    @Autowired 
    private Flash flash; 

    @Override 
    public void preHandle(WebRequest request) { 
     final Map<String, ?> messages = flash.getMessages(); 
     request.setAttribute("flash", messages, RequestAttributes.SCOPE_REQUEST); 

     for (Map.Entry<String, ?> entry : messages.entrySet()) { 
      final String key = "flash" + entry.getKey(); 
      request.setAttribute(key, entry.getValue(), RequestAttributes.SCOPE_REQUEST); 
     } 

     flash.reset(); 
    } 

    ... 
} 

Bây giờ trong bộ điều khiển, bạn có thể chỉ cần đặt các thông điệp trong "phạm vi flash":

@Conteroller 
public class ... { 
    @Autowired 
    private Flash flash; 

    @RequestMapping(...) 
    public void doSomething(...) { 
     // do some stuff... 
     flash.info("your.message.key", arg0, arg1, ...); 
    } 
} 

Trong chế độ xem của bạn y ou lặp qua các tin nhắn flash:

<c:forEach var="entry" items="${flash}"> 
    <div class="flash" id="flash-${entry.key}"> 
     <spring:message message="${entry.value}" /> 
    </div> 
</c:forEach> 

Tôi hy vọng điều này sẽ giúp bạn.

+1

Bây giờ, Spring 3.1 cuối cùng là GA tôi quảng bá câu trả lời của krishnakumarp là câu trả lời ưu tiên hơn tôi. –

1

Sau khi đập đầu tôi một lần nữa trong một thời gian, cuối cùng tôi đã làm cho nó hoạt động.

Tôi đang sử dụng spring 3.1 và nó có hỗ trợ cho requestFlashAttributes được chuyển qua các chuyển hướng.

Chìa khóa để giải quyết vấn đề của tôi là thay đổi kiểu trả về thành chuỗi chứ không phải đối tượng ModelAndView.

anh chàng này đã thực hiện một bài tuyệt vời về việc sử dụng thông điệp flash với mùa xuân (http://www.tikalk.com/java/redirectattributes-new-feature-spring-mvc-31)

+0

Liên kết ở trên bị hỏng, liên kết mới là http://www.tikalk.com/redirectattributes-new-feature-spring-mvc-31/ – Stifler

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