2013-02-08 61 views
6

मैं जेटी/रीस्टेसी ऐप पर काम कर रहा हूं। अगर मैं अपने आरईएसटी एंडपॉइंट्स में से एक से WebApplicationException(myResponse) फेंकता हूं, तो यह ग्राहक को दी गई प्रतिक्रिया भेजता है।मैं उपयोगकर्ता को स्टैक ट्रेस दिखाए बिना सर्वलेट फ़िल्टर में त्रुटि स्थिति कैसे संभालूं?

एक फिल्टर एक त्रुटि का पता लगाता है, मैं एक ही व्यवहार करना चाहते हैं:

  1. यह कार्यवाही से निष्पादन बंद कर देना चाहिए, और
  2. यह उपयोगकर्ता एक स्पष्ट, JSON- प्रारूपित त्रुटि है कि शामिल नहीं है देना चाहिए एक स्टैक ट्रेस।

जाहिर है, प्रतिक्रिया स्ट्रीम और return आईएनजी doFilter विधि के भीतर से काम करता है। लेकिन यह doFilter द्वारा बुलाए गए अन्य तरीकों के लिए काम नहीं करता है।

किसी भी अपवाद को फेंकने से स्थिति # 1 मिल जाएगी, लेकिन मुझे स्थिति # 2 को पूरा करने के लिए एक सौहार्दपूर्ण तरीका नहीं पता चला है। (आप तल पर मेरे सबसे अच्छे प्रयास देख सकते हैं।)

धारणा के रूप में बताया गया है उसके जवाब में, WebApplicationException एक फिल्टर के संदर्भ में किसी अन्य अपवाद की तरह व्यवहार कर रहे हैं, और इसलिए उपयोगकर्ता एक अच्छा बदसूरत स्टैक ट्रेस दे।

तो, मेरे सवालों का योग करने के लिए:

  • करो serveltt कंटेनर throw new WebApplicationException(Response) के लिए किसी भी बराबर है?
  • और शायद अधिक महत्वपूर्ण बात यह है कि अन्य जावा परियोजनाएं इसे कैसे संभालती हैं?

मैं एक फिल्टर में इस कोड है और यह काम करता है, लेकिन मैं एक और अधिक सुरुचिपूर्ण समाधान है कि स्वचालित रूप से सभी फ़िल्टर पर लागू होती पसंद करेंगे:

public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { 
    try { 
     doFilterOrThrow(request, response, chain); 
    } catch (WebApplicationException e) { 
     Response res = e.getResponse(); 
     ((HttpServletResponse) response).sendError(res.getStatus(), (String) res.getEntity()); 
    } 
} 

उत्तर

7

विशिष्ट हैंडलिंग वेब अनुप्रयोग अपवाद के लिए आप का उल्लेख है केवल एक जेएक्स-आरएस कंटेनर के संदर्भ में परिभाषित किया गया है, जिस तरह से, एक सर्वलेट कंटेनर के समान ही है।

वेब फ़िल्टर को सर्वलेट कंटेनर द्वारा नियंत्रित किया जाता है, जो यह नहीं जानता या देखभाल करता है कि एक जेएक्स-आरएस कंटेनर उसी एप्लिकेशन सर्वर के भीतर मौजूद है। यह वेब एप्लिकेशन अपवादों के बारे में भी नहीं जानता या परवाह नहीं करता है। तो जब आप फ़िल्टर के भीतर से WAE फेंकते हैं तो इसे किसी भी अन्य अपवाद (स्टैक ट्रेस के साथ सर्वर त्रुटि, या एक पूर्व-कॉन्फ़िगर किए गए त्रुटि पृष्ठ के समान ही माना जाता है यदि आप अपने वेब एप्लिकेशन में एक सेट अप करते हैं)।

यह मुझे प्रतीत होता है कि यदि आप क्लाइंट को एक त्रुटि का संकेत दे रहे हैं तो आप सीधे प्रतिक्रिया स्ट्रीम पर लिखकर फ़िल्टर से ऐसा कर सकते हैं। लेकिन यदि आप कुछ मौजूदा जेएक्स-आरएस लॉजिक का लाभ उठाने का प्रयास कर रहे हैं तो एक (रीस्टेसी विशिष्ट) समाधान आपके फ़िल्टर में त्रुटि के रूप में अनुरोध को ध्वजांकित करना होगा, फिर प्रदाता कक्षा का उपयोग करके जेएक्स-आरएस में डब्ल्यूएई उत्पन्न करना होगा। उदाहरण:

@WebFilter(urlPatterns = "*") 
public class ForwardingFilter implements Filter { 

    @Override 
    public void destroy() { 
     return; 
    } 

