# Tomcat, JSP, UTF-8 und URL-Codierung



## tme (14. Jan 2010)

Hallo,

in unser Programm ist eine Suche integriert. Diese Suche arbeitet mit einzelnen Seiten, welche über ein Menü mit der Seitennummer angesteuert werden, ähnlich der Suche über z.B. Google, also mit "2" bekommt man die Suchergebnisse 11-20 usw.

Die Codierung der URL, die für die Suchseiten benötigt wird, macht eine Routine, die aus den an die erste Suchseite übergebenen Parametern eine URL für die weiteren Seiten aufbaut:


```
String bar = translationResultPage+": ";
        String parameterString = "";
        java.util.Enumeration parameters = request.getParameterNames();
        while(parameters.hasMoreElements())
        {
            String parameter = (String)parameters.nextElement();
            boolean add = true;
            for(int i=0;i<ignoreParameters.length && add;i++)
            {
                if(parameter.indexOf(ignoreParameters[i])>-1) {
                    add = false;
                }
            }
            if(add)
            {
                String[] parametervalues = request.getParameterValues(parameter);
                for(int i=0;i<parametervalues.length;i++)
                {
                    parameterString += "&amp;"+parameter+"="+java.net.URLEncoder.encode(parametervalues[i],"UTF-8");
                }
            }
        }
```

Hiermit wird also eine URL erzeugt, die alle übergebenen Parameter an die Zielseite weitergibt.

Die URL für die zweite Seite der Suche nach "test" sieht also z.B. so aus:


```
... searchresult.jsp?position=10&x=24&searchstring=test&y=7
```

Wir finden hier jedoch unerwarteterweise eine Problematik mit Umlauten. Soweit ich verstanden habe, müssen Umlaute einfach mittels


```
URLEncoder.encode(String,String)
```

kodiert werden. Wir nutzen diese Funktion (wie oben gesehen), und so sieht für den Suchbegriff "Hängemappe" die URL für die zweite Seite so aus:


```
... searchresult.jsp?position=10&x=20&searchstring=h%C3%A4ngemappe&y=4
```

Codiert werden hier die 2 Zeichen, die in UTF8 ein "ä" ergeben. Tests mit einschlägigen Seiten, die URL-Codierung online anbieten, zeigen, dass die Decodierung der URL normal ein "ä" wiedergibt.

Rufen wir jetzt jedoch über den angegebenen Link die zweite Seite des Suchergebnisses auf, so beinhaltet die Variable (String), die den Suchbegriff mittels


```
searchstring = (String)request.getParameter("searchstring");
```

übernimmt, nicht mehr "hängemappe", sondern "hÃ¤ngemappe".

Bei den beiden komischen Zeichen handelt es sich um die beiden Zeichen, die zusammen das "ä" in UTF8 ergeben.

Wir vermuten, dass es sich durch eine Konfigurationsänderung ergeben hat. Die Server, auf denen das Shopsystem läuft, sind kürzlich auf neue Server und eine neue Anbindung umgezogen, wobei die Konfiguration nicht 1 zu 1 übernommen wurde.

Was ich noch hinzufügen kann:

- Die Seite wurde mit UTF-8-Kodierung versehen:


```
<%@ page pageEncoding="UTF-8" %>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
```

- Die Erkennung des lokalen Browsers auf UTF-8 funktioniert.

Hat jemand irgendeine Idee, wie es zu dieser Konstellation kommen kann?

Danke.


----------



## Antoras (14. Jan 2010)

Das gleiche Problem hatte ich vor kurzem auch. Ich hab es gemäß dieser Anleitung behoben: Tomcat/UTF-8 - Tomcat Wiki
Hab dabei die Methode mit dem Filter angewandt.


----------



## tme (19. Jan 2010)

Hallo und vielen Dank für den Vorschlag,

aber so ganz kann ich mich damit noch nicht abfinden. Ich glaube derzeit noch, dass dieses Verhalten entweder auf Unverständnis meinerseits basiert oder als Fehler bereits bekannt sein muß.

