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 (SetCharacterEn­codingFilter.ja­va) 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.setLo­cale() a response.setCon­tentType() 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

Článek patří do kategorie: Java

Přidat komentář

Povinné

Povinné, skryté

Security Image Povinné
Opište text z obrázku

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


Kalendář

April 2024
M T W T F S S
« Jan    
1234567
891011121314
15161718192021
22232425262728
2930  

Poslední články

Locations of visitors to this page