jsp乱码分析及解决(1)

1 篇文章 0 订阅

        想必大家在网站开发时经常遇到乱码问题,最近自己在写了一个博客的小例子时,又遇到了乱码问题,一般都是些常见的,往往搜搜,都有解决方案,但网上大部分都是直接贴解决方案的,没有指出具体原因,所以这两天自己看了一些关于乱码的文章,慢慢有点头绪,所以抓紧写下来,我会把自己遇到的乱码问题一一呈现给大家,并分析原因及写出解决办法。


         如有不对,还请大家多多包含,积极指正!一个人的理解往往是有限,甚至有错误,集思广益才会使分析更趋于正确、完美!



先看一段代码,解释几处代码:

<%@ page language="java" pageEncoding="gb2312"%>

<%@ page contentType="text/html;charset=iso8859-1"%>

<html>

<head>

<title>JSP的中文处理</title>

<meta http-equiv="Content-Type" content="text/html charset=gb2312">

</head>

<body>

<%out.print("JSP的中文处理");%>

</body>

</html>

第一处<%@ page language="java" pageEncoding="gb2312"%>,指定了页面的编码格式,jsp文件的存储格式就是这个编码格式,Eclipse会根据这个编码格式保存文件。并编译jsp文件,包括里面的汉字。


第二处编码为解码格式。因为存为gb2312的文件被解码为iso8859-1,这样如有中文肯定出乱码。也就是必须一致。如果第二处所在的这一行没有的话,系统默认也是使用iso8859-1的编码格式。所以如果没有这一行的话,也会出现乱码。必须一致才可以。

这行负责jsp页面中字符按什么编码格式显示,也就是最终见到的网页内容的编码格式。

注意:<%@ page language="java" pageEncoding=""%>指定了,<%@ page contentType="text/html;charset="%>没有指定的话,一般默认是iso8859-1编码格式;反之,它们编码格式相同。


 第三处编码为控制浏览器的解码方式。如果前面的解码都一致并且无误的话,这个编码格式用不用设置都可以。有的网页出现乱码,就是因为浏览器不能确定使用哪种编码格式。因为页面有时候会嵌入页面,导致浏览器混淆了编码格式出现了乱码。

注意:<%@ page contentType="text/html;charset="%>指定了浏览器的编码格式,如果jsp页面中指定了这个,那么meta http-equiv="Content-Type" content="text/html charset=">是不起作用的;只有jsp中没有<%@ page contentType="text/html;charset="%>,它才会起作用;如果它们都存在,<%@ page contentType="text/html;charset="%>优先。




下面开始进入正文:


情形1:

             jsp页面利用form表单提交(method=“post”),在servlet文件中利用request.getParameter("参数名")得到传过来的值。这里往往会出现乱码。




接下来的例子的处理方式是正确的,大家注意看红色字


关键点:jsp中的charset=“utf-8”且value = new String(value.getBytes("ISO8859_1"), "utf-8");这两个地方字符要保持一致才行。


index.jsp

<%@ page contentType="text/html; charset=utf-8" language="java" import="java.sql.*" errorPage="" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
<link href="CSS/style.css" type="text/css" rel="stylesheet">
<style type="text/css"></style>
</head>

<body onselectstart="return false">



<table class="indexmain">
  <tr>
    <td valign="top"><table width="658" border="0">
 <tr>
        <td colspan="2"> </td>
 </tr>
      <tr>
        <td width="92" height="358"> </td>
        <td width="550" valign="bottom">
		
<form name="form1" method="post" action="ConsumerServlet?method=0&sign=0" onSubmit="return userCheck()">
<table width="291" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td width="66" height="30">用户名:</td>
    <td width="225">
      <input name="account" type="text" class="inputinput" id="account" size="30">
    </td>
  </tr>
  
  <tr>
    <td height="30">密  码:</td>
    <td><input name="password" type="password" class="inputinput" id="password" size="30"></td>
  </tr>
  
  <tr>
    <td height="30" colspan="2" align="center">
	    <input type="image" class="inputinputinput" src="images/land.gif"> 
               
        <a href="#" onClick="javascript:form1.reset()"><img src="images/reset.gif"></a>
          
		<a href="accountAdd.jsp"><img src="images/register.gif"></a>
		
   </td>
  </tr>
</table>
</form>
		
		</td>
      </tr>
</table>
	
	</td>
</tr>
</table>
<script src="JS/validate.js" language="javascript" type="text/javascript"></script>
</body>
</html>


