ปัญหา
ข้อมูลที่ส่งมายัง Server (Tomcat) จากการกด submit แบบฟอร์มนั้น
หากข้อมูลเข้ารหัสเป็นภาษาไทย หรือภาษาอื่นๆที่ไม่ใช่รหัสแบบ ISO 8859-1 (Latin-1)
จะถูกถอดรหัสผิดพลาด กลายเป็นเครื่องหมาย ?
สาเหตุ
เนื่องจากตามมาตรฐานแล้ว เมื่อ Browser ส่ง Request มายัง Server
จะต้องส่งข้อมูลเกี่ยวกับการเข้ารหัสตัวอักษรมาด้วย ซึ่งจะทำให้ Server รู้ว่าข้อมูลที่ส่งมานั้นจะถอดรหัสออกมาได้อย่างไร
แต่ Browser ในปัจจุบัน เช่น IE ไม่ได้ทำตามมาตรฐานทั้งหมด
ซึ่ง Browser บางตัวไม่ได้ส่งข้อมูลเกี่ยวกับการเข้ารหัสมาให้ Server ดังนั้น
Server จึงไม่รู้ว่าจะถอดรหัสออกมาได้อย่างไร ซึ่งโดยปกติแล้ว Server ก็จะเลือกรหัสใดรหัสหนึ่งเป็นค่า
default
สำหรับ Tomcat จะเลือกใช้รหัสแบบ ISO 8859-1 ซึ่งทำให้รหัสภาษาไทยที่ส่งมายัง
Server ถูกตีความว่าเป็นรหัสแบบ ISO 8859-1 เมื่อถอดรหัสออกมา ภาษาไทยก็กลายเป็น
?
วิธีแก้ไข
-
หากแน่ใจว่าข้อมูลที่ Request มาเป็นรหัสแบบใด เราก็สามารถกำหนดรหัสนั้นไว้ได้ด้วยคำสั่ง
request.setCharacterEncoding(<Java Character Set>);
โดยเขียนคำสั่งนี้ไว้ที่บรรทัดต้นๆก่อนที่จะทำงานกับข้อมูลนั้นๆ แต่วิธีการนี้
จะต้องเขียนคำสั่งนี้ทุกๆหน้าของ Web Application ซึ่งอาจจะไม่สะดวกนัก และหากต้องการเปลี่ยนแปลงรหัสเป็นอย่างอื่น
ก็ต้องตามแก้ไขทุกๆหน้า หรืออาจจะเขียนเป็น including ก็น่าจะพอช่วยได้
- เขียนคำสั่งในข้อ 1 ไว้ในไฟล์หนึ่ง แล้วใช้คำสั่ง include จากทุกๆหน้า
- เพื่อให้สะดวกต่อการทำงาน เราสามารถสร้าง Filter ที่คอยกรอง Request
ที่เข้ามา โดยตรวจสอบว่ามีการกำหนด Character Encoding ไว้แล้วหรือไม่
หากยังไม่กำหนด ก็กำหนดค่าให้ใหม่ได้ วิธีนี้เราจะสามารถกำหนดรหัสที่ต้องการให้กับ
Filter ได้ใน WEB-INF/web.xml ไฟล์ เช่น
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException { if (request.getCharacterEncoding() == null) { request.setCharacterEncoding(encoding);
} chain.doFilter(request, response); }
โดยที่เพิ่มเติม WEB-INF/web.xml ดังนี้
<filter>
<filter-name>Character Encoding Filter</filter-name>
<filter-class>RequestCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Character Encoding Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
ตัวอย่าง
- ตัวอย่างการทดสอบปัญหา
- Source code ของคลาส RequestCharacterEncodingFilter
|