2009-07-08 24 views
39

मैं जावा में एक शानदार वेब सेवा पर काम कर रहा हूं। कुछ गलत होने पर मुझे क्लाइंट को त्रुटि संदेश भेजने का एक अच्छा तरीका चाहिए।क्लाइंट को उचित संदेश कैसे भेजें

Javadoc के अनुसार, HttpServletResponse.setStatus(int status, String message) को संदेश पैरामीटर के संदिग्ध अर्थ के कारण हटा दिया गया है। "

क्या प्रतिक्रिया संदेश या "reason phrase" प्रतिक्रिया का कोई पसंदीदा तरीका है? sendError(int, String) विधि यह नहीं करती है।

संपादित करें: स्पष्टीकरण के लिए, मैं HTTP स्थिति रेखा को संशोधित करना चाहता हूं, यानी "HTTP/1.1 404 Not Found", शरीर की सामग्री नहीं। विशेष रूप से, मैं "HTTP/1.1 400 Missing customerNumber parameter" जैसे प्रतिक्रियाएं भेजना चाहता हूं।

+0

क्या डिफ़ॉल्ट कारण वाक्यांश में कुछ गड़बड़ है कि जब आप sendError का उपयोग करते हैं तो आपका सर्वलेट कंटेनर लौटाता है? – laz

+0

इसके साथ विशेष रूप से कुछ भी गलत नहीं है, बस मैं एक और विशिष्ट संदेश भेजना चाहता हूं। –

उत्तर

16

मुझे नहीं लगता कि कोई भी विश्वसनीय क्लाइंट वाक्यांश के कारण को देखने की उम्मीद करेगा कि क्या गलत हुआ; मैंने देखा/उपयोग की जाने वाली सबसे पुरानी सेवाएं मानक स्थिति की जानकारी और प्रतिक्रिया के शरीर में एक विस्तृत संदेश भेज देंगे। sendError(int, String) उस स्थिति के लिए आदर्श है।

+3

कुछ लोगों ने तर्क दिया है कि मुझे कारण वाक्यांश के माध्यम से संदेश भी नहीं भेजना चाहिए, और मुझे लगता है कि मैं आश्वस्त हूं। मैं sendError (int, स्ट्रिंग) का उपयोग नहीं कर सकता, हालांकि, कंटेनर संदेश को उलझाता है। अगर मैं sendError (400, "blah") कहता हूं, प्रतिक्रिया शरीर (कम से कम वेबस्पेयर में) "त्रुटि 400: ब्लाह" है। अच्छा नहीं, खासकर अगर आप एक्सएमएल या कुछ अन्य सख्त प्रारूप वापस करना चाहते हैं। मैं setStatus (int) को कॉल करूंगा और मैन्युअल रूप से शरीर सामग्री लिखूंगा। –

0

यह वास्तव में स्पष्ट नहीं है कि आप क्या करने की कोशिश कर रहे हैं। मेरा पहला विचार sendError था लेकिन आप कहते हैं कि जो भी आप चाहते हैं वह नहीं करता ... क्या आपने "त्रुटि प्रतिक्रिया" का एक सेट बनाने के लिए देखा है, जिसका अर्थ है विशिष्ट xml या JSON सामग्री (या जो भी आप ट्रांसफर भाषा के रूप में उपयोग कर रहे हैं) त्रुटि संदेश या कोड और कोई अन्य उपयोगी जानकारी है?

मैंने कुछ समय पहले स्प्रिंग-एमवीसी आधारित रीस्टफुल सेवाओं के लिए ऐसा कुछ किया था और यह अच्छी तरह से काम करता था, लेकिन आपको क्लाइंट को सामान्य 500 संदेश या कुछ प्राप्त करने के लिए हर अपवाद को पकड़ना और संभालना होगा। वसंत अपवाद रिजॉलर्स ने इसके लिए अच्छा काम किया।