ConsumerServlet.java


	// 用户登录操作
	public void checkConsumer(HttpServletRequest request,HttpServletResponse response)
			                                                         throws ServletException, IOException {
		
		String account = Chinese.toChinese(request.getParameter("account"));
	
		consumerDao = new ConsumerDao();
		
		ConsumerForm consumerForm = consumerDao.getConsumerForm(account);
		
		if (consumerForm == null) {
			request.setAttribute("information", "您输入的用户名不存在,请重新输入!");
		} else if (!consumerForm.getPassword().equals(
				request.getParameter("password"))) {
			request.setAttribute("information", "您输入的登录密码有误,请重新输入!");
		} else {

			request.setAttribute("form", consumerForm);
			
					
		}
		//验证通过之后
		RequestDispatcher requestDispatcher = request.getRequestDispatcher("dealwith.jsp");
		requestDispatcher.forward(request, response);
	}


Chinese.java(关键)

              

public class Chinese {
    public  static String  toChinese(String value) {
           try {
               if (value == null) {
                   return "";
               } else {
                   value = new String(value.getBytes("ISO8859_1"), "utf-8");
                   return value;                                             
               }                             //用ISO8859_1的编码格式去读取value,并转换成utf-8
           } catch (Exception e) {
               return "";
           }
    }
}


这段代码负责转码,可能大家对红色代码不太理解,我这里贴上JAVA API的解释:


public byte[] getBytes(String charsetName)

               throws UnsupportedEncodingException

使用指定的字符集将此String 解码为字节序列,并将结果存储到一个新的字节数组中。

当此字符串不能在给定的字符集中解码时,该方法无指定的行为。当需要进一步控制解码过程时,应使用CharsetEncoder 类。

参数:

charsetName - 受支持的 charset 名称

返回:

结果字节数组

抛出:

UnsupportedEncodingException - 如果指定的字符集不受支持


public String(byte[] bytes,

              String charsetName)

       throws UnsupportedEncodingException

构造一个新的 String,方法是使用指定的字符集解码指定的字节数组。新的 String 的长度是一个字符集函数,因此不能等于字节数组的长度。

当给定字节在给定字符集中无效的情况下,该构造方法无指定的行为。当需要进一步控制解码过程时,应使用 CharsetDecoder 类。

参数:

bytes - 要解码为字符的字节

charsetName - 受支持的 charset 的名称

抛出:

UnsupportedEncodingException - 如果指定字符集不受支持




情形2:

          form表单的另外一种形式(利用Submit)。



下面是一个提交页面(submit.jsp),代码如下:


<%@ page contentType="text/html; charset=gb2312"%>

 <html>

<head><title>JSP的中文处理</title>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

</head>

<body>

<form name="form1" method="post/get" action="process.jsp">

<div align="center">

<input type="text" name="name">

<input type="submit" name="Submit" value="Submit">

</div>

</form>

</body>

</html>

下面是处理页面 (process.jsp) 代码:


<%@ page contentType="text/html; charset=gb2312"%>

<html>

<head>

<title>JSP的中文处理</title>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

</head>

<body>

<%=request.getParameter("name")%>

</body>

</html>

如果输入中文,就会看到乱码,解决方法同上:


<%@ page contentType="text/html; charset=gb2312"%>

<html>

<head>

<title>JSP的中文处理</title>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

</head>

<body>

<%

String s=new String(request.getParameter("name").getBytes("ISO-8859-1"),"gb2312") ;

out.print(s);

%>

</body>

</html>

这样就OK了。



分析:

            tomcat默认使用ISO-8859-1的方式去读取数值的,但实际里面的字符编码应该是jsp页面的pageEncoding指定的(一般不会是iso-8859-1),这样的话读取之后显示的编码格式和存储的格式不一致,所以出现了乱码。


            而我们的转码恰恰解决了这个问题,我们先使用ISO-8859-1格式解码字符串,再利用与pageEncoding一致的编码格式解码字节数组,这样就使读取之后显示的编码格式和存储的格式一致,乱码问题解决。






网上搜索的来另外一种解决方案:

                                         通过request.seCharacterEncoding ("gb2312")对请求进行统一编码。


修改后的process.jsp代码如下:


<%@ page contentType="text/html; charset=gb2312"%>

<%request.setCharacterEncoding("gb2312");%>

<html>

<head>

<title>JSP的中文处理</title>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

</head>

<body>

<%=request.getParameter("name")%>

</body>

</html>

经测试,这个方法不行,还是乱码,哪位给解释解释????






未完待续~~~


               

           






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值