2014-04-13 7 views
7

का आह्वान करें मैं थोड़ा सा बांध रहा हूं ... मेरा केक चाहता हूं और इसे भी खा सकता हूं।जर्सी ... सभी अपवादों को कैसे लॉग इन करें, लेकिन अभी भी अपवाद मैपर

मैं लॉग इन करना चाहता हूं अपवाद मेरे आवेदन को फेंकता है। तो अगर कोई गलत यूआरएल हिट करता है, तो मैं एसएलएफ 4 जे में स्टैक ट्रेस लॉग करना चाहता हूं।

तो आप शायद सोच रहे हैं, 'हे thats आसान, बस एक exceptionmapper को लागू करने और अपवाद लॉग ऑन "तो मैंने किया था:।

public class RestExceptionMapper implements ExceptionMapper<java.lang.Exception> { 
    private static final Logger log = LoggerFactory.getLogger(RestExceptionMapper.class); 

    /** 
    * {@inheritDoc} 
    */ 
    @Override 
    public Response toResponse(Exception exception) { 
     log.error("toResponse() caught exception", exception); 
     return null; 
    } 
} 

आप इस के बजाय 404 त्रुटि जब किसी प्रकार के एक करते हैं गलत यूआरएल में, उन्हें 500 त्रुटि मिलती है। एक अनुमान लगाएगा कि नल लौटने से चेन हैंडलर को अपवाद का प्रचार किया जाएगा, लेकिन जर्सी ऐसा नहीं करता है। यह वास्तव में बहुत कम जानकारी प्रदान करता है कि यह एक दूसरे पर एक हैंडलर क्यों चुनता है ...

क्या कोई इस समस्या में भाग गया है और आपने इसे कैसे हल किया?

+0

मैं CDI इंटरसेप्टर –

+0

तो प्रयोग करेंगे, तुम्हारी समस्या क्या है: यह 404 त्रुटियों है या यह अपवाद मानचित्रकारों चुना जाता है कैसे है? ? या कुछ और? –

+0

नहीं, समस्या यह है कि जर्सी के साथ प्रदान किए गए "स्टॉक" इंटरसेप्टर कैल नहीं हैं अगर आप उपरोक्त कोड का उपयोग करते हैं तो इसका नेतृत्व किया। 404 त्रुटियां 500 त्रुटियां बन गईं। –

उत्तर

6

सही HTTP स्थिति कोड के लिए, अपने अपवाद नक्शाकार कुछ इस तरह दिखाई दे सकता है:

@Provider 
public class RestExceptionMapper implements ExceptionMapper<Throwable> 
{ 
    private static final Logger log = LoggerFactory.getLogger(RestExceptionMapper.class); 

    @Override 
    public Response toResponse(Throwable exception) 
    { 
     log.error("toResponse() caught exception", exception); 

     return Response.status(getStatusCode(exception)) 
       .entity(getEntity(exception)) 
       .build(); 
    } 

    /* 
    * Get appropriate HTTP status code for an exception. 
    */ 
    private int getStatusCode(Throwable exception) 
    { 
     if (exception instanceof WebApplicationException) 
     { 
      return ((WebApplicationException)exception).getResponse().getStatus(); 
     } 

     return Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); 
    } 

    /* 
    * Get response body for an exception. 
    */ 
    private Object getEntity(Throwable exception) 
    { 
     // return stack trace for debugging (probably don't want this in prod...) 
     StringWriter errorMsg = new StringWriter(); 
     exception.printStackTrace(new PrintWriter(errorMsg)); 
     return errorMsg.toString();    
    } 
} 

यह भी लगता है कि आप अपवाद मानचित्रकारों व्यापक में रुचि रखते हैं, लेकिन कल्पना के अनुसार यह संभव नहीं है:

JAX-आरएस 2.0 युक्ति, अध्याय 4.4

"अपवाद मानचित्रण प्रदाताओं प्रतिक्रिया का एक उदाहरण के लिए एक जाँच या क्रम अपवाद मैप करें। एक अपवाद मानचित्रण प्रदाता अपवाद मैपर इंटरफ़ेस लागू करता है और स्वचालित खोज के लिए @ प्रदाता के साथ एनोटेट किया जा सकता है। अपवाद को मैप करने के लिए अपवाद मैपिंग प्रदाता चुनते समय, एक कार्यान्वयन को उस प्रदाता का उपयोग करना चाहिए जिसका सामान्य प्रकार अपवाद का निकटतम सुपरक्लास है।

जब कोई संसाधन वर्ग या प्रदाता विधि अपवाद फेंकता है जिसके लिए अपवाद मैपिंग प्रदाता है, मिलान प्रदाता को प्रतिक्रिया उदाहरण प्राप्त करने के लिए उपयोग किया जाता है। परिणामस्वरूप प्रतिक्रिया संसाधित की जाती है जैसे कि एक वेब संसाधन विधि ने प्रतिक्रिया वापस कर दी है, खंड 3.3.3 देखें। विशेष रूप से, एक मैप की गई रिस्पांस ContainerResponse फिल्टर श्रृंखला अध्याय 6.

में परिभाषित का उपयोग कर एक संभावित अनंत लूप से बचने के लिए संसाधित किया जाना चाहिए, एक भी अपवाद नक्शाकार एक अनुरोध और उसके संगत प्रतिक्रिया की प्रक्रिया के दौरान इस्तेमाल किया जाना चाहिए। जेएक्स-आरएस कार्यान्वयन अपवाद से पहले मैप किए गए प्रतिक्रिया को संसाधित करते समय अपवादों को मानचित्रित करने का प्रयास नहीं करना चाहिए। इसके बजाय, इस अपवाद धारा 3.3.4 में चरण 3 और 4 में वर्णित के रूप संसाधित होना चाहिए। "

19

आप एक RequestEventListener उपयोग कर सकते हैं और किसी भी मौजूदा प्रसंस्करण के साथ हस्तक्षेप किए बिना, एक अपवाद घटना के लिए सुनने के लिए लॉग इन फेंकने योग्य है। नोट । इसका मतलब है कि पहली बार एक ApplicationEventListener जो तब RequestEventListener का एक उदाहरण देता दर्ज की

public class ExceptionLogger implements ApplicationEventListener, RequestEventListener { 

    private static final Logger log = LoggerFactory.getLogger(RequestExceptionLogger.class); 

    @Override 
    public void onEvent(final ApplicationEvent applicationEvent) { 
    } 

    @Override 
    public RequestEventListener onRequest(final RequestEvent requestEvent) { 
     return this; 
    } 

    @Override 
    public void onEvent(RequestEvent paramRequestEvent) { 
     if(paramRequestEvent.getType() == Type.ON_EXCEPTION) { 
      log.error("", paramRequestEvent.getException()); 
     } 
    } 
} 
+0

मुझे लगता है कि यह बेहतर जवाब है क्योंकि ओपी एक विशिष्ट HTTP त्रुटि के अपवाद को मैप करने की कोशिश नहीं कर रहा है, बल्कि इसे लॉग इन करने के लिए। – uldall

+0

"मैं अपने आवेदन को फेंकने वाले सभी अपवादों को लॉग करना चाहता हूं।" यह वास्तव में प्रश्न का उत्तर देता है। –

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