Kódování JSP stránek a fmt tag library
2. March 2007
Věděli jste, že za určitých okolností není možné nastavit JSP stránce běžící v kontajneru Tomcat 4.x kódování podle vašich představ?
Jak správně nastavit kódování
Pro dánského zákazníka jsme dělali webové stránky. Zvolili jsme kódování utf-8. Jak je známo, je pro právně fungující kódování učinit v případě JSP stránek tyto kroky:
Použití filtru
Filtr (SetCharacterEncodingFilter.java) explicitně nastaví kódování uf-8 každému požadavku.
Definice filtru v deployment deskriptoru:
<!-- Filter to set character encoding on each request -->
<filter>
<filter-name>Set Character Encoding</filter-name>
<filter-class>
cz.venturia.provlinser_dk.filter.SetCharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
A nastavení jeho mapování:
<filter-mapping>
<filter-name>Set Character Encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Nastavení přímo v JSP souboru
Základem je, aby skutečné kódování vašich JSP souborů bylo utf-8.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
Z uvedeného kódu jsou nejdůležitější části
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
a
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
(zde navíc správně umístěno před tag <title>
).
Uvedený kód stránky za vás mimochodem automaticky vygeneruje Eclipse
(musíte mít stažený plugin WTP, pak klepnete na
File/New/Other/Web/JSP).
Až do chvíle, kdy jsme nepoužili tag fmt:formatDate kódování fungovalo.
Proč se všechny stránky zobrazují korektně… a zrovna tahle jedna nikoliv. Na navíc má podle hlaviček odpověď kódávání iso-8859–2? Zjistit, že za změnu kódování stránky může tento tag byl úkol asi na hodinu.
Ukažme si jeho použití na stránce:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
Datum: <fmt:formatDate value="${date}" pattern="d.M.yyyy" />
</body>
</html>
V proměnné date
mám uložen objekt typu
java.util.Date
. Při použití fmt:formatDate
se
totiž zavolá response.setLocale()
a
response.setContentType()
a přepíšou se vámi
nastavené hodnoty. Jako parametr setLocale()
se použije
se právě aktuální java.util.Locale
, který je v případě
českého prostředí „cs_CZ“. Dle převodní tabulky se
k tomuto locale váže kódování iso-8859–2.
A právě toto kódování nastaví Tomcat 4.x vaší stránce.
V diskusích na internetu jsem našel jeden hack. Spočívá v editaci catalina.jar:
jar -xvf catalina.jar
edit file org/apache/catalina/util/CharsetMapperDefault.properties
change all encodings to UTF-8
jar -cvf catalina.jar META-INF/MANIFEST.MF org/*
Nepovažuji to ovšem za šťastné řešení. Kdo vám dovolí vrtat se ve zdrojových kódech Tomcatu. Na kterém navíc mohou běžet i aplikace od dalších firem, a jejich funkčnost by naopak tento hack mohl poškodit. I podle selského rozumu to asi nebude uplně best practise.
Informace z článku Tomcat má
problémy s kódováním můj problém také nevyřešili. Petr
Ferschmann zde radí použít -Dfile.encoding=utf-8
do
CATALINA_OPTS
a přídání
URIEncoding=„UTF-8“
do konfigujerace konektoru
v server.xml.
Moje řešení
Moje řešení je až překvapivě jednoduché. Knihovnu fmt vůbec nepoužívat. Je zde totiž výborná alternativa – Jakarta Datetime Library. Tato knihovna má podobné schopnost jako fmt a co je hlavní – nezmění vám svévolně kódování.
Zde alternativa k předchozímu příklady tentokrát za použítí knihovny Jakarta Datetime Library:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="dt" uri="http://jakarta.apache.org/taglibs/datetime-1.0" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
Datum: <dt:format pattern="d.M.yyyy"><c:out value="${date.time}" /></dt:format>
</body>
</html>
Podle informací zjištěných na internetu se de facto ani nejedná o bug. Autoři Tomcatu 4.x pouze vzali výklad specifikace Servlet API 2.3 za špatný konec. Tomcat 5.x (specifikace Servlet API 2.4) již funguje dle požadavků. Když už tady mluvím o Tomcatu – právě byla releasnuta finální verze Tomcatu 6.
Závěřem
- pro formátování data na stránkách doporučuji Jakarta Datetime Library
- v rámci testovacího procesu zkontrolujte, že skutečné kódování stránky je to, které jste nastavili. Já používám HttpWatch plugin do IE.
- pokud máte možnost používejte Tomcat 5.x, kde vše funguje podle představ
- v žádném případě nehackujete
catalina.jar
:)
Zdroje
- http://marc.theaimsgroup.com/?…
- http://bugs.sun.com/…/view_bug.do?…
- Character Sets and Encodings
- Displaying international characters in JSP
- Tomcat a problémy s kódováním
Článek patří do kategorie: Java
Přidat komentář
Povolené HTML značky:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>
Odkazovat na tento článek | Přihlásit se k odběru těchto komentářů přes RSS Feed