2011-07-06 16 views
7

चलो कहते हैं कि मैं एक JSF प्रबंधित बीन में इस कार्रवाई करते हैं:जेएसएफ में एंकर पर रीडायरेक्ट कैसे करें?

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

मेरे view आईडी msg साथ एक एंकर तत्व है।

view.jsf#msg 

या जो कुछ भी मेरे FacesServlet फिल्टर पैटर्न है: मैं यूआरएल इस लंगर (पहुँच मामलों के लिए) की तरह है, चाहते हैं।

return "view#msg?faces-redirect=true"; स्पष्ट रूप से काम नहीं करेगा क्योंकि JSF (कम से कम mojarra) एक दृश्य के रूप में view#msg का मूल्यांकन करने का प्रयास करेगा।

तो मेरा सवाल यह है कि जेएसएफ को अंत में #msg के साथ एक यूआरएल पर रीडायरेक्ट करना है।

उत्तर

10

क्योंकि JSF (mojarra कम से कम) के लिए एक दृश्य

ओह के रूप में view#msg का मूल्यांकन करने की कोशिश करेंगे, कि बुरा है। यह निश्चित रूप से जेएसएफ/मोजाररा लड़कों में एक वृद्धि अनुरोध के लायक है।

आपकी सर्वश्रेष्ठ शर्त 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"); 
} 

(यह सोचते हैं कि FacesServlet*.xhtml पर मैप किया गया है)

वैकल्पिक रूप से, आप सशर्त जे एस का एक टुकड़ा है कि बजाय करता है प्रस्तुत करना सकता है।

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

अच्छा सोचा कि जे एस का टुकड़ा (मैं JAVASERVERFACES-3154 के लिए एक ठीक की वजह से वैसे भी ViewHandler के लिए आवरण बनाने के लिए किया था,)। साथ ही, 'बाहरी कॉन्टेक्स्ट # रीडायरेक्ट()' बहुत काम करता है। एक बार फिर, एक अच्छा जवाब :) – bluefoot

0

आप एक अवैध यूआरएल बनाने की कोशिश - टुकड़ा (#) हमेशा एक यूआरएल के अंतिम भाग है।

return "view?faces-redirect=true#msg" सही यूआरएल होगा।

दुर्भाग्यवश यह खंड डिफ़ॉल्ट NavigationHandler द्वारा कम से कम जेएसएफ 2.2 में छीन लिया गया है।

जबकि BalusC के दो विकल्प भी काम कर रहे हैं, मेरे पास ऑफ़र करने का तीसरा विकल्प है। एक छोटे पैच के साथ NavigationHandler और ViewHandler लपेटें:

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

संबंधित मुद्दे