Ich habe mal 2 winzige JSPs erzeugt, mit denen das Verhalten trivial nachvollziehbar ist.

Datei 1:

```
<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<jsp:useBean id="shop" scope="session" class="de.branion.br.Shop" >
    <jsp:setProperty name="shop" property="domain" value="<%=new java.net.URL(request.getRequestURL().toString()).getHost()%>" />
</jsp:useBean>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%@page import="java.net.URLEncoder"%><html>
<%
if(request.getParameter("searchstring")!=null) {
  response.sendRedirect(shop.getUnsecureConnection()+"/system/testrun1.jsp?searchstring=" + URLEncoder.encode(request.getParameter("searchstring"), "UTF-8"));
}
%>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<form style="display: inline" action="<%=shop.getUnsecureConnection() + response.encodeURL("system/testrun2.jsp")%>" method="post" id="searchform">
  <table width="100%" border="0" cellspacing="0" cellpadding="0">
    <tr>
      <td valign="middle">
        <div style="width: 125px">
          <input name="searchstring" style="width: 125px" type="text" class="textfeld" maxlength="80" value="<%if (request.getParameter("searchstring") != null) {out.write((String) request.getParameter("searchstring"));}%>" accesskey="s">
        </div>
      </td>
      <td>
        <img border="0" src="imgs/transparent.gif" width="2" alt="">
      </td>
      <td valign="middle" align="right">
        <div>
          <input type="image" src="imgs/transparent.gif" class="buttongo">
        </div>
      </td>
    </tr>
  </table>
</form>

</body>
</html>
```
Datei 2:

```
<%@ page language="java" contentType="text/html; charset=UTF-8"
  pageEncoding="UTF-8"%>
<jsp:useBean id="shop" scope="session" class="de.branion.br.Shop" >
    <jsp:setProperty name="shop" property="domain" value="<%=new java.net.URL(request.getRequestURL().toString()).getHost()%>" />
</jsp:useBean>
<!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>
  <%=request.getParameter("searchstring")%><br>
</body>
</html>
```

Steuert man testrun2.jsp an und gibt im Eingabefeld "test" ein, so wird dieser Parameter auf der URL-Zeile korrekt und literal übergeben. Gibt man dagegen ein "ä" ein, so codiert zwar der Link den Umlaut in die Prozentwerte, Firefox 3.5.7 zeigt jedoch in der URL-Eingabezeile beim Parameter ein "ä" an. Fange ich dies entsprechend mit request.getparameter ab, so resultiert dies in die 2 Zeichen, die ein "ä" in UTF-8 codieren.

Kann jemand dieses Verhalten in eurem Tomcat nachvollziehen? Ist das vielleicht ein Browserproblem?

Danke,

Thomas

Edit: spannend ist in diesem Zusammenhang vielleicht noch, dass es meiner Einschätzung nach mit der URL-Codierung einen Informationsverlust gibt. Die Information, dass diese beiden Zeichen in der URL-Codierung vor der Codierung ein Zeichen waren, ist nicht mehr vorhanden. So kann doch eigentlich die Interpretation, die am Ende die URL auflöst, nicht unterscheiden, ob ich im Quellstring ein "ä" hatte oder die zwei Zeichen tatsächlich Teil des Quellstrings waren.


----------



## tme (20. Jan 2010)

Kurzer Hinweis: Nimmt man die manuelle Codierung nicht mit UTF-8, sondern mit latin1 als Encoding vor, so fällt das Problem weg, weil hier nicht mehr 2 Zeichen, sondern nur 1 Zeichen codiert werden und die Ambiguität nicht mehr anfällt. Wie erwartet interpretiert bzw. liest Java die Parameter dann korrekt ein und wandelt latin1-codierte Umlaute in die UTF-8-Äquivalente um.


----------



## tme (22. Jan 2010)

Wir haben jetzt alle auf der URL-Zeile benötigten Umlautcodierungen in latin1 anstatt UTF-8 vorgenommen, damit umgehen wir das Problem. Wir verstoßen damit zwar gegen die Empfehlungen vom WWW, aber dafür haben wir eine Lösung


----------

