2010-12-17 18 views
23

माहौल में मैं उपयोग कर रहा हूँ (बिलाव 6), पथ के सेगमेंट जाहिरा तौर पर ISO-8859-1 का उपयोग करते समय एक @PathVariable को मैप किया जा रहा डीकोड कर रहे हैं में प्रतिशत दृश्यों।स्प्रिंग/बाकी @PathVariable वर्ण एन्कोडिंग

मुझे पसंद है कि UTF-8 होने के लिए चाहते हैं।

मैं पहले से ही बिलाव कॉन्फ़िगर किया गया (server.xml में URIEncoding विशेषता का उपयोग) UTF-8 उपयोग करने के लिए।

क्या वसंत/बाकी अपने आप डीकोडिंग कर रहे हैं? यदि हां, तो मैं डिफ़ॉल्ट एन्कोडिंग कहां ओवरराइड कर सकता हूं?

अतिरिक्त जानकारी; यहाँ अपने परीक्षण कोड है:

@RequestMapping(value = "/enc/{foo}", method = RequestMethod.GET) 
public HttpEntity<String> enc(@PathVariable("foo") String foo, HttpServletRequest req) 
{ 
    String resp; 

    resp = "  path variable foo: " + foo + "\n" + 
     "  req.getPathInfo(): " + req.getPathInfo() + "\n" + 
     "req.getPathTranslated(): " + req.getPathTranslated() + "\n" + 
     " req.getRequestURI(): " + req.getRequestURI() + "\n" + 
     " req.getContextPath(): " + req.getContextPath() + "\n"; 

    HttpHeaders headers = new HttpHeaders(); 
    headers.setContentType(new MediaType("text", "plain", Charset.forName("UTF-8"))); 
    return new HttpEntity<String>(resp, headers); 
} 

अगर मैं निम्नलिखित यूआरआइ पथ के साथ एक HTTP GET अनुरोध करते हैं: जो है UTF-8 एन्कोडेड

/TEST/enc/£ and € rates 
के तत्कालीन प्रतिशत-एन्कोड रूप

/TEST/enc/%c2%a3%20and%20%e2%82%ac%20rates 

उत्पादन है कि मैं मिलता है:

 path variable foo: £ and ⬠rates 
     req.getPathInfo(): /enc/£ and € rates 
req.getPathTranslated(): C:\Users\jre\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\TEST\enc\£ and € rates 
    req.getRequestURI(): /TEST/enc/%C2%A3%20and%20%E2%82%AC%20rates 
    req.getContextPath(): /TEST 

जो मुझे दिखाता है कि टॉमकैट (URIEncoding विशेषता को सेट करने के बाद) सही चीज करता है (getPathInfo() देखें), लेकिन पथ चर अभी भी आईएसओ -885 9 -1 में डीकोड किया गया है।

और जवाब है:

स्प्रिंग/बाकी जाहिरा तौर पर, अनुरोध एन्कोडिंग है, जो करने के लिए एक बहुत ही अजीब बात है का उपयोग करता है के रूप में इस शरीर, नहीं यूआरआई के बारे में है। आह।

इस जोड़ना:

<filter> 
    <filter-name>CharacterEncodingFilter</filter-name> 
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
    <init-param> 
     <param-name>encoding</param-name> 
     <param-value>UTF-8</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>CharacterEncodingFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

समस्या तय। यह वास्तव में आसान होना चाहिए।

और वास्तव में, यह भी बदतर है:

विधि वास्तव में एक अनुरोध शरीर है, और वह एक UTF-8 में एन्कोड नहीं है, तो अतिरिक्त forceEncoding पैरामीटर की जरूरत है। ऐसा लगता है, लेकिन मुझे चिंता है कि इससे बाद में और समस्याएं पैदा हो जाएंगी।

एक और दृष्टिकोण

इस बीच में, मुझे पता चला है कि यह डिकोडिंग, मेरे को निर्दिष्ट

<property name="urlDecode" value="false"/> 

निष्क्रिय करने के लिए संभव है ... जो मामले प्राप्तकर्ता कर सकते हैं सही काम करने के लिए; लेकिन निश्चित रूप से यह कई अन्य चीजों को कठिन बना देगा।

उत्तर

27

मैं बात यह है कि आप फ़िल्टर जोड़ने की जरूरत है web.xml को

<filter> 
    <filter-name>CharacterEncodingFilter</filter-name> 
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
    <init-param> 
     <param-name>encoding</param-name> 
     <param-value>UTF-8</param-value> 
    </init-param> 
    <init-param> 
     <param-name>forceEncoding</param-name> 
     <param-value>true</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>CharacterEncodingFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
+1

