2010-06-05 9 views
8

नहीं पकड़ सकता मैं ग्लासफ़िश v3 पर एक जेएसएफ 2.0 एप्लिकेशन विकसित कर रहा हूं और मैं ViewExpiredException को संभालने की कोशिश कर रहा हूं। लेकिन जो कुछ भी मैं करता हूं, मुझे हमेशा अपने स्वयं के त्रुटि पृष्ठ की बजाय ग्लासफ़िश त्रुटि रिपोर्ट प्राप्त होती है।जेएसएफ: ViewExpiredException

वीईई की घटना का अनुकरण करने के लिए, मैंने निम्नलिखित कार्य को मेरे बैकिंग बीन में डाला, जो वीईई को आग लगा देता है। मैं इस जेएसएफ पेज से कमांडलिंक के माध्यम से इस समारोह को ट्रिगर कर रहा हूं। कोड:

@Named 
public class PersonHome { 
    (...) 
    public void throwVEE() { 
    throw new ViewExpiredException(); 
    } 
} 

पहले मैं बस मेरे web.xml को एक त्रुटि पेज जोड़कर इसे करने की कोशिश में:

<error-page> 
    <exception-type>javax.faces.application.ViewExpiredException</exception-type> 
    <location>/error.xhtml</location> 
</error-page> 

लेकिन यह काम नहीं करता, मैं त्रुटि के लिए पुनः निर्देशित नहीं कर रहा हूँ लेकिन मैं कर रहा हूँ पता चला Glassfish errorpage है, जो निम्नलिखित सामग्री के साथ एक HTTP स्थिति 500 ​​पृष्ठ दिखाती है:

description:The server encountered an internal error() that prevented it from fulfilling this request. 
exception: javax.servlet.ServletException: javax.faces.application.ViewExpiredException 
root cause: javax.faces.el.EvaluationException:javax.faces.application.ViewExpiredException 
root cause:javax.faces.application.ViewExpiredException 

अगला बात मैं करने की कोशिश की लिखने के लिए ExceptionHandlerFactory और एक CustomExceptionHandler, के रूप में डेस था जावासेवरफेस 2.0 में पूरा किया गया - पूर्ण संदर्भ। तो मैं चेहरे-config.xml में निम्नलिखित टैग डाला:

<factory> 
    <exception-handler-factory> 
    exceptions.ExceptionHandlerFactory 
    </exception-handler-factory> 
</factory> 

और जोड़ा इन कक्षाओं: कारखाना:

package exceptions; 

import javax.faces.context.ExceptionHandler; 

public class ExceptionHandlerFactory extends javax.faces.context.ExceptionHandlerFactory { 

    private javax.faces.context.ExceptionHandlerFactory parent; 

    public ExceptionHandlerFactory(javax.faces.context.ExceptionHandlerFactory parent) { 
     this.parent = parent; 
    } 

    @Override 
    public ExceptionHandler getExceptionHandler() { 
     ExceptionHandler result = parent.getExceptionHandler(); 
     result = new CustomExceptionHandler(result); 
     return result; 
    } 

} 

कस्टम अपवाद संचालक:

package exceptions; 

import java.util.Iterator; 

import javax.faces.FacesException; 
import javax.faces.application.NavigationHandler; 
import javax.faces.application.ViewExpiredException; 
import javax.faces.context.ExceptionHandler; 
import javax.faces.context.ExceptionHandlerWrapper; 
import javax.faces.context.FacesContext; 
import javax.faces.event.ExceptionQueuedEvent; 
import javax.faces.event.ExceptionQueuedEventContext; 

class CustomExceptionHandler extends ExceptionHandlerWrapper { 

    private ExceptionHandler parent; 

    public CustomExceptionHandler(ExceptionHandler parent) { 
     this.parent = parent; 
    } 

    @Override 
    public ExceptionHandler getWrapped() { 
     return this.parent; 
    } 

    @Override 
    public void handle() throws FacesException { 
     for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) { 
      ExceptionQueuedEvent event = i.next(); 
      System.out.println("Iterating over ExceptionQueuedEvents. Current:" + event.toString()); 
      ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource(); 
      Throwable t = context.getException(); 
      if (t instanceof ViewExpiredException) { 
       ViewExpiredException vee = (ViewExpiredException) t; 
       FacesContext fc = FacesContext.getCurrentInstance(); 

       NavigationHandler nav = 
         fc.getApplication().getNavigationHandler(); 
       try { 
        // Push some useful stuff to the flash scope for 
        // use in the page 
        fc.getExternalContext().getFlash().put("expiredViewId", vee.getViewId()); 

        nav.handleNavigation(fc, null, "/login?faces-redirect=true"); 
        fc.renderResponse(); 

       } finally { 
        i.remove(); 
       } 
      } 
     } 
     // At this point, the queue will not contain any ViewExpiredEvents. 
     // Therefore, let the parent handle them. 
     getWrapped().handle(); 
    } 
} 

लेकिन अभी भी मुझे अपने त्रुटि पृष्ठ पर रीडायरेक्ट नहीं किया गया है - मुझे उपरोक्त की तरह ही HTTP 500 त्रुटि मिल रही है। मैं क्या गलत कर रहा हूं, मेरे कार्यान्वयन में क्या गुम हो सकता है कि अपवाद सही ढंग से संभाला नहीं गया है? कोई भी अत्यधिक सराहना की मदद!

संपादित

