Maison > Java > javaDidacticiel > le corps du texte

Notes JAVA WEB - Caractères chinois tronqués

巴扎黑
Libérer: 2017-06-26 11:11:01
original
1449 Les gens l'ont consulté

Analyse des problèmes de code tronqué JAVA WEB

Cause du code tronqué

Dans le processus de développement Web Java, nous rencontrons souvent le problème du code tronqué La raison du code tronqué. peut être résumé comme un codage de caractères. Ne correspond pas à la méthode de décodage.

Puisque la raison des caractères tronqués est que les méthodes d'encodage et de décodage des caractères ne correspondent pas, alors pourquoi devons-nous encoder les caractères ? Est-il acceptable de ne pas les encoder ? En effet, l'unité de base de stockage des données dans un ordinateur est de 1 octet, soit 8 bits, donc le nombre maximum de caractères qu'il peut exprimer est de 28=256, et dans notre société réelle, il y a beaucoup plus de caractères (caractères chinois, anglais, autres caractères, etc.) que ce nombre, donc afin de résoudre le conflit entre caractères et octets, les caractères doivent être codés avant de pouvoir être stockés dans l'ordinateur.

Encodage et décodage

 Les méthodes d'encodage courantes dans les ordinateurs incluent ASCII, ISO-8859-1, GB2312, UTF-16 et UTF-8.

Le code ASCII est représenté par les 7 bits inférieurs d'un octet, donc le nombre maximum de caractères pouvant être exprimés est de 27=128 . ISO-8859-1 est une extension de l'organisation ISO basée sur le code ASCII. Elle est compatible avec le code ASCII et couvre la plupart des caractères d'Europe occidentale. ISO8859-1 utilise un octet pour représenter, il peut donc exprimer jusqu'à 256 caractères. GB2312 utilise un codage sur deux octets. La plage de codage est A1-F7, où A1-A9 est la zone de symboles et B0-F7 est la zone de caractères chinois, contenant 6 763 caractères chinois. GBK consiste à étendre le codage GB2312 et à ajouter davantage de caractères chinois. Il existe 21 003 caractères chinois pouvant être exprimés. UTF-16 utilise une méthode de codage de longueur fixe. Quel que soit le caractère représenté, il est représenté par 2 octets. C'est également le format de stockage des caractères dans la mémoire JAVA. Contrairement à UTF-16, UTF-8 utilise une méthode de codage de longueur variable et différents types de caractères peuvent être composés de 1 à 6 octets.

Jetons un coup d'œil à l'encodage des différentes méthodes d'encodage dans l'ordinateur en utilisant la chaîne "Hyuuga Hinata", comme indiqué ci-dessous.

Analyse et solution du code tronqué

 Pour le problème du code tronqué dans JAVA WEB, nous divisons les caractères tronqués causés par les requêtes et les caractères tronqués causés par les réponses. Pour différents caractères tronqués, nous devons analyser les causes des caractères tronqués, c'est-à-dire quelle est la méthode de codage des caractères et quelle est la méthode de décodage. .

Pour le code tronqué provoqué par la requête, nous devons analyser la requête HTTP et vérifier sa méthode d'encodage Étant donné que les requêtes HTTP sont divisées en requêtes Get et requêtes Post, nous en discuterons. séparément ensuite.

Pour la requête Get, il s'agit de la méthode de requête par défaut du navigateur, et de la méthode de soumission lorsque le formulaire est défini sur "Get". Nous vérifions le contenu spécifique via le navigateur Firefox comme suit :

La barre d'adresse est :

Le contenu de la demande est :

 

Nous pouvons voir à partir de la requête ci-dessus que la chaîne de requête dans la requête GET est stockée dans la ligne de requête et envoyée au Serveur WEB, grâce à l'encodage "Hyuga Hinata" on peut voir que la méthode d'encodage utilisée par le navigateur pour cette chaîne est "UTF-8".

En regardant le code du serveur, nous pouvons voir des caractères tronqués (comme indiqué ci-dessous) En effet, le serveur décode les données après avoir reçu l'encodage de chaîne par défaut en utilisant ISO-8859-1. . , donc les méthodes de codage et de décodage ne sont pas unifiées.

 

La solution est la suivante :

Obtenez d'abord l'utilisateur de chaîne avant de décoder l'encodage, puis spécifiez la méthode d'encodage de la chaîne, comme indiqué ci-dessous :

Le diagramme de solution est le suivant suit :

 Dans le processus de développement Web Java, nous transmettons des paramètres dans des hyperliens et rencontrons souvent des situations chinoises. Dans ce cas, nous devons encoder le chinois, nous pouvons le définir sur UTF-8 et le schéma de décodage est le même que ci-dessus.

 

<a href="${pageContext.request.contextPath}/Test?user=<%=URLEncoder.encode("日向雏田", "UTF-8")%>">点击</a>
Copier après la connexion

 Pour la demande de publication, c'est la méthode de soumission lorsque la soumission du formulaire est définie sur " Poste" . Nous utilisons Firefox pour vérifier son contenu spécifique comme suit :

La barre d'adresse et sa page sont :

Le contenu de la demande de publication est :

, mettez le contenu de la demande directement dans le corps de la demande et envoyez-le au serveur Web, ainsi que la méthode d'encodage est "utf-8".

Dans cette Servlet de réponse, le corps de la méthode doPost est le suivant :

public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String user=request.getParameter("user");
		System.out.println(user);//输出为日向雏田
	}
