2009-04-27 20 views
57

डिफ़ॉल्ट रूप से में त्रुटि प्रतिसाद सामग्री, बिलाव कुछ HTML सामग्री वापस ग्राहक के लिए अगर यह एक HTTP 404. मुझे पता है कि web.xml के माध्यम से एक <error-page>can be configured इस सामग्री को अनुकूलित करने की तरह कुछ का सामना करना पड़ता भेजता है।अक्षम सभी डिफ़ॉल्ट HTTP बिलाव

हालांकि, मैं टॉमकैट को पर प्रतिक्रिया सामग्री के संदर्भ में कुछ भी नहीं भेजूंगा (मुझे अभी भी स्थिति कोड पसंद है)। क्या इसे आसानी से कॉन्फ़िगर करने का कोई तरीका है?

मैं ए से बचने की कोशिश कर रहा हूं ए) मेरे सर्वलेट से प्रतिक्रिया स्ट्रीम पर स्पष्ट रूप से खाली सामग्री भेज रहा है, और बी) web.xml में HTTP त्रुटि स्थितियों के पूरे समूह के लिए कस्टम त्रुटि पृष्ठों को कॉन्फ़िगर करना।

कुछ पृष्ठभूमि के लिए, मैं एक HTTP एपीआई विकसित कर रहा हूं और अपनी प्रतिक्रिया सामग्री को नियंत्रित कर रहा हूं। तो एक HTTP 500 के लिए, उदाहरण के लिए, मैं त्रुटि जानकारी युक्त प्रतिक्रिया पर कुछ एक्सएमएल सामग्री populating हूँ। HTTP 404 जैसी स्थितियों के लिए, HTTP प्रतिक्रिया स्थिति क्लाइंट के लिए पर्याप्त है, और सामग्री टोमकैट भेजना अनावश्यक है। यदि कोई अलग दृष्टिकोण है, तो मैं इसे सुनने के लिए खुला हूं।

संपादित करें: निरंतर जांच के बाद, मुझे अभी भी समाधान के रास्ते में बहुत कुछ नहीं मिल रहा है। यदि कोई निश्चित रूप से कह सकता है कि यह संभव नहीं है, या सबूत के साथ संसाधन प्रदान करें कि यह काम नहीं करेगा, तो मैं इसे एक उत्तर के रूप में स्वीकार करूंगा और इसके चारों ओर प्रयास करूँगा।

+6

मैं कोड के अर्थ को अधिभारित नहीं कर रहा हूं, क्योंकि मैं उनका इरादा कर रहा हूं। यह एक आरईएसटी एपीआई के लिए है - उदाहरण के तौर पर, अगर कोई मेरी एपीआई में एक निश्चित संसाधन पर एक जीईटी करता है, और मुझे यह नहीं मिला है, तो मैं प्रतिक्रिया स्थिति को 404 पर सेट कर रहा हूं। अगर मेरे पास कुछ प्रकार की अजीब त्रुटि है , मैंने 500 की स्थिति निर्धारित की है और प्रतिक्रिया में कुछ त्रुटि सामग्री प्रदान की है। लेकिन मैं इस सामग्री पर विशेष नियंत्रण चाहता हूं - मैं नहीं चाहता कि टॉमकैट एचटीएमएल या कुछ और लौटाए। अगर सामग्री वापस आनी है, तो मैं चाहता हूं कि मेरा सर्वलेट ऐसा कर रहा हो। –

+4

मैंने यह भी पाया कि सर्वलेट 3 एक कैच के लिए अनुमति देता है-सभी : http://static.springsource.org/spring/docs/3.2.0.BUILD-SNAPSHOT/reference/html/mvc.html# एमवीसी-एन-ग्राहक-सर्वलेट-कंटेनर-त्रुटि-पृष्ठ –

+0

@ErichEichinger - यह उपयोगी जानकारी है, इसे पास करने के लिए धन्यवाद। –

उत्तर

39

यदि आप कोई त्रुटि पृष्ठ दिखाने के लिए टोमकैट नहीं चाहते हैं, तो sendError (...) का उपयोग न करें। इसके बजाय setStatus (...) का उपयोग करें।

उदा। यदि आप एक 405 प्रतिक्रिया देना चाहते हैं, तो आप

response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);  
response.getWriter().println("The method " + request.getMethod() + 
    " is not supported by this service."); 

इसके अलावा अपने सर्वलेट से किसी भी अपवाद नहीं फेंक याद करते हैं। इसके बजाय अपवाद को पकड़ें और फिर, स्थिति को सेट करें अपना स्वयं का कोड बनाएं।

अर्थात

protected void service(HttpServletRequest request, 
     HttpServletResponse response) throws IOException { 
    try { 

    // servlet code here, e.g. super.service(request, response); 

    } catch (Exception e) { 
    // log the error with a timestamp, show the timestamp to the user 
    long now = System.currentTimeMillis(); 
    log("Exception " + now, e); 
    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
    response.getWriter().println("Guru meditation: " + now); 
    } 
} 
निश्चित रूप से