यह सिद्धांत में अच्छा लगता है, लेकिन मदद नहीं करता है। दस्तावेज़ों को देखकर, यदि * शरीर * के लिए एन्कोडिंग लागू करता है, तो यूआरआई नहीं। –

+1

@ जुलिएयन: यह एक सही समाधान है (हालांकि 'बल एन्कोडिंग' आवश्यक नहीं है), वसंत पथ चर को हल करने के लिए अनुरोध एन्कोडिंग का उपयोग करता है, http://static.springsource.org/spring/docs/3.0.x/javadoc-api देखें /org/springframework/web/util/UrlPathHelper.html (और आपको भी पोस्ट पैरामीटर के लिए इस फ़िल्टर की आवश्यकता है)। – axtavt

+1

@axtavt: ओह, जो इस तरह के डिजाइन के साथ आता है? वैसे भी, मैं पुष्टि करने में सक्षम हूं कि मुझे वास्तव में यूटीएफ -8 मिल जाता है जब मैं एक यूटीएफ -8 एन्कोडेड बॉडी, जैसे POST के साथ HTTP अनुरोध भेजता हूं। मैंने विज्ञापन के रूप में काम करने वाले फ़िल्टर को प्राप्त नहीं किया है (मुझे पता है कि कुछ हो रहा है क्योंकि जब मैं कक्षा का नाम तोड़ता हूं तो मुझे क्लास नॉटफाउंड अपवाद प्राप्त होता है)। –

4

पथ चर अभी भी मेरे लिए ISO-8859-1 में डीकोड की, यहां तक ​​कि वर्ण एन्कोडिंग फ़िल्टर के साथ।यहां यह है कि मुझे इसके आसपास जाने के लिए क्या करना है। अगर आपके पास कोई अन्य विचार है तो कृपया मुझे बताएं!

वास्तविक UTF-8 सर्वर पर पात्रों डीकोड देखने के लिए, तुम सिर्फ यह कर और मूल्य पर एक नज़र ले जा सकते हैं (आप अपने नियंत्रक मानकों को जोड़ने के लिए "HttpServletRequest httpServletRequest" की जरूरत है):

String requestURI = httpServletRequest.getRequestURI(); 
String decodedURI = URLDecoder.decode(requestURI, "UTF-8"); 

मैं जो कुछ भी चाहता हूं वह कर सकता हूं (जैसे डीकोडेड यूआरआई से मैन्युअल रूप से पैरामीटर प्राप्त करें), अब मेरे पास सर्वर पर सही डीकोडेड डेटा है।

+3

सुनिश्चित करें कि आपका प्रेषण सर्वलेट का यूआरएल मैपिंग CharacterEncodingFilter से छोटा नहीं है, अन्यथा यह फ़िल्टर को भी हिट नहीं करेगा। – checketts

+0

वह समस्या थी! धन्यवाद! – 11101101b

0

लेकिन क्या यह चूसना नहीं है कि आपको यह काम करने के लिए टॉमकैट कॉन्फ़िगरेशन (URIEncoding) के साथ गड़बड़ करनी है? यदि सर्वलेट एपीआई ने पथ को प्राप्त करने और उनके अपरिवर्तित प्रतिनिधित्व में मापदंडों का अनुरोध करने का एक तरीका प्रदान किया है, तो एप्लिकेशन (या वसंत) पूरी तरह से डीकोडिंग से निपट सकता है। और जाहिर है, HttpServletRequest#getPathInfo और HttpServletRequest#getQueryString यह भी प्रदान करेगा, लेकिन बाद के लिए इसका मतलब यह होगा कि वसंत को क्वेरी स्ट्रिंग को स्वयं पार्स और डीकोड करना होगा और HttpServletRequest#getParameter और दोस्तों पर भरोसा नहीं करना होगा। जाहिर है, वे ऐसा नहीं करते हैं, जिसका अर्थ है कि आपके पास @RequestParam या @PathVariable हमारे अलावा अन्य किसी भी चीज़ को कैप्चर नहीं कर सकता है-एस्सी स्ट्रिंग सुरक्षित रूप से सर्वलेट कंटेनर कॉन्फ़िगरेशन पर निर्भर किए बिना।

2

सर्वर.एक्सएमएल में टॉमकैट पर कनेक्टर को कॉन्फ़िगर करने का प्रयास करें। अपने कनेक्टर टैग में useBodyEncodingForURI="true" या URIEncoding="UTF-8" जोड़ें। उदाहरण के लिए:

<Connector port="8080" protocol="HTTP/1.1" 
      connectionTimeout="20000" 
      useBodyEncodingForURI="true" 
      redirectPort="8443" /> 
संबंधित मुद्दे