2010-06-05 17 views
8

Glassfish v3 üzerinde bir JSF 2.0 uygulaması geliştiriyorum ve ViewExpiredException işlemeye çalışıyorum. Ama ne yaparsam yapayım, kendi hata sayfam yerine her zaman bir Glassfish hata raporu alırım. VEE'nin oluşumunu simüle etmek için, aşağıdaki işlevi VEE'yi ateşleyen destek fasulyem içine soktum. Bu işlevi JSF sayfamdan bir commandLink aracılığıyla tetikliyorum. Kodu:JSF: ViewExpiredException yakalanamıyor

@Named 
public class PersonHome { 
    (...) 
    public void throwVEE() { 
    throw new ViewExpiredException(); 
    } 
} 
ilk ben sadece benim web.xml bir hata-sayfa ekleyerek denedim At

:

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

Ama bu işe yaramazsa, ben hata yönlendirildi değilim denedim

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 

sonraki şey ExceptionHandlerFactory ve CustomExceptionHandler olarak des yazmaktı: ama şu içeriğe sahip bir HTTP Durum 500 sayfa gösterir Glassfish errorpage, gösterilen ediyorum JavaServerFaces 2.0 - Complete Reference numaralı belgedir. Bu sınıflar

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

Ve ekledi: Yani ben yüzler-config.xml içine aşağıdaki etiketi takılı fabrika:

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

} 

özel durum işleyicisi:

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

Ama HALA Hata sayfama yönlendirilmedi - Yukarıdaki gibi aynı HTTP 500 hatası alıyorum. Neyi yanlış yapıyorum, uygulamada özel durumun doğru şekilde ele alınmadığı konusunda eksik olan ne olabilir? 'un herhangi biri çok takdir edilmiş!

Tamam

DÜZENLEME i dürüstüm. Aslında, kodum aslında Scala'da yazılmış, ama bu uzun bir hikaye. Her zaman bir Java sorunu olduğunu düşündüm. Bu durumda GERÇEK hata kendi aptallığımdı. (Scala) kodumda, CustomExceptionHandler'da, satırı "i.remove();" ile eklemeyi unuttum. Böylece ViewExpiredException, işlem yaptıktan sonra UnhandledExceptionsQueue içinde kaldı ve "köpürdü". Ve ne zaman havalanırsa, bir ServletException olur.

İkinizi de karıştırdığınız için gerçekten üzgünüm!

+0

* *: Eğer 1 örnekte olduğu gibi bir fasulye içindeki bunu varsayılan olarak, bu bir 'FacesException' sarılmış ve o-ecek edilecek beklenen hata sayfasında bitmez. – BalusC

+0

Teşekkürler. Haklısın, jSF-phase ifadesini son düzenlememden kaldırdım. – ifischer

+0

Son düzenlediğiniz yayın işe yarıyor mu? Düşünceleriniz için ViewExpired hatasında –

cevap

14

Bu sınama durumu bozuk.ViewExpiredException genellikle yalnızca görünümü geri yüklerken (oturumda eksik olduğu için), yanıtı oluştururken veya çekirdeği başlatırken değil, yalnızca atılır. Durumunuzda, bu istisna, çekirdeğin başlatılması sırasında atılır ve bu istisna, ServletException'a sarılmıştır.

gerçek HTTP oturumu sona erdi iken sunucuya bir HTTP POST isteği gönderdiğinizde ViewExpiredException genellikle sadece atılır. Bir webbrowser

  1. aç POST formu ile bir JSF sayfa (h:form varsayılan zaten POST gereğidir), kapatma sunucu ve çünkü (önemli olan iş dizinini temizlemek: Yani güvenilir bu çoğaltmak için iki yol vardır temelde çoğu sunucu, kapatma sırasında diske açık oturumları serileştirecek ve onları başlangıçta sınıflandırmayacaktır), sunucuyu yeniden başlatıp zaten açılmış formu gönderecektir. ViewExpiredException atılacaktır.

  2. 1 dakikaya web.xml yılında <session-timeout> Set ve POST formu ile JSF sayfasını açtıktan sonra 1 dakika boyunca formu gönderin. Bu, ViewExpiredException'u da atar. "HERHANGİ JSF-fazda bir ViewExpiredException atmak CAN Yani"

+0

Teşekkürler BalusC. Ancak bu neden hata sayfasına doğru şekilde yönlendirilmemiş? – gekrish

+2

Bir "ServletException" atıldığı için. – BalusC

2

Uzman değilim. Bunlar sadece vahşi tahminler veya öneriler.

1) ilk yaklaşımda kendisi ile çalışmak gerektiğini 2) Based on this çalışıp çalışmadığını görmek için standart bir HTML sayfaya yönlendirme deneyin, bir JSF PhaseListener yazmayı deneyin ve şimdi RESTORE GÖRÜNÜM Phase.Right aynı istisna , ya INVOKE UYGULAMASI ya da GÜNCELLEME MODEL Aşamasında atıyorsunuz. 3) Bir sysout ile, hata sayfasının yapılandırıldığından emin olun - Servlet Bağlamı'nı kullanarak (Bunu denemedim ama mümkün olmalıdır)

Hatta sorunun ne olabileceğini merak ediyorum !!!

+0

da aynı yönlendirmeyi ayarlamanız gerekiyor! Daha önce FazListen kullanmamıştım, onları tanımak güzeldi. Sadece RESTORE_VIEW-fazında istisnayı atan bir tanesini uyguladık - ve şimdi gerçekten doğru yönlendiriyor! Özel durumumun InvokeUygulama aşamasında atılır. Bu aşamada atılan istisnaların neden doğru şekilde yakalanmadığını merak ediyorum. – ifischer

+0

Hmm hayır, neden işe yaramadı faz değil, ben de RESTORE_VIEW-fazında istisna attığımda Status-500 aldım (bir kez çalıştı, ama artık değil) Daha fazla araştırmak zorunda ... – ifischer