, अगर आप किसी भी सामग्री नहीं करना चाहते, तो बस, लेखक के लिए कुछ भी नहीं लिखते सिर्फ स्थिति सेट।

+0

'println()' के बजाय 'प्रिंट()' का उपयोग करके अतिरिक्त नई लाइन चार का कारण बनता है। यह विशेष रूप से उपयोगी है यदि आप रिक्त स्ट्रिंग भेज रहे हैं, 'सामग्री-लंबाई: 0' – manikanta

+3

के साथ मुझे लगता है कि यह वास्तविक कारण क्यों है क्योंकि यह आउटपुट स्ट्रीम में लिखा गया है। मेरा मानना ​​है कि यदि आप बस स्थिति निर्धारित करते हैं और प्रतिक्रिया में कुछ भी नहीं लिखते हैं, तो टोमकैट 405 के लिए डिफ़ॉल्ट त्रुटि प्रतिक्रिया भेज देगा। –

+0

बस स्थिति कोड सेट करना मानक त्रुटि पृष्ठ को दबाने के लिए पर्याप्त प्रतीत नहीं होता है (कम से कम, मेरे अपने अनुभव पर आधारित नहीं है)। –

2

क्यों एक खाली HTML पृष्ठ के साथ <error-page> तत्व कॉन्फ़िगर नहीं करें?

+1

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

9

जैसा कि हेकी ​​ने कहा, sendError() के बजाय स्थिति निर्धारित करने से टॉमकैट प्रतिक्रिया इकाई/निकाय/पेलोड को छूता नहीं है।

आप केवल प्रतिक्रिया हेडर मेरे मामले में की तरह, किसी भी संस्था के बिना भेजना चाहते हैं,

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
response.setContentLength(0); 

काम कर देता है।Content-Length: 0 के साथ, print() भले ही इस्तेमाल किया, जैसे कोई प्रभाव नहीं पड़ेगा:

HTTP/1.1 401 Unauthorized 
Server: Apache-Coyote/1.1 
Content-Type: text/html;charset=utf-8 
Content-Length: 0 
Date: Wed, 28 Sep 2011 08:59:49 GMT 

आप कुछ त्रुटि संदेश भेजना चाहते हैं, तो संदेश लंबाई के साथ setContentLength() का उपयोग करें:

response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
response.setContentLength(0); 
response.getWriter().print("this string will be ignored due to the above line"); 

ग्राहक की तरह कुछ प्राप्त करता है (शून्य के अलावा) या आप इसे सर्वर पर छोड़ सकते हैं

8

किसी भी त्रुटि निकाय को भेजने से टॉमकैट को रोकने का त्वरित, थोड़ा गंदा, लेकिन आसान तरीका है टोमकैट होस्ट के खिलाफ setErrorReportValveClass को कॉल करना एक कस्टम त्रुटि रिपोर्ट वाल्व जो कुछ भी करने के लिए रिपोर्ट ओवरराइड करता है। अर्थात्:

public class SecureErrorReportValve extends ErrorReportValve { 

@Override 
protected void report(Request request,Response response,Throwable throwable) { 
} 

} 

और के साथ सेट:

((StandardHost) tomcat.getHost()).setErrorReportValveClass(yourErrorValveClassName); 

आप अपने संदेश भेजना चाहते हैं, और सिर्फ लगता है बिलाव चाहिए नहीं इसके साथ गड़बड़ है, तो आप की तर्ज पर कुछ करना चाहते हैं:

@Override 
protected void report(final Request request, final Response response, final Throwable throwable) { 
    String message = response.getMessage(); 
    if (message != null) { 
     try { 
      response.getWriter().print(message); 
      response.finishResponse(); 
     } catch (IOException e) { 
     } 
    } 
} 
+0

पर एक नज़र डालें, यह बहुत अच्छा काम करता है! मुझे हर एक प्रतिक्रिया को लपेटने के बजाय इसे नियंत्रित करने के लिए एक ही जगह रखना पसंद है। अधिक पहलू उन्मुख। – mckamey

+0

वास्तव में एक बेहतर समाधान! धन्यवाद – Poni

+0

कोई अच्छा समाधान नहीं है, आप सर्वलेट spec के खिलाफ जा रहे हैं। –

1

हालांकि यह प्रश्न थोड़ा पुराना है, मैं भी इस समस्या में भाग गया। सबसे पहले, टॉमकैट का व्यवहार बिल्कुल सही है। यह प्रति सर्वलेट स्पेक है। किसी को spec के खिलाफ टोमकैट के व्यवहार को बदलना नहीं चाहिए। जैसा कि हेक्की वेसालेन और एमआरकोडर ने उल्लेख किया है, केवल setStatus और setStatus का उपयोग करें।

किसके लिए यह चिंता कर सकता है, मैंने के दस्तावेज़ों को बेहतर बनाने के लिए टॉमकैट के साथ ticket उठाया है।