    @Override 
    public void doFilter(final ServletRequest request, 
      final ServletResponse response, final FilterChain chain) 
      throws IOException, ServletException { 
     // Add an error response to be processed by the JAX-RS container. 
     // This would obviously be based on some condition. 
     request.setAttribute("errorResponse", 
       Response.status(500).entity("Didn't work out!").build()); 
     chain.doFilter(request, response); 
    } 

    @Override 
    public void init(FilterConfig arg0) throws ServletException { 
     return; 
    } 
} 

@Provider 
@ServerInterceptor 
@HeaderDecoratorPrecedence 
@RequestScoped 
public class ForwardingHandlerProvider implements PreProcessInterceptor { 

    @Override 
    public ServerResponse preProcess(final HttpRequest request, 
      final ResourceMethod method) throws Failure, 
      WebApplicationException { 
     final Response errorResponse = (Response) request 
       .getAttribute("errorResponse"); 
     if (errorResponse != null) 
      throw new WebApplicationException(errorResponse); 
     return null; 
    } 
} 

के बाद से प्रदाता JAX-आरएस देश में मौजूद है, वेब अनुप्रयोग अपवाद JAX-आरएस विनिर्देश की धारा 3.3.4 के नियमों के अनुसार संसाधित किया जाता है, और आप ग्राहक पर वांछित प्रतिक्रिया मिल पक्ष।

* संपादित करें: *

लब्बोलुआब यह है, वहाँ कोई मानक जावा ईई निर्धारित रास्ता (वर्तमान में) क्या JAX-रुपये में उपलब्ध है के लिए इसी तरह एक केंद्रीकृत फैशन में सर्वलेट अपवाद को संभालने के लिए है। चूंकि आप जेबॉस/रेस्टेसी का उपयोग कर रहे हैं, इसलिए आप बहुत करीब पहुंचने के लिए जेबॉस Seam Catch लाइब्रेरी का उपयोग कर सकते हैं।

@HandlesExceptions 
public class ExceptionHandler { 
    public void handleServletException(
      final @Handles @WebRequest CaughtException<ServletException> caught, 
      @Context final HttpServletResponse response) { 
     try { 
      response.sendError(500, "An error occured"); 
     } catch (final IOException ioe) { 
      System.err.println("Dumb IO Exception: " + ioe); 
     } 
    } 
} 

ऊपर Seam Catch documentation में वर्णित है, अपवाद संचालक को दिखाता है। ध्यान दें कि लाइब्रेरी अभी भारी प्रवाह में है, इसलिए आप इसे केवल अंतिम उपाय के रूप में उपयोग करना चाहेंगे।

+0

जानकारी के लिए धन्यवाद, मुझे लगता है कि मैं इस मुद्दे को थोड़ा बेहतर समझता हूं। हालांकि, स्पष्टीकरण के लिए: मैं प्रतिक्रिया स्ट्रीम को लिखने के लिए एक तरीका ढूंढ रहा हूं और * बाद के निष्पादन को रोकता हूं *। जिस ऐप पर मैं काम कर रहा हूं उसके पास कई फ़िल्टर हैं और उनमें से कुछ पिछले डेटा से डेटा पर निर्भर करते हैं। मैं सिर्फ 'doFilter()' विधि से 'वापसी' कर सकता था, लेकिन यह तब काम नहीं करता है जब त्रुटि स्थिति किसी अन्य विधि में पता चलती है जो 'doFilter()' कॉल करता है। (कम से कम अतिरिक्त तर्क के बिना नहीं ...) –

+0

यदि आपको तत्काल प्रसंस्करण करना बंद करना है तो आपको मूल रूप से फ़िल्टर में दोहराने की आवश्यकता है, डेटा जो *** *** जेएक्स-आरएस द्वारा वापस किया जाएगा। इसके आस-पास कोई दूसरा रास्ता नहीं है, क्योंकि फ़िल्टर जेएक्स-आरएस कंटेनर में निष्पादित नहीं किए जाते हैं (बल्कि इसके आगे)। एक और विकल्प प्री-प्रोसेस इंटरसेप्टर में आपके फ़िल्टर लॉजिक को कार्यान्वित करना होगा, हालांकि मुझे लगता है कि इंटरमीडिएट फिल्टर और प्रक्रियाएं हैं जिन्हें आप उस बिंदु से पहले छोड़ने की कोशिश कर रहे हैं। – Perception

+0

क्या फिल्टर में शामिल सर्वलेट कंटेनर में होने वाली किसी भी त्रुटि के लिए जेनेरिक त्रुटि हैंडलर सेट अप करने का कोई तरीका है? असल में, मुझे लगता है कि यह मेरी आवश्यकता हो सकती है: http://stackoverflow.com/questions/4207586/error-handler-servlet-how-to-get-exception- क्योंकि –