उम्मीद है कि इससे मदद मिलती है ... यदि नहीं, तो आप जो कुछ हासिल करने की कोशिश कर रहे हैं उस पर थोड़ा और स्पष्टता हो सकती है। क्षमा करें अगर मैं घना हो रहा हूं और कुछ स्पष्ट याद कर रहा हूं।

2

मैं आरईएसटी के आसपास 'सर्वोत्तम प्रथाओं' से काफी परिचित नहीं हूं। लेकिन मुझे पता है कि अवधारणा HTTP पर आधारित है और इसे स्वाभाविक रूप से कैसे काम करना चाहिए। तो एक अनुप्रयोग त्रुटि के लिए शरीर के अंदर एक माइम प्रकार और सरल पाठ का उपयोग करने के बारे में, जैसे 'एप्लिकेशन/माईएप-अपवाद' और कुछ 'ब्लै ब्लै'? आप इसके लिए एक क्लाइंट लाइब्रेरी प्रदान कर सकते हैं।

मैं एप्लिकेशन त्रुटियों के लिए HTTP प्रतिक्रिया कोड का उपयोग नहीं करता। क्योंकि मुझे यह जानना अच्छा लगता है कि क्या असफल रहा है: चाहे यह मेरा एप्लिकेशन या मेरा HTTP सर्वर हो।

(मुझे आशा है, मैं कुछ सबसे अच्छा अभ्यास सलाह देखेंगे, भी।)

+3

उस स्थिति में, * 403 निषिद्ध * एक असफल HTTP सर्वर या एक असफल अनुप्रयोग को दर्शाता है? और * 418 के बारे में क्या मैं एक टीपोट * हूं, जैसा कि http://www.ietf.org/rfc/rfc2324.txt में परिभाषित किया गया है? ;-) – Arjan

+0

हे, अच्छा बिंदु। लेकिन मैंने इस समाधान का प्रस्ताव दिया, क्योंकि हेडर सामग्री सीमित है। तो हाँ, मुझे खुद को सही करना है। एप्लिकेशन/सर्वर त्रुटि को इंगित करने के लिए प्रतिक्रिया कोड का उपयोग करना सही है। लेकिन सीमाओं (एन्कोडिंग, लंबाई इत्यादि) के कारण, मैं हेडर के साथ त्रुटि संदेश नहीं भेजूंगा। त्रुटि संदेश भेजने के लिए, मैं एमआईएमई प्रकार और प्रतिक्रिया निकाय का उपयोग करने का प्रस्ताव करता हूं। तो क्लाइंट के लिए त्रुटि संदेश बनाते समय, आपके एप्लिकेशन को किसी भी सीमा के बारे में पता नहीं होना चाहिए। – cafebabe

0

मुझे लगता है कि sendError यह करना चाहिए, लेकिन अपने आवेदन सर्वर में नाकाम रहने के किया जा सकता है ... आईबीएम WebSphere 3.5 मुझे एक पर विफल बहुत समय पहले जबकि टोमकैट संदेश को प्रचारित करेगा; सूर्य मंचों पर JavaServer Pages (JSP) and JSTL - Error page: preserve header "HTTP/1.x 400 My message"? देखें।

अंततः मैं निम्नलिखित तरीके को इस्तेमाल किया है, लेकिन इस JSP विशिष्ट की तरह है, और वास्तव में पुराने हो सकते हैं:

<%@ page isErrorPage="true" %> 
<% 
    // This attribute is NOT set when calling HttpResponse#setStatus and then 
    // explicitely incuding this error page using RequestDispatcher#include() 
    // So: only set by HttpResponse#sendError() 
    Integer origStatus = 
     (Integer)request.getAttribute("javax.servlet.error.status_code"); 
    if(origStatus != null) { 
     String origMessage = 
      (String)request.getAttribute("javax.servlet.error.message"); 
     if(origMessage != null) { 
      response.reset(); 
      response.setContentType("text/html"); 
      // deprecated, but works: 
      response.setStatus(origStatus.intValue(), origMessage); 
      // would yield recursive error: 
      // response.sendError(origStatus, origMessage); 
     } 
    } 
