ITKeyword,专注技术干货聚合推荐

注册 | 登录

java web 学习总结之 Servlet/JSP 编码问题

u014756827 分享于 2014-07-09

推荐:【Java.Web】JSP —— HTML, Servlet,JSP比较, JSP基础

HTML V.S. Servlet V.S. JSP 静态HTML文件,Servlet和JSP都能向客户端返回HTML页面。 静态HTML文件 当浏览器请求访问http://localhost:8080/base-webapp/index.h

2019阿里云全部产品优惠券(新购或升级都可以使用,强烈推荐)
领取地址https://promotion.aliyun.com/ntms/yunparter/invite.html

Servlet和JSP编码问题  

字节流:

 1.得到OutputStream  字节流


  OutputStream os = response.getOutputStream();
  用默认编码输出数据,就是本地编码GBK
  os.write("李赛是一个正直的男人".getBytes());

  在浏览器上输出正常。
  
 用代码设置浏览器的编码
  
  第一种搞法: 通过响应头
  response.setHeader("Content-Type", "text/html;charset=UTF-8");
  第二种搞法: 用meta标签模拟 (只针对IE浏览器有效果)
  os.write("<meta http-equiv='Content-Type'  

  content='text/html;charset=UTF-8' >".getBytes());
  第三种搞法:
  response.setContentType("text/html;charset=UTF-8");
  用指定的编码输出
  os.write("李赛是一个正直的男人".getBytes("gbk"));

   2.字符流

   得到字符流
   解决办法:设置服务器响应正文编码
   response.setCharacterEncoding("gbk");更改服务器往浏览器输出的编码,iso-8859-1转gbk往外输出
  
    如下一行代码有 两个功能:

告知浏览器用什么编码。

另外一个功能,告知服务器输出用什么编码
    response.setContentType("text/html;charset=gbk");
    代码的设置要先于printwriter的出现
    PrintWriter pw = response.getWriter();
    因为默认采用iso-8859-1输出,输出时肯定乱码
    pw.write("崔召金是一个成功男士");

 

  //设置response使用的码表,以控制response以什么码表向浏览器写出数据
  response.setCharacterEncoding("UTF-8");

  //指定浏览器以什么码表打开服务器发送的数据 以下的2种都可以
  response.setHeader("content-type", "text/html;charset=UTF-8");
  response.setContentType("text/html;charset=UTF-8");

  //把客户端提交的数据转码

  request.setCharacterEncoding("UTF-8");

推荐:java web -- jsp 和 servlet 线程安全

最近看了一些JAVA WEB开发部分,发现JSP和Servlet需要注意线程安全,以前玩过PHP,知道犹豫PHP的运行方式,所以PHP每个页面每次访问都是独立的,所以不用考虑线

关于JSP页面中的pageEncoding和contentType两种属性的详细解析

简单的说,pageEncoding是jsp文件本身的编码 contentType的charset是指服务器发送给客户端时的内容编码,例如:pageEncoding="GBK",这句话的意思是,告诉JVM这个jsp本身采用的"GBK"编码,在JSP编译成Servlet传给JVM的时候,就用“GBK”的编码方式将Jsp网页源文件翻译成统一的UTF-8形式的Java字节码,如果不加设定,则 JVM默认的用iso-8859这种编码方式。 contentType里的charset=gbk,指示的是此网页文件输出到浏览器的输出方式为gbk。在这个过程中,一个JSP的源文件需要经过三个阶段、两次编码,才能完成一次完整的输出。

以一个JSP文件通过Servlet容器假(设为Tomcat)输出到浏览器并显示的过程为例来说明三个阶段、两次编码的具体过程

第一阶段:第一次编码:从JSP到Servlet(.java文件),从pageEncoding———>UTF-8

在第一阶段中完成Jsp的第一次编码:第一次编码用到的指令是pageEncoding,根据pageEncoding=“XXX”的指示,找到编码的规则为“XXX”,服务器在将JSP文件编译成.java文件时会根据pageEncoding的设定读取jsp,结果是由指定的编码方案翻译成统一的UTF-8 JAVA源码(即.java),如果pageEncoding没有设定,则使用默认的iso-8859这种编码方式。设定错了出来的就是中文乱码。

第二阶段:从Servlet文件(.java)到Java字节码文件(.class),从UTF-8———>UTF-8

第一阶段是将jsp编译成.java文件,第二阶段主要是将(.java)的源文件翻译成JVM可识别的java byteCode,也就是Java字节码文件,是由JAVAC命令完成的,这些文件就是通常我们所说的(.class)文件。在这一阶段中,不论JSP编写时候用的是什么编码方案,经过这个阶段的结果全部是UTF-8的encoding的java源码。 JAVAC用UTF-8的encoding读取java源码,编译成UTF-8 encoding的二进制码(即.class),这是JVM对常数字串在二进制码(java encoding)内表达的规范。这一过程是由JVM的内在规范决定的,不受外界控件,这也是为什么,有时候看起来是乱码的程序能编译通过,但是去无法正常显示的原因。

第三阶段:第二次编码:从Tomcat服务器到浏览器,从UTF-8―――>contentType

这一阶段,主要是Tomcat显示的输出JSP网页的过程,这在一过程中用到的指令是contentType。 Tomcat(或其的application container)载入和执行由第二阶段生成出来JAVA二进制码,输出的结果,也就是在客户端可见到的结果,在这事输出过程中,由contentType属性中的charset来指示,将UTF8形式的二进制码以charset的编码形式来输出。如果没有人为设定,则默认的是ISO8859-1.的形式。

注意的问题:以上说的这个过程在大多数据情况是普遍适用的。但这也不是绝对的,还要看各自JSPC的处理方式.在网页设计中,设定pageEncoding不等于contentType,更有利亚洲区的文字 CJKV系JSP网页的开发和展示, (例pageEncoding=GB2312不等于 contentType=utf-8)。 jsp文件不像.java,.java在被编译器读入的时候默认采用的是操作系统所设定的locale所对应的编码,比如中国大陆就是GBK,台湾就是BIG5或者MS950。而一般我们不管是在记事本还是在ue中写代码,如果没有经过特别转码的话,写出来的都是本地编码格式的内容。所以编译器采用的方法刚好可以让虚拟机得到正确的资料。但是jsp文件不是这样,它没有这个默认转码过程,如果指定了pageEncoding就可以实现正确转码了。举个例子: <%@ page contentType="text/html;charset=utf-8" %>大都会打印出乱码,因为输入“你好”的编码方式你没有指定,在大多数情况下我们在中国大陆地区所用的电脑在输入的“你好”的时候,都会用gbk来编码,但是对服务器而言,是否正确抓到“你好”却不得而知。但是如果更改为 <%@ page contentType="text/html;charset=utf-8" pageEncoding="GBK"%>这样就服务器一定会是正确抓到“你好”了,这就是为什么有两个不同的指令设定,和两次不同的编码过程。

明白了这三个阶段和两次编码过程,那么在编程的时候,JSP网页中、数据库中、Web服务器中,关于一些字符的设定就会很清楚,要不然,会设来设去,字符跟着转来转去,最终没没转出过正确的来,记住一点,万变不离其踪,只要把最本质的东西搞明白,不管怎么变都不会有太大的问题。

近期笔者会把数据库与网页交互过程中出现的一些乱码问题、字符集问题、编码规则问题再整理下,在下一篇文章中与读者见面。







 



推荐:Java Web学习总结(9)——servlet和Jsp生命周期解读

一、servlet的工作工程       Servlet是运行在Servlet容器(有时候也叫Servlet引擎,是web服务器和应用程序服务器的一部分,用于在发送的请求和响应之上提供网络

Servlet和JSP编码问题   字节流:  1.得到OutputStream  字节流   OutputStream os = response.getOutputStream();   用默认编码输出数据,就是本地编码GBK   os.write("李赛是一个正直的男人".g

相关阅读排行


用户评论

游客

相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。