Codierung und Dekodierung
In der folgenden Abbildung können wir verstehen, wo sich in Javaweb Transcodierung befindet:
Der Benutzer möchte, dass der Server eine HTTP -Anforderung sendet. Die Orte, an denen Codierung URL, Cookies und Parameter sind, sind erforderlich. Nach der Codierung akzeptiert der Server die HTTP -Anforderung, analysiert die HTTP -Anforderung und dekodiert dann die URL, Cookies und Parameter. Während der Geschäftslogikverarbeitung des Servers müssen Datenbanken, lokale Dateien oder andere Dateien im Netzwerk usw. gelesen werden. Diese Prozesse erfordern Codierung und Decodierung. Nach Abschluss der Verarbeitung codiert der Server die Daten und sendet sie an den Client, und der Browser zeigt sie nach dem Dekodieren dem Benutzer an. Es gibt viele Codierung und Dekodierung in diesem gesamten Prozess, und der wahrscheinlichste Ort, an dem verstümmelt wirkt, ist der Prozess der Interaktion mit dem Server und dem Client.
Der gesamte oben erwähnte Vorgang kann wie folgt zusammengefasst werden: Die seitencodierten Daten werden an den Server übergeben, und der Server dekodiert die erhaltenen Daten, und nach einer Geschäftslogikverarbeitung wird das Endergebnis codiert und verarbeitet, und der Client decodiert und zeigt es dem Benutzer an. Im Folgenden werde ich also um eine Erklärung der Codierung und Dekodierung von Javaweb bitten.
Wenn der Client möchte, dass der Server eine Anfrage sendet, wird er vier Situationen übergeben:
1. Direkter Zugriff nach URL.
2. Seitenlink.
3. Form
4. Formular nach Einreichung
URL -Methode: Bei URLs gibt es kein Problem, wenn alle URLs auf Englisch sind. Wenn es Chinesen gibt, wird eine Kodierung beteiligt. Wie kodieren Sie? Welche Regeln möchten Sie codieren? Wie kann man es also dekodieren? Die Antworten werden nacheinander unten beantwortet! Schauen Sie sich zunächst die Komponenten der URL an:
In dieser URL codiert der Browser Pfad und Parameter. Verwenden Sie die folgende URL, um den Codierungsprozess besser zu erklären
http://127.0.0.1:8080/perbank/i am cm? name = ich bin cm
Geben Sie die obige Adresse in das Bowser -URL -Eingangsfeld ein. Durch Anzeigen der HTTP -Nachrichten -Header -Informationen können wir sehen, wie der Browser sie codiert. Hier sind die Codierungsbedingungen von drei Browsern:
Sie können sehen, dass die Codierung von "I Am" von Major Browsern wie folgt lautet:
Pfadteil | Abfragezeichenfolge | |
Firefox | E6 88 91 E6 98 Af | E6 88 91 E6 98 Af |
Chrom | E6 88 91 E6 98 Af | E6 88 91 E6 98 Af |
Dh | E6 88 91 E6 98 Af | CE D2 CA C7 |
Protected void converturi (MessageBytes URI, Anfrage) löst eine Ausnahme aus {bytechunk bc = uri.getByTechunk (); int länge = bc.getLength (); Charchunk cc = uri.getCHARChunk (); cc.alcode (Länge, -1); String ec = connector.geturiencoding (); // den URI -Decodierungssatz erhalten, wenn (Enc! = Null) {B2CConverter conv = request.geturiconverter (); try {if (conv == null) {conv = new b2cconverter (ENC); request.seturiconverter (conv); }} catch (ioException e) {...} if (conv! = null) {try {convert (bc, cc, cc.getBuffer (). Länge - cc.getend ()); Uri.setchars (cc.getBuffer (), cc.getStart (), cc.getLength ()); zurückkehren; } catch (ioException e) {...}}} // Standard -Codierung: Schnellkonvertier Byte [] bbuf = bc.getBuffer (); char [] cbuf = cc.getBuffer (); int start = bc.getStart (); für (int i = 0; i <länge; i ++) {cbuf [i] = (char) (bbuf [i+start] & 0xff); } uri.setchars (CBUF, 0, Länge); } Aus dem obigen Code können wir feststellen, dass der Dekodierungsvorgang des URI zuerst den Dekodierungssatz des Connectors erhalten hat, der in server.xml konfiguriert ist
<Connector URiencoding = "UTF-8" />
Wenn nicht definiert, wird die Standardcodierung von ISO-8859-1 zum Parsen verwendet.
Für den Teil der Abfrage -Zeichenfolge wissen wir, dass alle Parameter in Parametern gespeichert sind, und dann verwenden wir Anforderungen. GETPARAMETER wird die Dekodierungsarbeiten erledigt, wenn die GetParameter -Methode zum ersten Mal bezeichnet wird. In der GetParameter -Methode ruft sie die Parseparameter -Methode von org.apache.catalina.connector.request auf, die die übergabes Parameter dekodieren. Der folgende Code ist nur ein Teil der Parseparameters -Methode:
// die codierende Zeichenfolge abrufen Enc = getCharactercoding (); // den charset booleschen in contentType useBodyCodingforuri = connector.getuseBodyCodingForuri () definiert; if (Enc! = null) {// Wenn die Codierung nicht leer ist, setzen Sie die Codierung auf ENC -Parameter.SetSetEnCoding (ENC); if (useBodyCodingForuri) {// Wenn der Diagramm eingestellt ist, setzen Sie die Decodierung von QueryString auf Diagrammparameter.SetQueryStringCoding (ENC); }} else {// Setzen Sie die Standard -Dekodierungsmethodenparameter. if (useBodyCodingForuri) {parameters.setQueryStringCoding (org.apache.coyote.constants.default_character_encoding); }} Aus dem obigen Code können wir feststellen, dass das Dekodierungsformat der Abfragezeichenfolge entweder das festgelegte Diagramm verwendet oder das Standard-Dekodierungsformat ISO-8859-1 verwendet. Beachten Sie, dass das Diagramm in dieser Einstellung der im HTTP -Header definierte ContentType ist. Gleichzeitig müssen wir Folgendes konfigurieren:
<Connector URienCoding = "UTF-8" useBodyCodingforuri = "True"/>
Der obige Teil führt den Codierungs- und Dekodierungsprozess von URL -Anfragen im Detail ein. In der Tat sind unsere mehr Möglichkeiten, uns in dem Formular einzusetzen.
Form bekommen
Wir wissen, dass das Senden von Daten über URLs leicht zu Problemen mit verstümmelten Code verursacht werden kann. Daher verwenden wir dazu, Formulare zu verwenden. Wenn der Benutzer auf das Formular einreicht, setzt der Browser weitere Codes, um die Daten an den Server zu übergeben. Die durch GET über eingereichten Daten werden nach der URL gespleißt (kann sie als Abfragezeichenfolge angesehen werden? Der Tomcat-Server wird entsprechend dem festgelegten Uriencoding dekodieren. Wenn er nicht festgelegt ist, wird die Standard-ISO-8859-1 zum Dekodieren verwendet. Wenn wir die Codierung auf UTF-8 auf der Seite festlegen und das Uriencoding nicht festgelegt ist oder nicht festgelegt wird, tritt der Kelsel auf, wenn der Server decodiert. Zu diesem Zeitpunkt können wir im Allgemeinen die richtigen Daten über die Form der neuen String (Request.GetParameter ("Name") erhalten. GetBytes ("ISO-8859-1"), "UTF-8").
Formposten
Für die Post -Methode wird die von ihr verwendete Codierung auch durch die Seite bestimmt, dh contentType. Wenn ich ein Formular einsage, indem ich auf die Schaltfläche Senden auf der Seite klicke, codiert der Browser zunächst die Parameter des Postformulars gemäß dem Charset -Codierungsformat des Onentype und sendet es an den Server. Auf der Serverseite verwendet es auch den im ContentType festgelegten Zeichensatz (es unterscheidet sich von der GET -Methode hier). Dies bedeutet, dass die über das Postformular eingereichten Parameter im Allgemeinen keine verstümmelten Probleme haben. Natürlich können wir das Zeichensatz für uns selbst festlegen: Anfrage.
Lösen Sie das Problem der verstümmelten URLs auf Chinesisch
Wir senden hauptsächlich Anfragen über zwei Einreichungsformen an den Server: URL und Form. Die Formularform hat im Allgemeinen keine verstümmelten Probleme, und die verstümmelten Probleme liegen hauptsächlich auf der URL. Durch die Einführung der vorherigen Blogs wissen wir, dass der Prozess des Sendens von Anforderungscodierung per URL wirklich zu verwirrend ist. Unterschiedliche Betriebssysteme, unterschiedliche Browser und unterschiedliche Web -Charakter -Sets führen zu völlig unterschiedlichen Codierungsergebnissen. Ist es nicht zu beängstigend, wenn Programmierer jedes Ergebnis berücksichtigen möchten? Gibt es eine Möglichkeit, sicherzustellen, dass der Client nur eine Codierungsmethode verwendet, um eine Anforderung an den Server auszugeben?
haben! Hier biete ich hauptsächlich die folgenden Methoden
JavaScript
Die Verwendung von JavaScript -Codierung gibt dem Browser nicht die Möglichkeit, einzugreifen. Senden Sie nach der Codierung eine Anforderung an den Server und dekodieren Sie sie dann auf dem Server. Beim Beherrschen dieser Methode benötigen wir drei Methoden der JavaScript -Codierung: Escape (), Encodeuri () und Encodeuricomponent ().
Flucht
Die angegebene Zeichenfolge wird mit dem SIO -Latin -Zeichensatz codiert. Alle Nicht-ASCII-Zeichen werden im %xx-Format als Zeichenfolgen codiert, wobei XX die hexadezimale Zahl darstellt, die dem Zeichen im Zeichensatz entspricht. Beispielsweise beträgt die dem Format entsprechende Codierung %20. Die entsprechende Dekodierungsmethode ist unausweichlich ().
In der Tat kann escs () nicht direkt für die URL-Codierung verwendet werden, seine tatsächliche Funktion besteht darin, den Unicode-kodierten Wert eines Charakters zurückzugeben. Zum Beispiel ist das Ergebnis von "Ich bin cm" oben %U6211 %U662FCM, wobei die entsprechende Codierung von "I" 6211 beträgt, die Codierung von "Ja" 662F und die Codierung von "CM" CM.
Beachten Sie, dass Escape () nicht durch "+" codiert wird. Wir wissen jedoch, dass eine Webseite, wenn es Leerzeichen gibt, in + Zeichen konvertiert wird. Wenn der Server Daten verarbeitet, wird das + Zeichen in Räume verarbeitet. Seien Sie daher vorsichtig, wenn Sie es verwenden.
codieren
Wenn Sie die gesamte URL codieren, wird das utf-8-Format verwendet, um die codierte Zeichenfolge auszugeben. Encodeuri codiert jedoch keine Sonderzeichen außer ASCII -Codierung, wie :! @ # $ & * () =: /; ? + '.
Enkodierkomponent
Umwandeln Sie Uri-Zeichenfolgen in Fluchtformat-Saiten im UTF-8-Codierungsformat. Im Vergleich zu Encodeuri wird Encodeuricomponent leistungsfähiger sein und es wird für Symbole (; /?: @ & = + $, #) Codiert, die nicht in encodeuri () codiert sind. Encodeuricomponent codiert jedoch nur die Komponenten der URL einzeln und wird nicht zur Codierung der gesamten URL verwendet. Die entsprechende Dekodierungsfunktionsmethode Decodeuricomponent.
Natürlich verwenden wir normalerweise die Encodeuri -Partei, um Codierungsoperationen durchzuführen. Die sogenannte JavaScript-Codierung und -decodierung zweimal im Hintergrund ist, diese Methode zu verwenden. Es gibt zwei Lösungen, um dieses Problem in JavaScript zu lösen: eine Transkodierung und zwei Transkodierungsmethoden.
Einmal transkodieren
JavaScript -Transkodierung:
var url = '<s: Eigenschaft value = "webpath" />/showmoblieqrcode.servlet?name=I am cm'; window.location.href = cododeuri (URL);
Transcodierte URL: http://127.0.0.1:8080/perbank/showmoblieqrcode.servlet?name=%E6%8%91%E6%98%AFCM
Backend -Verarbeitung:
String name = request.getParameter ("Name"); System.out.println ("Vordergrund -Eingangsparameter:" + Name); name = new String (name.getBytes ("ISO-8859-1"), "UTF-8"); System.out.println ("decodierte Parameter:" + Name); Ausgangsergebnis:
Eingehende Parameter in der Rezeption: ?????? cm
Nach dem Dekodieren von Parametern: Ich bin CM
Sekundäre Transkodierung
JavaScript
var url = '<s: Eigenschaft value = "webpath" />/showmoblieqrcode.servlet?name=I am cm'; window.location.href = cododeuri (cododeuri (url));
Transcodierte URL: http://127.0.0.1:8080/perbank/showmoblieqrcode.servlet?name=%25e6%2588%2591%25e6%2598%25afcm
Backend -Verarbeitung:
String name = request.getParameter ("Name"); System.out.println ("Vordergrund -Eingangsparameter:" + Name); name = urdecoder.decode (name, "utf-8"); System.out.println ("decodierte Parameter:" + Name); Ausgangsergebnis:
Front-End eingehende Parameter: E68891E698AFCM
Nach dem Dekodieren von Parametern: Ich bin CM
Filter
Mit Filtern liefern Filter zwei Typen, die erste ist das Festlegen der Codierung, und die zweite besteht darin, Decodierungsvorgänge direkt im Filter auszuführen.
Filter 1
Dieser Filter legt direkt das Codierungsformat der Anforderung fest.
öffentliche Klasse Charactercoding implementiert Filter {private filterconfig config; String coding = null; public void destroy () {config = null; } public void dofilter (ServletRequest -Anfrage, ServletResponse -Antwort, Filterchain -Kette) löst IOException, ServletException aus {Request.Setcharactercoding (codieren); chain.dofilter (Anfrage, Antwort); } public void init (filterConfig config) löst servletException {this.config = config; // Konfigurationsparameter sca. str = config.getInitParameter ("codieren") abrufen; if (str! = null) {coding = str; }}} Konfiguration:
<!-chinesische Filterkonfiguration-> <Filter> <Filter-name> chinesische Mittelkodierung </filter-name> <Filterklasse> com.test.filter.Charactercoding </filterklasse> <init-param> </param-name> codieren </param-value> </filter </param-valing <Filter-name> chinesiscodierung </filter-name> <url-pattern>/*</url-pattern> </filtermapping>
Filter 2
In der Verarbeitungsmethode dekodiert der Filter die Parameter direkt und setzt dann die dekodierten Parameter in das Anforderungsattribut zurück.
öffentliche Klasse Charactercoding implementiert Filter {Protected FilterConfig FilterConfig; String coding = null; public void destroy () {this.FilterConfig = null; } / *** initialisieren* / public void init (filterconfig filterconfig) {this.filterConfig = filterConfig; } / *** Instrumente in das Encodierungsformular von UTF -8 umwandeln** @param Instrelt eingeben* @return utf - 8's Codierungsformular String* @throws UnsupportedenCodingException* / private String toutf (String Instrument) löscht UnneupportendenCodingException {String outstr = ""; if (instr! } Rückkehr; } / *** chinesische Verarbeitung von Kleidungsfilter* / public void dofilter (ServletRequest ServletRequest, ServletResponse ServletResponse, Filterchain -Kette) löst IoException, ServleTexception {httpServletRequest Request = (httpServletRequest) servletRequest; HttpServletResponse response = (httpServletResponse) servletResponse; // Die Methode zum Abholen der Anforderung (1. post oder 2.get) und eine andere Verarbeitung erfolgt gemäß verschiedenen Anforderungsmethoden String -Methode = Request.getMethod (); // 1. Für Anfragen, die in Post eingereicht wurden, setzen Sie die Codierung direkt auf UTF-8 if (method.equalSignoreCase ("post")) {try {request.setcharactercoding ("utf-8"); } catch (unportedenCodingException e) {e.printstacktrace (); }} // 2. Anforderung in Get sonst {// den vom Client Enumeration <string> Paramnames = Request.GetParameternames () eingereichten Parameter -Set -Set ausgeliefert. // Überqueren Sie den Parametersatz, um den Namen und den Wert jedes Parameters zu erhalten (Paramnames.HasmoreElements ()) {String name = paramnames.nextElement (); // Die Parameternamen -String -Werte [] = Request.GetParamTervalues (Name) herausholen; // Take out its value according to the parameter name // If the parameter value set is not empty if (values != null) { // traverse the parameter value set for (int i = 0; i < values.length; i++) { try { // Circle back and call each value toUTF(values[i]) method to convert the character encoding of the parameter value String vlustr = toUTF(values[i]); Werte [i] = vlustr; } catch (unportedenCodingException e) {e.printstacktrace (); }} // den Wert in der Form eines Attributs in der Request request.setAttribute (Name, Werte) ausblenden; }}} // Setzen Sie die Antwortmethode und unterstützen Sie chinesische Zeichensatze Antwort. // Führen Sie den nächsten Filter weiter aus. Wenn es keinen Filter gibt, ist die Anfrage eine Kette.Dofilter (Anfrage, Antwort); }} Konfiguration:
<!-- Chinese filter configuration --> <filter> <filter-name>chineseEncoding</filter-name> <filter-class>com.test.filter.CharacterEncoding</filter-class> </filter> <filter-mapping> <filter-name>chineseEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
andere
1. Setzen Sie PageCoding und ContentType
<%@ page Language = "java" contentType = "text/html; charset = utf-8" pageCoding = "utf-8"%>
2. Richten Sie die Uriencodierung von Tomcat ein
Standardmäßig verwendet der Tomcat-Server das ISO-8859-1-Codierungsformat, um die vom Parameter Uriencodierung angeforderte URL zu codieren. Daher müssen wir nur URienCoding = "UTF-8" zum <Connektor> -Tag der Server.xml-Datei von Tomcat hinzufügen.