+1

क्या आप "बिल्कुल सही" व्यवहार से क्या मतलब समझ सकते हैं? कौन सा व्यवहार, विशेष रूप से? सर्वलेट विनिर्देश से एक लिंक या अंश मदद कर सकता है। मुझे 3.0 विनिर्देशों में कुछ भी नहीं मिला जो प्रतिक्रिया की वास्तविक सामग्री पर विशेष रूप से त्रुटि प्रतिक्रियाओं के लिए आवश्यकताओं को संबोधित करता था। जहां तक ​​[आरएफसी 2616] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) जाता है, किसी भी त्रुटि स्थिति के लिए इकाई सामग्री पर कोई आवश्यकता नहीं होती है। –

+0

हां, ज़ाहिर है। यह आरएफसी के लिए बाध्य नहीं है लेकिन सर्वलेट के लिए खुद ही है। दोनों ''sendError'] (http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse दोनों के लिए ओरेकल के सर्वलेट एपीआई जावाडॉक्स, सर्वलेट spec 3.0, अध्याय 10.9.2 और 10.9.3 देखें। एचटीएमएल # sendError% 28int% 29) विधियों और मेरे प्रश्न [टोमकैट उपयोगकर्ता मेलिंगलिस्ट] (http://www.mail-archive.com/[email protected]/msg102755.html) पर। –

5

हालांकि यह सुरक्षा कारणों से सर्वलेट का अनुपालन करता है, हालांकि मैं टॉमकैट या किसी अन्य सर्वलेट कंटेनर को त्रुटि विवरण भेजने के लिए नहीं चाहता हूं। मैं इसके साथ थोड़ा सा संघर्ष किया। खोज और कोशिश कर के बाद, समाधान के रूप में अभिव्यक्त किया जा सकता:

  1. के रूप में दूसरों उल्लेख किया है, sendError() का उपयोग नहीं करते, setStatus() का उपयोग करने के बजाय तरह
  2. चौखटे उदा वसंत सुरक्षा sendError() हालांकि ...
  3. Filter लिखें
    ए। sendError() से setStatus()
    बी पर कॉल रीडायरेक्ट करता है। कंटेनर को प्रतिक्रिया

A little example servlet filter doing this can be found here को संशोधित करने से रोकने के लिए प्रतिक्रिया को अंत में फ़्लश करता है।

+1

+1 यह इंगित करने के लिए कि ढांचे ने पूर्वनिर्धारित व्यवहार किया है और एक उदाहरण फ़िल्टर प्रदान किया है, जो - जैसा कि मैं [जर्सी] का उपयोग कर रहा हूं (https://jersey.java।नेट /) - मुझे एक [एक विशिष्ट जर्सी संपत्ति] की खोज की गई है (https://jersey.java.net/apidocs/2.5/jersey/org/glassfish/jersey/server/ServerProperties.html#RESPONSE_SET_STATUS_OVER_SEND_ERROR) – watery

28

हालांकि यह प्रश्न पर "कुछ भी नहीं भेजें" कथन, और Clive Evans' answer की लहर पर प्रतिक्रिया नहीं देता है, मुझे पता चला कि टॉमकैट में आप उन्हें बहुत अधिक वर्बोज ग्रंथों को बिना त्रुटि पृष्ठों से दूर कर सकते हैं एक कस्टम ErrorReportValve बनाना।

<Valve className="org.apache.catalina.valves.ErrorReportValve" showReport="false" showServerInfo="false" /> 

Link to official documentation:

आप 2 पैरामीटर "showReport" और अपने "server.xml" पर "showServerInfo" के माध्यम से इस अनुरूपण ErrorReportValve को पूरा कर सकते हैं।

टॉमकैट 7.0.55 पर मेरे लिए काम किया, मेरे लिए टॉमकैट 7.0 पर काम नहीं किया।47 (मुझे लगता है कि निम्न लिंक http://www.mail-archive.com/[email protected]/msg113856.html) पर

+5

टॉमकैट 8 के साथ काम करना उत्कृष्ट समाधान! – eis

+3

टॉमकैट दस्तावेज़ कहते हैं कि तत्व , या सर्वर.xml में तत्वों के भीतर जा सकता है। मेरे लिए वाल्व तत्व के भीतर डालने के लिए काम नहीं किया था, लेकिन इसे अलग-अलग तत्वों के अंदर डाला। दस्तावेज़ों में यह भी कहा गया है कि टॉमकैट तत्व पर किसी भी गैर मेलिंग होस्ट नाम को रूट करता है जो तत्व के डिफ़ॉल्ट विशेषता में सेट है। यह सुनिश्चित करने के लिए कि आपके मेजबान/संदर्भों के बाहर के स्थानों पर यूआरएल को टॉमकैट में संकलित त्रुटि संदेश नहीं दिखाए गए हैं, आपको यह सुनिश्चित करना होगा कि यह आपके डिफ़ॉल्ट को जोड़ा गया है। –

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