ठीक है, मैं ईमानदार हूँ। असल में, मेरा कोड वास्तव में स्कैला में लिखा गया है, लेकिन यह एक लंबी कहानी है। मैंने सोचा कि यह हर समय एक जावा समस्या थी। इस मामले में वास्तविक त्रुटि मेरी खुद की मूर्खता थी। मेरे (स्कैला) कोड में, कस्टमएक्सप्शन हैंडलर में, मैं "i.remove();" के साथ रेखा को जोड़ना भूल गया तो ViewExpiredException इसे संभालने के बाद UnhandledExceptionsQueue में रहा, और यह "बुलबुला हुआ"। और जब यह बुलबुले हो जाता है, तो यह सर्वलेट अपवाद बन जाता है।

मैं आपको दोनों को भ्रमित करने के लिए वास्तव में क्षमा चाहता हूं!

+0

* "तो आप किसी भी JSF चरण में एक ViewExpiredException फेंक कर सकते हैं" *: डिफ़ॉल्ट रूप से, जब आप अपने 1 उदाहरण के रूप में एक सेम के अंदर ऐसा करते हैं, यह एक 'FacesException' में लिपटे किया जाएगा और यह होगा अपेक्षित त्रुटि पृष्ठ में समाप्त नहीं होता है। – BalusC

+0

धन्यवाद। आप सही हैं, मैंने अपने अंतिम संपादन से किसी भी जेएसएफ-चरण-कथन को हटा दिया है। – ifischer

+0

क्या आपकी आखिरी संपादित पोस्ट यह काम कर रही है? मुझे आपके विचारों के लिए ViewExpired त्रुटि के साथ ही –

उत्तर

14

यह टेस्ट केस फर्जी है।ViewExpiredException आमतौर पर केवल दृश्य को पुनर्स्थापित करने के दौरान फेंक दिया जाता है (क्योंकि यह सत्र में गायब है), प्रतिक्रिया को प्रस्तुत करने और न ही बीन को तत्काल करने के दौरान। आपके मामले में यह अपवाद बीन को तुरंत चालू करने के दौरान फेंक दिया जाता है और यह अपवाद ServletException में लपेटा गया है।

वास्तविकViewExpiredException आमतौर पर केवल तभी फेंक दिया जाता है जब आप HTTP सत्र समाप्त होने पर सर्वर को HTTP POST अनुरोध भेजते हैं।

  1. एक webbrowser में खोलें यह POST में के साथ एक JSF पेज (h:form डिफ़ॉल्ट पहले से ही पोस्ट से होता है), बंद सर्वर और (अपने काम निर्देशिका साफ महत्वपूर्ण है, क्योंकि: तो वहाँ मूल रूप से इस मज़बूती से पुन: पेश करने के दो तरीके हैं अधिकांश सर्वर शट डाउन पर डिस्क पर खुले सत्रों को क्रमबद्ध करेंगे और स्टार्टअप पर उन्हें बेअसर कर देंगे), सर्वर को पुनरारंभ करें और पहले से खोले गए फॉर्म को सबमिट करें। एक ViewExpiredException फेंक दिया जाएगा।

  2. 1 मिनट के लिए web.xml में <session-timeout> निर्धारित करें और पोस्ट फार्म के साथ JSF पेज खोलने के बाद 1 मिनट से अधिक फ़ॉर्म सबमिट करें। यह ViewExpiredException भी फेंक देगा।

+0

धन्यवाद BalusC। लेकिन यह त्रुटि पृष्ठ पर सही तरीके से रीडायरेक्ट क्यों नहीं किया जाता है? – gekrish

+2

क्योंकि 'ServletException' फेंक दिया गया है। – BalusC

2

मैं एक विशेषज्ञ नहीं हूं। ये सिर्फ जंगली अनुमान या सुझाव हैं।

1), एक मानक HTML पृष्ठ पर रीडायरेक्ट कि अगर काम करता है 2) Based on this देखने के लिए प्रयास करें यह पहली दृष्टिकोण के साथ ही काम करना चाहिए, एक JSF PhaseListener लिखने का प्रयास करें और अभी पुनर्स्थापित देखें Phase.Right में एक ही अपवाद फेंक , आप या तो INVOKE आवेदन या अद्यतन मॉडल चरण में फेंक रहे हैं। 3) एक sysout द्वारा, सुनिश्चित करें कि त्रुटि पृष्ठ कॉन्फ़िगर किया गया है - सर्वलेट संदर्भ का उपयोग करके (मैंने यह कोशिश नहीं की है लेकिन यह संभव होना चाहिए)

यहां तक ​​कि मुझे उत्सुकता है कि समस्या क्या हो सकती है !!!

+0

पर एक ही पुनर्निर्देशन सेट करने की आवश्यकता है! मैंने पहले कभी फेजलिस्टर्स का इस्तेमाल नहीं किया, उन्हें जानना अच्छा लगा। मैंने अभी एक लागू किया है, जो RESTORE_VIEW-phase में अपवाद फेंकता है - और अब यह वास्तव में सही ढंग से रीडायरेक्ट करता है! मेरा अपवाद InvokeAplication चरण में फेंक दिया गया है। मुझे आश्चर्य है कि इस चरण में फेंकने वाले अपवादों को सही तरीके से कैच नहीं किया जाता है? – ifischer

+0

हम्म नहीं, यह चरण नहीं है कि यह क्यों काम नहीं करता है, मुझे स्थिति -500 भी मिलता है जब मैं RESTORE_VIEW-phase (अपवाद में एक बार काम करता हूं, लेकिन अब और नहीं) में अपवाद फेंकता है ... – ifischer