2010-03-24 4 views
5

मुझे हाल ही में सर्वलेट द्वारा उत्पन्न वेबसाइटों के एन्कोडिंग के साथ एक समस्या थी, ऐसा हुआ कि अगर टोलेट्स के तहत सर्वलेट तैनात किए गए थे, लेकिन जेटी के तहत नहीं। मैं इसके बारे में अनुसंधान का एक छोटा सा था और निम्नलिखित सर्वलेट को समस्या को सरल बनाया:टोमकैट द्वारा प्रतिक्रिया में कोई एन्कोडिंग सेट क्यों नहीं है? मैं इसके साथ कैसे निपट सकता हूं?

public class TestServlet extends HttpServlet implements Servlet { 
    @Override 
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException { 
     response.setContentType("text/plain"); 
     Writer output = response.getWriter(); 
     output.write("öäüÖÄÜß"); 
     output.flush(); 
     output.close(); 
    } 
} 

अगर मैं घाट के तहत इस तैनाती और इसे करने के लिए ब्राउज़र को निर्देशित, यह उम्मीद परिणाम देता है। डेटा ISO-8859-1 के रूप में दिया जाता है और अगर मैं हेडर में एक बार देख ले, तो जेट्टी रिटर्न:

Content-Type: text/plain; charset=iso-8859-1 

ब्राउज़र इस हैडर से एन्कोडिंग का पता लगाता है। यदि मैं टोमकैट में एक ही सर्वलेट को तैनात करता हूं, तो ब्राउज़र अजीब पात्र दिखाता है। लेकिन टोमकैट आईएसओ -885 9 -1 के रूप में डेटा भी लौटाता है, अंतर यह है कि कोई हेडर इसके बारे में नहीं बताता है। तो ब्राउज़र को एन्कोडिंग का अनुमान लगाना है, और यह गलत हो जाता है।

मेरा सवाल है, क्या यह टोमकैट सही या बग का व्यवहार है? और यदि यह सही है, तो मैं इस समस्या से कैसे बच सकता हूं? निश्चित रूप से, मैं हमेशा सर्वलेट में response.setCharacterEncoding("UTF-8"); जोड़ सकता हूं, लेकिन इसका मतलब है कि मैंने एक निश्चित एन्कोडिंग सेट की है, जिसे ब्राउजर समझ सकता है या नहीं। समस्या अधिक प्रासंगिक है, यदि कोई ब्राउज़र नहीं है लेकिन दूसरी सेवा सर्वलेट तक पहुंचती है। तो मुझे सबसे लचीली तरीके से समस्या से कैसे निपटना चाहिए?

+0

Btw: 'लागू करता Servlet' ज़रूरत से ज़्यादा' HttpServlet' पहले से ही करता है के रूप में है। – BalusC

उत्तर

-1

यदि आप एन्कोडिंग निर्दिष्ट नहीं करते हैं, तो टॉमकैट आपके पात्रों को एन्कोड करने के लिए स्वतंत्र है, हालांकि यह महसूस करता है, और ब्राउजर यह अनुमान लगाने के लिए स्वतंत्र है कि टॉमकैट ने कौन सी एन्कोडिंग की थी। आप सही हैं कि समस्या को हल करने का तरीका response.setCharacterEncoding("UTF-8") है।

आपको इस बात की चिंता नहीं करनी चाहिए कि ब्राउज़र एन्कोडिंग को समझ नहीं पाएगा, क्योंकि पिछले 10 वर्षों में जारी किए गए लगभग सभी ब्राउज़र यूटीएफ -8 का समर्थन करते हैं। यद्यपि यदि आप वास्तव में चिंतित हैं, तो आप उपयोगकर्ता एजेंट द्वारा प्रदान किए गए "स्वीकृति-एन्कोडिंग" हेडर का निरीक्षण कर सकते हैं।

+1

यह सही नहीं है, विनिर्देशन को आईएसओ -885 9 -1 को डिफ़ॉल्ट एन्कोडिंग के रूप में आवश्यक है। –

+0

मुझे टॉमकैट को एन्कोडिंग चुनने में कोई समस्या नहीं है, लेकिन इस तथ्य के साथ एक समस्या है कि टॉमकैट ब्राउज़र को नहीं बताता है जो इसे एन्कोडिंग कर रहा था। और जैसा कि मैंने लिखा है, आधुनिक ब्राउज़र आईएसओ- और यूनिकोड-एन्कोडिंग का समर्थन कर सकते हैं, लेकिन अन्य प्रोग्राम servlets द्वारा प्रदान की जाने वाली सेवाओं तक पहुंच सकते हैं। – Dishayloo

+0

@ टिम: यह कौन सा विनिर्देश होगा? मैं कहूंगा कि इस मामले में शायद यह अप्रासंगिक है। –

4

यदि आप एन्कोडिंग निर्दिष्ट नहीं करते हैं, तो सर्वलेट विनिर्देश के लिए आईएसओ -885 9 -1 की आवश्यकता होती है। हालांकि, AFAIK को कंटेनर को सामग्री प्रकार में एन्कोडिंग सेट करने की आवश्यकता नहीं है, कम से कम नहीं, अगर आप इसे "टेक्स्ट/सादा" पर सेट करते हैं। यह वही कल्पना का कहना है: setContentType को

