2009-09-02 7 views
7

Ho un tale collegamento a pagina JSP con la codifica Big5 http://hello/world?name=婀ㄉ E quando sono entrata nella barra degli indirizzi del browser, verrà cambiata in qualcosa di simile http://hello/world?name=%23%24%23 E quando vogliamo ottenere questo parametro nella pagina JSP, tutte le i personaggi sono corrottiPerché il carattere è corrotto quando si usa request.getParameter() in java?

E abbiamo impostato questo: request.setCharacterEncoding ("UTF-8"), quindi tutte le richieste verranno convertite in UTF8.

Ma perché in questo caso, non funziona? Grazie in anticipo !.

+0

Qual è l'URL effettivo? –

risposta

14

Quando si immette l'URL nella barra degli indirizzi del browser, il browser può convertire la codifica dei caratteri prima della codifica dell'URL. Tuttavia, questo comportamento non è ben definito, vedere la mia domanda,

Handling Character Encoding in URI on Tomcat

Il più delle volte otteniamo UTF-8 e latino-1 nei browser più recenti, ma arriviamo tutti i tipi di codifiche (tra cui Big5) in quelli vecchi. Quindi è meglio evitare caratteri non ASCII nell'URL inserito direttamente dall'utente.

Se l'URL è incorporato in JSP, è possibile forzare in UTF-8, generando in questo modo,

String link = "http://hello/world?name=" + URLEncoder.encode(name, "UTF-8"); 

Su Tomcat, la codifica deve essere specificata sul connettore come questo,

<Connector port="8080" URIEncoding="UTF-8"/> 

È inoltre necessario utilizzare request.setCharacterEncoding("UTF-8") per la codifica del corpo, ma non è sicuro impostarlo in servlet perché funziona solo quando il parametro non viene elaborato ma altri filtri o valvole potrebbero attivare l'elaborazione. Quindi dovresti farlo in un filtro. Tomcat viene fornito con un filtro di questo tipo nella distribuzione di origine.

6

Non è possibile avere caratteri non ASCII in un URL: è sempre necessario codificarli per percentuale. Nel fare ciò, i browser hanno difficoltà a renderli. Il rendering funziona meglio se codifichi l'URL in UTF-8 e quindi lo codifichi per cento. Per il tuo URL specifico, ciò darebbe http://hello/world?name=%E5%A9%80%E3%84%89 (controlla il browser che cosa fornisce per questo link specifico). Quando si ottiene il parametro in JSP, è necessario annullarlo esplicitamente e quindi decodificarlo da UTF-8, poiché il browser lo invierà così com'è.

+1

Ma come posso codificarlo? Cambiarlo da Non-ASCII a Percent-encode? Quale funzione dovrei usare in java? – MemoryLeak

8

Per evitare giocherellare con l'server.xml uso:

protected static final String CHARSET_FOR_URL_ENCODING = "UTF-8"; 

protected String encodeString(String baseLink, String parameter) 
     throws UnsupportedEncodingException { 
    return String.format(baseLink + "%s", 
      URLEncoder.encode(parameter, CHARSET_FOR_URL_ENCODING)); 
} 
// Used in the servlet code to generate GET requests 
response.sendRedirect(encodeString("userlist?name=", name)); 

per ottenere effettivamente quei parametri su Tomcat you need to do something like: (?)

final String name = 
     new String(request.getParameter("name").getBytes("iso-8859-1"), "UTF-8"); 

come apparentemente request.getParameter URLDecodes() la corda e lo interpreta come iso-8859-1 - o qualunque sia il URIEncoding impostato su server.xml. Per un esempio su come ottenere il set di caratteri URIEncoding da server.xml per Tomcat 7 vedere here

+0

come cambiare la codifica predefinita per 'getParameter'? – orezvani

+0

@emab: dal 'server.xml' come dettagliato nelle altre risposte –

0

