2011-07-06 22 views
7

Hãy nói rằng tôi có hành động này trong JSF Managed Bean:Làm thế nào để chuyển hướng đến một neo trong JSF?

public String doSomething() { 
    FacesContext.getCurrentInstance().getExternalContext().getFlash().put("msg", "Something was done successfully"); 
    return "view?faces-redirect=true"; 
} 

My view có một yếu tố neo với id msg. Tôi muốn url có neo này (đối với các vấn đề trợ năng), như:

view.jsf#msg 

Hoặc bất kỳ mẫu bộ lọc FacesServlet nào của tôi.

return "view#msg?faces-redirect=true"; rõ ràng sẽ không hoạt động vì JSF (ít nhất mojarra) sẽ cố gắng đánh giá view#msg làm chế độ xem.

Vì vậy, câu hỏi của tôi là làm thế nào để làm cho JSF chuyển hướng đến một URL với #msg cuối cùng.

Trả lời

10

vì JSF (cá móm ít nhất) sẽ cố gắng để đánh giá view#msg như một cái nhìn

Ồ, đó là khó chịu. Nó chắc chắn có giá trị một yêu cầu nâng cao tại các chàng trai JSF/Mojarra.

Đặt cược tốt nhất của bạn là gửi chuyển hướng theo cách thủ công với sự trợ giúp của ExternalContext#redirect().

public void doSomething() throws IOException { 
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); 
    ec.getFlash().put("msg", "Something was done successfully"); 
    ec.redirect("view.xhtml#msg"); 
} 

(giả định rằng FacesServlet được ánh xạ trên *.xhtml)

Ngoài ra, bạn có điều kiện có thể làm cho một mảnh JS mà làm thế để thay thế.

<ui:fragment rendered="#{not empty flash.msg}"> 
    <script>window.location.hash = 'msg';</script> 
</ui:fragment> 
+1

Tốt nghĩ rằng mảnh JS. Ngoài ra, 'ExternalContext # redirect()' hoạt động rất nhiều. Một lần nữa, một câu trả lời hay :) – bluefoot

0

Bạn cố tạo URL không hợp lệ - đoạn (#) luôn là phần cuối cùng của URL.

return "view?faces-redirect=true#msg" sẽ là URL chính xác.

Thật không may rằng đoạn bị tước bỏ theo mặc định NavigationHandler, ít nhất là trong JSF 2.2.

Trong khi hai tùy chọn của BalusC cũng đang hoạt động, tôi có tùy chọn thứ ba để cung cấp. Quấn NavigationHandlerViewHandler với một bản vá nhỏ:

public class MyViewHandler extends ViewHandlerWrapper { 

    public static final String REDIRECT_FRAGMENT_ATTRIBUTE = MyViewHandler.class.getSimpleName() + ".redirect.fragment"; 

    // ... Constructor and getter snipped ... 

    public String getRedirectURL(final FacesContext context, final String viewId, final Map<String, List<String>> parameters, final boolean includeViewParams) { 
     final String redirectURL = super.getRedirectURL(context, viewId, removeNulls(parameters), includeViewParams); 
     final Object fragment = context.getAttributes().get(REDIRECT_FRAGMENT_ATTRIBUTE); 
     return fragment == null ? redirectURL : redirectURL + fragment; 
    } 

} 

public class MyNavigationHandler extends ConfigurableNavigationHandlerWrapper { 

    // ... Constructor and getter snipped ... 

    public void handleNavigation(final FacesContext context, final String fromAction, final String outcome) { 
     super.handleNavigation(context, fromAction, 
      storeFragment(context, outcome)); 
    } 

    public void handleNavigation(final FacesContext context, final String fromAction, final String outcome, final String toFlowDocumentId) { 
     super.handleNavigation(context, fromAction, 
      storeFragment(context, outcome), toFlowDocumentId); 
    } 

    private static String storeFragment(final FacesContext context, final String outcome) { 
     if (outcome != null) { 
      final int hash = outcome.lastIndexOf('#'); 
      if (hash >= 0 && hash + 1 < outcome.length() && outcome.charAt(hash + 1) != '{') { 
       context.getAttributes().put(MyViewHandler.REDIRECT_FRAGMENT_ATTRIBUTE, outcome.substring(hash)); 
       return outcome.substring(0, hash); 
      } 
     } 
     return outcome; 
    } 
} 

(tôi đã phải tạo ra các wrapper cho ViewHandler dù sao, vì bản sửa lỗi cho JAVASERVERFACES-3154)

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