कॉल वर्ण एन्कोडिंग सेट केवल तभी दी सामग्री प्रकार स्ट्रिंग चारसेट विशेषता के लिए एक मूल्य प्रदान करता है।

दूसरे शब्दों में, आप इस

response.setContentType("text/plain; charset=XXXX") 

बिलाव की तरह सामग्री प्रकार सेट केवल तभी चारसेट स्थापित करने के लिए आवश्यक है। मैंने कोशिश नहीं की है कि यह काम करता है या नहीं।

सामान्य रूप से, मैं हमेशा यूटीएफ -8 में एन्कोडिंग सेट करने की सिफारिश करता हूं (क्योंकि यह कम से कम परेशानी का कारण बनता है, कम से कम ब्राउज़र में) और फिर, पाठ/सादे के लिए, ब्राउज़रों को रोकने के लिए स्पष्ट रूप से एन्कोडिंग को स्थिति दें सिस्टम डिफ़ॉल्ट का उपयोग करने से।

+0

हम्म, जेटी का व्यवहार गलत है? जेटी इस मामले में चीजों को अधिक आसान बनाता है, क्योंकि यह अपेक्षा के अनुसार काम करता है। – Dishayloo

+0

मुझे ऐसा लगता है। या कम से कम मुझे कल्पना में कुछ भी नहीं मिला है जो कहता है कि जेटी को इस मामले में सामग्री प्रकार को संशोधित करना चाहिए। –

0

यहां फ़िल्टर कि मैं UTF-8 एन्कोडिंग मजबूर करने के लिए लिखा था है: जेसी Barnum के जवाब के समर्थन में

public class CharacterEncodingFilter implements Filter { 
private static final Logger log = Logger.getLogger(CharacterEncodingFilter.class.getName()); 

boolean isConnectorConfigured = false; 

public void init(FilterConfig filterConfig) throws ServletException {} 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
    request.setCharacterEncoding("utf-8"); 
    response.setCharacterEncoding("utf-8"); 
    if(! isConnectorConfigured) { 
     isConnectorConfigured = true; 
     try { //I need to do all of this with reflection, because I get NoClassDefErrors otherwise. --jsb 
      Field f = request.getClass().getDeclaredField("request"); //Tomcat wraps the real request in a facade, need to get it 
      f.setAccessible(true); 
      Object req = f.get(request); 
      Object connector = req.getClass().getMethod("getConnector", new Class[0]).invoke(req); //Now get the connector 
      connector.getClass().getMethod("setUseBodyEncodingForURI", new Class[] {boolean.class}).invoke(connector, Boolean.TRUE); 
     } catch(NoSuchFieldException e) { 
      log.log(Level.WARNING, "Servlet container does not seem to be Tomcat, cannot programatically alter character encoding. Do this in the Server.xml <Connector> attribute instead."); 
     } catch(Exception e) { 
      log.log(Level.WARNING, "Could not setUseBodyEncodingForURI to true on connector"); 
     } 
    } 
    chain.doFilter(request, response); 
} 

public void destroy() {} 

}

2

, अपाचे विकी पता चलता है कि एक फिल्टर चरित्र को नियंत्रित करने के लिए किया जा सकता अनुरोध और प्रतिक्रिया का एन्कोडिंग। हालांकि, टोमकैट 5।5 और बाद वाले वर्शन SetCharacterEncodingFilter के साथ बंडल किया गया है, इसलिए जेसी (कोई अपराध जेसी) का उपयोग करने के बजाय अपाचे के कार्यान्वयन का उपयोग करना बेहतर हो सकता है। टॉमकैट कार्यान्वयन केवल अनुरोध पर वर्ण एन्कोडिंग सेट करते हैं, इसलिए फ़िल्टर को सभी सर्वलेटों की प्रतिक्रिया पर सेट सेट सेट करने के साधन के रूप में उपयोग करने के लिए संशोधन आवश्यक हो सकता है।

विशेष रूप से, बिलाव कार्यान्वयन यहाँ उदाहरण है:

5.x

webapps/सर्वलेट-उदाहरण/वेब-INF/वर्गों/फिल्टर/SetCharacterEncodingFilter.java

webapps/jsp- उदाहरण/वेब-INF/वर्गों/फिल्टर/SetCharacterEncodingFilter.java

6.x

webapps/उदाहरण/वेब-INF/वर्गों/फिल्टर/SetCharacterEncodingFilter.java

7.x

7.0.20 के बाद से फिल्टर प्रथम श्रेणी के नागरिक बन गए और कोर बिलाव में उदाहरण से ले जाया गया था और उपलब्ध है किसी भी वेब एप्लिकेशन को संकलित करने और इसे अलग-अलग बंडल करने की आवश्यकता के बिना। टॉमकैट द्वारा प्रदान किए गए फ़िल्टर की सूची के लिए प्रलेखन देखें। वर्ग नाम है: org.apache.catalina.filters.SetCharacterEncodingFilter

यह पृष्ठ अधिक बताता है: http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q3

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