Ho avuto un problema con JBoss 7.0, e penso che questa soluzione filtro funziona anche con Tomcat:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 

    HttpServletRequest httpRequest = (HttpServletRequest) request; 
    HttpServletResponse httpResponse = (HttpServletResponse) response; 

    try { 
     httpRequest.setCharacterEncoding(MyAppConfig.getAppSetting("System.Character.Encoding")); 

     String appServer = MyAppConfig.getAppSetting("System.AppServer"); 
     if(appServer.equalsIgnoreCase("JBOSS7")) { 
      Field requestField = httpRequest.getClass().getDeclaredField("request"); 
      requestField.setAccessible(true); 
      Object requestValue = requestField.get(httpRequest); 

      Field coyoteRequestField = requestValue.getClass().getDeclaredField("coyoteRequest"); 
      coyoteRequestField.setAccessible(true); 
      Object coyoteRequestValue = coyoteRequestField.get(requestValue); 

      Method getParameters = coyoteRequestValue.getClass().getMethod("getParameters"); 
      Object parameters = getParameters.invoke(coyoteRequestValue); 

      Method setQueryStringEncoding = parameters.getClass().getMethod("setQueryStringEncoding", String.class); 
      setQueryStringEncoding.invoke(parameters, MyAppConfig.getAppSetting("System.Character.Encoding")); 

      Method setEncoding = parameters.getClass().getMethod("setEncoding", String.class); 
      setEncoding.invoke(parameters, MyAppConfig.getAppSetting("System.Character.Encoding")); 
     } 

    } catch (NoSuchMethodException nsme) { 
     System.err.println(nsme.getLocalizedMessage()); 
     nsme.printStackTrace(); 
     MyLogger.logException(nsme); 
    } catch (InvocationTargetException ite) { 
     System.err.println(ite.getLocalizedMessage()); 
     ite.printStackTrace(); 
     MyLogger.logException(ite); 
    } catch (IllegalAccessException iae) { 
     System.err.println(iae.getLocalizedMessage()); 
     iae.printStackTrace(); 
     MyLogger.logException(iae); 

    } catch(Exception e) { 
     TALogger.logException(e); 
    } 

    try { 
     httpResponse.setCharacterEncoding(MyAppConfig.getAppSetting("System.Character.Encoding")); 
    } catch(Exception e) { 
     MyLogger.logException(e); 
    } 
} 
+0

Se si è verificato un problema simile, si prega di fare una nuova domanda. – xDaevax

+0

Non è una domanda. Ho risolto il mio problema, che è esattamente lo stesso, con questo filtro. – ff9will

0

Ho fatto un bel po 'di ricerca su questo tema quindi questo potrebbe aiutare gli altri che stanno vivendo lo stesso problema su Tomcat. Questo è preso da http://wiki.apache.org/tomcat/FAQ/CharacterEncoding.

(Come utilizzare UTF-8 in tutto il mondo).

  • Imposta URIEncoding = "UTF-8" sul tuo <Connector> in server.xml. Riferimenti: connettore HTTP, connettore AJP.
  • Utilizzare un filtro di codifica caratteri con la codifica predefinita impostata su UTF-8
  • Modificare tutti i JSP per includere il nome charset nel relativo contentType. Ad esempio, utilizzare <% @ page contentType = "text/html; charset = UTF-8"%> per le solite pagine JSP e <jsp:directive.page contentType="text/html; charset=UTF-8" /> per le pagine nella sintassi XML (ovvero documenti JSP).
  • Modificare tutti i servlet per impostare il tipo di contenuto per le risposte e includere il nome charset nel tipo di contenuto in UTF-8. Utilizzare response.setContentType ("text/html; charset = UTF-8") o response.setCharacterEncoding ("UTF-8").
  • Modificare le librerie di generazione contenuto utilizzate (Velocity, Freemarker, ecc.) Per utilizzare UTF-8 e specificare UTF-8 nel tipo di contenuto delle risposte generate.
  • Disattivare qualsiasi valvola o filtro che possa leggere i parametri di richiesta prima che il filtro di codifica dei caratteri o la pagina jsp abbia la possibilità di impostare la codifica su UTF-8.
Problemi correlati