Copier après la connexion
La raison du code tronqué ici est toujours que lorsque le code getParameter ("utilisateur"), le serveur Web utilise le schéma de décodage par défaut "ISO-8859-1" pour décodage, ce qui entraîne un codage et Si vous n'êtes pas d'accord avec le schéma de décodage, la solution peut être d'utiliser la solution get request tronquée, mais il existe une solution plus simple, qui consiste à spécifier directement le schéma de codage/décodage du corps de la méthode comme "utf-8". Le plan est le suivant.

 

L'analyse ci-dessus du code tronqué a provoqué par la demande complète.
public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("utf-8");  //设置请求体的编码/解码方案为UTF-8 但是请求行的编码解码方案不会受影响
		String user=request.getParameter("user");
		System.out.println(user);          //输出为日向雏田
	}
Copier après la connexion

Dans le code tronqué provoqué par l'impact, le serveur Web écrira le contenu de la réponse dans le corps de la réponse et le renverra au client sans impliquer la ligne d'état. Par exemple, si « HelloWorld » est affiché sur le navigateur, la réponse est celle indiquée dans la figure ci-dessous.


Nous devons impliquer quatre méthodes pour le code tronqué provoqué par la réponse, comme suit :

 
response.setHeader("Content-Type", "text/html;cahrset=utf-8");//设置发送到客户端的响应的内容类型和响应内容的编码类型(响应体的编码类型)
response.setCharacterEncoding("utf-8");//设置响应体的编码类型
response.getWriter();           //获取响应的输出字符流 
response.getOutputStream();        //获取响应的输出字节流
Copier après la connexion
Pour définition de la réponse Le type d'encodage du corps, tel que Response.setHeader("Content-Type", "text/html;cahrset=utf-8"); et Response.setCharacterEncoding("utf-8"); par ces deux méthodes, etc. Efficace, si la méthode de codage du corps de la réponse n'est pas définie, la valeur par défaut est ISO-8859-1, et la méthode de codage du jeu de caractères du corps de la réponse ultérieurement itérera la méthode de codage du paramètre précédent. Ces deux méthodes sont valides avant la méthode getWriter, et la méthode de définition du codage dans la méthode getWriter ne sera pas valide.

Mais ces deux méthodes sont un peu différentes, c'est-à-dire que la méthode setHeader("Content-Type", "text/html;cahrset=utf-8") sera automatiquement utilisée par le navigateur. La méthode d'encodage du corps de la réponse est décodée et la méthode setCharacterEncoding() n'est pas utilisée par tous les navigateurs pour décoder en utilisant la méthode d'encodage de cette méthode. Les deux méthodes suivantes sont testées et les résultats sont les suivants :

 

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setHeader("Content-Type", "text/html;charset=utf-8");
		response.getWriter().write("日向雏田");
	}
Copier après la connexion
 

  

  从上面可以看到第一个方法对于浏览器来说,支持的较好,提倡采用第一种方法设置响应体的字符编码方式。

  对于获取响应字符输出流的方法,如果在此之前没有设置响应体的编码方式,那么默认为null,即ISO-8859-1方式进行编码。而且后面设置的编码方式会覆盖前面设置的编码方式。在getWriter()方法之后设置的编码无效。

  对于获取响应输出字节流,我们在输出字符串时,我们需要设置字符串的编码方式如果没有那么默认ISO-8859-1。

  对于前面2个输出流,由于只有一个输出缓存,所以这两个方法互斥。

  以上,为了保证响应无乱码,需要保证字符编码和解码方法的统一,方案如下:

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
//	方案1
//		response.setHeader("Content-Type", "text/html;charset=utf-8");
//		response.getWriter().write("日向雏田");
//	方案2
//		response.getOutputStream().write("日向雏田".getBytes("UTF-8"));
//	方案1,2互斥
	}
Copier après la connexion

  

  此外在Java web开发过程中,我们还会遇到当进行文件下载时,中文文件名导致的问题,如下图所示:

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String realPath=this.getServletContext().getRealPath("/src/日向雏田.jpg");
		String fileName=realPath.substring(realPath.lastIndexOf(&#39;\\&#39;)+1);
		response.setHeader("content-disposition", "attachment;filename="+fileName);
		InputStream is=new FileInputStream(new File(realPath));
		OutputStream os=response.getOutputStream();
		byte[] buff=new byte[1024];
		int len=0;
		while((len=is.read(buff))>0){
			os.write(buff, 0, len);
		}
		os.close();
		is.close();
	}
Copier après la connexion

  采用火狐浏览器进行测试,查看页面效果,及其响应结果如下:

  

  经过查看响应头分析,下载文件名存放在响应头中,且对于中文文字没有采用UTF-8、UTF-16、GBK等等能识别中文的编码,那么对于中文文件名导致采用哪种编码方式呢?查看REF 7578得知,在此处采用ASCII编码,但是REF规定,如果不可避免的要使用非ASCII码的字符,程序员应该均匀的使用UTF-8,来最小化交互操作的问题。

  所以,解决方案就是把文件名编码成UTF-8,传递给响应头,浏览器(部分)默认对该文件名进行UTF-8解码处理。

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String realPath=this.getServletContext().getRealPath("/src/日向雏田.jpg");
		String fileName=realPath.substring(realPath.lastIndexOf(&#39;\\&#39;)+1);
		String utf_8Name=URLEncoder.encode(fileName,"utf-8");//解决方案
		response.setHeader("content-disposition", "attachment;filename="+utf_8Name);
		InputStream is=new FileInputStream(new File(realPath));
		OutputStream os=response.getOutputStream();
		byte[] buff=new byte[1024];
		int len=0;
		while((len=is.read(buff))>0){
			os.write(buff, 0, len);
		}
		os.close();
		is.close();
	}
Copier après la connexion

  效果如下:其中火狐浏览器并没有对其解码

 

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!