%> 

और अगर आप इंटरनेट एक्सप्लोरर के साथ परीक्षण करने के लिए होती हैं: अक्षम "शो अनुकूल HTTP त्रुटि संदेशों "। (जब इसे अक्षम नहीं किया जाता है, तो आईई में एचटीएमएल सामग्री की कुछ न्यूनतम लंबाई की कुछ अजीब आवश्यकता होती है, जो अगर नहीं मिलेगी, तो आईई को इसके बजाय अपना स्वयं का त्रुटि संदेश दिखाएगा। रजिस्ट्री कुंजी HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\ErrorThresholds माइक्रोसॉफ्ट के Description of Hypertext Transport Protocol Error Messages पर भी देखें।)

8

आपकी स्पष्टीकरण के बाद, मैंने टॉमकैट में यह कोशिश की।

response.sendError(HttpServletResponse.SC_BAD_REQUEST, "message goes here"); 

रिटर्न

HTTP/1.1 400 message goes here 

जवाब में पहली पंक्ति के रूप निष्पादित।

आपके द्वारा उपयोग किए जा रहे सर्वलेट कंटेनर में कोई समस्या होनी चाहिए।

+0

प्रलेखन के अनुसार, sendError केवल सामग्री में संदेश भेजने की गारंटी है। यह स्थिति रेखा के बारे में कुछ भी नहीं कहता है। –

+0

हमम, मुझे किसी भी सामग्री को भेजने की अनुमति नहीं है? मैंने हमेशा सोचा है कि यदि वेब सर्वर भाग इसे आपूर्ति नहीं करता है तो वेब सर्वर भाग कुछ डिफ़ॉल्ट सामग्री उत्पन्न करेगा। आपके द्वारा प्रदान किया गया लिंक इस बात का जिक्र नहीं करता है? – Arjan

17

आप बिलाव उपयोग कर रहे हैं, सेटिंग org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER देखें:

http://tomcat.apache.org/tomcat-5.5-doc/config/systemprops.html

  • यदि यह सही कस्टम HTTP स्थिति संदेश HTTP हेडर के भीतर इस्तेमाल किया जाएगा। उपयोगकर्ताओं को यह सुनिश्चित करना होगा कि ऐसा कोई भी संदेश आईएसओ -885 9 -1 एन्कोडेड है, विशेष रूप से यदि उपयोगकर्ता द्वारा प्रदत्त इनपुट को संभावित XSS भेद्यता को रोकने के लिए संदेश में शामिल किया गया है। यदि निर्दिष्ट नहीं किया गया है तो गलत का डिफ़ॉल्ट मान उपयोग किया जाएगा।

मूल जोखिम पर कुछ विस्तार के लिए इस पेज देखें:

import java.util.Map; 
import java.util.Set; 
import java.util.Map.Entry; 

import org.springframework.beans.factory.InitializingBean; 

public class SystemPropertiesInitializingBean implements InitializingBean { 

    private Map<String, String> systemProperties; 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     if (null == systemProperties || systemProperties.isEmpty()) { 
      return; 
     } 

     final Set<Entry<String, String>> entrySet = systemProperties.entrySet(); 
     for (final Entry<String, String> entry : entrySet) { 

      final String key = entry.getKey(); 
      final String value = entry.getValue(); 

      System.setProperty(key, value); 
     } 

    } 

    public void setSystemProperties(final Map<String, String> systemProperties) { 
     this.systemProperties = systemProperties; 
    } 

} 

और applicationContext में:

http://www.securityfocus.com/archive/1/archive/1/495021/100/0/threaded

+0

आह, जानना अच्छा है! – Arjan

0

वसंत संचालित वेब आवेदन में, बिलाव पर चल रहा सेम निम्न का उपयोग .xml:

<bean class="....SystemPropertiesInitializingBean"> 
    <property name="systemProperties"> 
     <map> 
      <entry key="org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER" value="true"/> 
     </map> 
    </property> 
</bean> 
संबंधित मुद्दे