2009-05-11 5 views
2

Une exigence du produit que nous construisons est que ses points de terminaison d'URL soient sémantiquement significatifs pour les utilisateurs dans leur langue maternelle. Cela signifie que nous avons besoin d'URL codées en UTF-8 pour prendre en charge tous les alphabets sous le soleil. Nous ne souhaitons pas non plus fournir de documentation sur la configuration de l'installation pour chaque serveur d'application et chaque version que nous prenons en charge. Nous aimerions donc pouvoir exécuter ce code en interne. Cela pourrait ne pas être possible, car au moment où la servlet a reçu la requête, elle a été encodée par le serveur App, etc.La configuration de Tomcat 5.5 en UTF-8 code toutes les redirections sendRedirect()?

J'ai réussi à faire fonctionner cette fonction (pour mon premier cas d'utilisation avec ISO-Latin non Caractères ASCII US) en reconstituant les informations de chemin de la demande avec:

String pathInfoEncoded = new String(httpServletRequest.getPathInfo().getBytes(), "UTF-8"); 

puis d'analyser cela. Toutefois, cela ne fonctionne pas après la redirection d'un POST vers un GET en utilisant sendRedirect(). Le chemin de la requête est déjà échappé (donc ö est encodé en% F6) et ma méthode ci-dessus ne fonctionne pas.

Donc, je suppose que ma question est que je vais à ce sujet tout faux? Et si oui, quel est l'antidote à mon ignorance? :)

Mise à jour: trouvé la solution. Le problème est que l'API Servlet a un comportement étrange en ce qui concerne le codage d'URL avant d'envoyer la redirection. Vous devez coder URL (échapper les caractères UTF-8) AVANT d'appeler sendRedirect(). La méthode encodeRedirectURL() ne le fait pas pour vous.

Cette page discute: http://www.whirlycott.com/phil/2005/05/11/building-j2ee-web-applications-with-utf-8-support/

Répondre

4

Un couple de choses à étudier et à expérimenter avec:

  • Jetez un oeil à votre fichier ./conf/server.xml et veiller à ce que le connecteur a le URIEncoding Attribut défini sur "UTF-8".

Par exemple:

<Connector port="8080" 
      protocol="HTTP/1.1" 
      URIEncoding="UTF-8"/> 
  • Utilisez une sorte d'outil basé sur un navigateur (par exemple: TamperData pour FireFox) pour voir ce que votre navigateur envoie au serveur - il peut très bien être échapper Pour toi. Si tel est le cas, vous pouvez utiliser URL.decode() sur le serveur.
  • Au lieu d'utiliser Response.redirect(), définissez manuellement les en-têtes et le code de réponse.

.: par exemple

response.setHeader("Location", myUtf8unencodedUrl); 
response.setStatus(response.SC_MOVED_TEMPORARILY); 

Pas de promesses, mais ce que je voudrais essayer si elle était moi. :)

1

Nous avons la même situation ici, à savoir notre produit et est nécessaire pour afficher des URL significatives à l'utilisateur potentiellement toutes les langues sur la terre. Tous nos outils et techniques prennent en charge UTF-8, donc pas de problème avec ça. Echapper aux caractères UTF-8 fonctionne techniquement, mais IE (7, 8) montre les URL échappées à la recherche alors que Firefox les désapparaît et affiche de bonnes urls, ie '/français/Banane.html' sera affiché dans IE comme '/ fran% C3% A7ais/Banane.html '. GET après POST/rediriger après que les soumissions de formulaire ne fonctionnaient pas du tout, ni envoyer d'URL UTF-8 ni échapper les URLs UTF-8. Nous avons également essayé d'utiliser le codage d'entité numérique de style XML sans succès.

Cependant, nous avons finalement trouvé un moyen de rediriger avec succès après un POST: coder la chaîne UTF-8 par octet en utilisant ISO-8859-1. Aucun d'entre nous ne comprend vraiment comment cela peut fonctionner de toute façon (comment le navigateur peut-il décoder cela, comme le nombre d'octets par caractère utf-8 peut varier et comment le navigateur le sait, il était à l'origine utf-8?), Mais Cela fait.

Voici un servlet simple à essayer cela:


package springapp.web.servlet; 

import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStream; 

import javax.servlet.ServletContext; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.commons.io.IOUtils; 

public class TestServlet extends HttpServlet { 

private static final long serialVersionUID = -1743198460341004958L; 

/* (non-Javadoc) 
    * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 
    */ 
@Override 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException { 

    String url = "çöffte.html"; 
    try { 
     ServletContext context = req.getSession().getServletContext(); 
    // read utf8 encoded russian url 
      if (context.getResource("/WEB-INF/ru_url.txt") != null){ 
      InputStream is = context.getResourceAsStream("/WEB-INF/ru_url.txt"); 
      if (is != null){ 
       url = IOUtils.toString(is, "UTF-8"); 
       System.out.println(String.format("Redirecting to [%s]", url)); 
      } 
      } 
     } 
     catch (FileNotFoundException fNFEx) { 
     fNFEx.printStackTrace(); 
     } 
     catch (IOException ioEx) { 
     ioEx.printStackTrace(); 
     } 

     byte[] utfBytes = url.getBytes("UTF-8"); 
     String result = new String(utfBytes, "ISO-8859-1"); 
     resp.sendRedirect(result); 

     // does not work: 
     //resp.sendRedirect(url); 
     //resp.sendRedirect(Utf8UrlEscaper.escapeUtf8(url)); 
     //resp.sendRedirect(Utf8UrlEscaper.escapeToNumericEntity(url)); 
} 
} 

Pour la copie cible de redirection et coller une URL de langue maternelle par exemple de wikipedia dans un fichier encodé en utf-8 (sans nomenclature!) et enregistrez-le dans le répertoire WEB-INF. Dans notre exemple, nous avons pris une url russe (http://ru.wikipedia.org/wiki/Заглавная_страница) et l'enregistrer dans un fichier nommé 'ru_url.txt'.

Nous avons créé une application SpringMVC simple mappant n'importe quelle URL * .abc à la servlet de test. Maintenant, si vous démarrez l'application et entrez quelque chose comme 'localhost: 8080/springmvctest/a.abc' vous devriez être redirigé vers le site russe wikipedia et le navigateur (IE et Firefox, Safari ou sinon peut-être pas) devrait montrer une belle utf -8 codé, url de russion native.

Questions connexes