Http协议中规定,数据的传输采用字节编码方式,即无论浏览器提交的数据所包含的中文是什么字符编码格式,一旦由服务器经过Http协议传输,则这些数据均将以字节的形式上传给服务器,因为Http协议的底层使用的时TCP传输协议。TCP(Transmission Control Protocol):传输控制协议,是一种面向连接的,可靠的,基于字节流的,端对端的通信协议,在请求中,这些字节均以%开头,以十六进制的形式出现,比如:%7A%9B%3D。
当用户通过表单向浏览器提交一个包含UTF-8编码格式的两个字的中文请求时,浏览器会将这两个中文字符变为六个字节(一般一个UTF-8汉字占用三个字节),形如:%7A%9B%3D%7A%9B%3D,并上传给Tomcat服务器,Tomcat接收到这六个字节,并不知道这六个字节采用的是什么字符编码。而自身默认的编码格式为ISO8859-1,所以会将这六个字节以ISO8859-1的格式进行编码,编码后在控制台显示乱码。
Http请求与响应包含内容: 请求:请求行,请求头,空行,请求正文(如果是GET方法提交,请求参数会附加到请求行,请求正文就会没内容;如果是POST方法提交,请求参数显示到请求正文中) 响应:状态行,响应头,空行,响应正文
1,POST提交时中文乱码问题的解决
setCharacterEncoding()方法设置请求正文中的字符编码,可以解决POST提交时的中文乱码问题,但无法解决GET提交时的中文乱码 req.setCharacterEncoding(“UTF-8”);
2,GET提交时中文乱码问题的解决 第一种方式:在Tomcat服务器下的server.xml文件中找到`
并将它改为:
该种方式并不适用,因为Tomacat里有许多虚拟主机,发布着许多应用,修改服务器的server.xml就必须重启服务器,会导致所有应用重启。
第二种方式: 通过字符串按原字符编码打散成字节数组,再将字节数组按指定字符编码组装成字符串 缺点:当出现较多的中文乱码问题时比较麻烦。
package com.ixat.servlets;//GET提交时中文乱码问题的解决import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class RegisterServlet extends HttpServlet {public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException ,IOException{//对于请求中的中文乱码问题的万能解决方案//这里接收到的name,其字符编码为ISO8850-1String name = req.getParameter("name");//通过表单提交的参数//打散:将name字符串按照原字符编码进行打散byte[] bytes=name.getBytes("ISO8859-1");//组装:将bytes字节数组按照指定字符编码组装,组装为Stringname=new String(bytes,"UTF-8");String age = req.getParameter("age");System.out.println("name="+name);System.out.println("age="+age);}}标准输出流
需要获取客户端提交请求的相关信息,需要从HttpServletRequest对象中获取,需要向客户端的发送数据,则需要通过HttpServletResponse对象来完成
ServletResponse接口的getWriter()方法,用于获取一个输出流对象PrintWriter,该输出流对象专门向客户端浏览器输出字符数据,称为标准输出流。
package com.ixat.servlets;//Response的PrintWriterimport java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class SomeServlet extends HttpServlet {public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{//获取标准输出流PrintWriter pw=res.getWriter();//向标准输出流中写入数据,那么客户端浏览器会直接看到这些数据pw.print("abc");pw.println("asd");pw.write("mno");pw.append("rst");//对标准输出流的关闭,可以不关闭,因为系统会在请求和响应结束的时候,req和res对象销毁,在销毁响应对象时会自动将标准输出流关闭//pw.close();过滤器要对标准输出流进行处理,不必关闭}}3,ServletResponse的中文乱码问题的解决
res.setContentType(“text/html;charset=UTF-8”);
package com.ixat.servlets;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class SomeServlet extends HttpServlet {public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{//res.setCharacterEncoding("UTF-8"); //address闄曡タ瑗垮畨 设置后出现的乱码问题 //设置相应的MIME类型(video/mp4,image/jpg等也属于MIME类型)res.setContentType("text/html;charset=UTF-8");//其中可以指定MIME的字符编码,即响应体的字符编码/*res.setContentType("text/html;charset=ISO8859-1");res.setCharacterEncoding("UTF-8");此方法的使用前提:之前必须要先使用setContentPath()方法, 作用:用于修改ContentType的MIME类型字符编码*///获取标准输出流PrintWriter pw=res.getWriter();//res.setCharacterEncoding("UTF-8"); //不能设置在标准输出流对象之后,无效。pw.write("address");pw.write("中国上海");}}