`
bjrobin
  • 浏览: 13628 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

尚学堂.张志宇.乱码分析_07_form表单存储格式.doc

    博客分类:
  • java
 
阅读更多

 

1       结论

l  req.setCharacterEncoding( "gbk" );

n  含义是取上一个页面的参数,按照 gbk 进行解码

n  tomcat 取参数默认按照 iso-8859-1 进行解码

l  resp.setContentType( "text/html;charset=gbk" );

n  含义是发送内容到客户端浏览器,按照 gbk 进行编码

n  tomcat 发送内容到客户端浏览器,默认按照 iso-8859-1 进行编码

 

 

场景 1

场景 2

场景 3

 

 

 

form 表单存为什么格式

ansi

ansi

utf-8

 

 

 

form 表单提交方式

post

post

post

 

 

 

Servlet resp.setContentType

-

charset=gbk

charset=gbk

 

 

 

Servlet req.setCharacterEncoding

-

gbk

gbk

 

 

 

是否有乱码

没有乱码

没有乱码

鎴戜滑

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2       场景 1

form.html

<form action="/my/servlet/TestServlet" method="post" >

    <input name="username">

    <input type="submit" value=" 提交 ">

</form>

 

TestServlet.java

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 TestServlet extends HttpServlet {

 

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)

           throws ServletException, IOException {

       PrintWriter out = resp.getWriter();

        String username = req.getParameter( "username" );

       System. out .println(username);

       out .println(username);

       out .close();

    }

 

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse resp)

           throws ServletException, IOException {

       doGet(req, resp);

    }

}

 

web.xml

    <servlet>

      <servlet-name>TestServlet</servlet-name>

      <servlet-class>TestServlet</servlet-class>

    </servlet>

 

    <servlet-mapping>

        <servlet-name>TestServlet</servlet-name> 

        <url-pattern>/servlet/TestServlet</url-pattern>

    </servlet-mapping>

 

访问这个地址 http://127.0.0.1/my/form.html

输入“我们”然后提交。我们看到的是正确的中文,没有乱码

2.1   分析

 

下面通过例子详细说明为什么没有乱码。

虽然场景 1 没有乱码。但不是最终的解决办法。

因为页面本身的中文会有乱码。

 

// 重要结论

//jvm 只能表示 unicode 收录的字符们

//jvm 在内存里用 utf-16 编码表示一个字符

//System.out.println 先按照操作系统默认的编码来编码,得到的字节们传到 console console 再按系统默认的编码解码

//zhongwen.getBytes("GBK")--> 编码

//new String(zhongwen.getBytes("GBK"), "iso8859-1");--> 解码

//tomcat 取参数默认按照 iso-8859-1 进行解码

//tomcat 发送内容到客户端浏览器,默认按照 iso-8859-1 进行编码

 

// 字符 " " gbk 编码: ced2

// 字符 " " utf-16 编码: 6211

// 字符 " " utf-8 编码: e6 88 91

public class TestBB {

 

    public static void main(String args[]) throws Exception {

       //jvm 在内存里用 utf-16 编码表示一个字符 ,

       // 所以在内存中, zhongwen 这个引用指向的字符串对象包括 2 个字节 62 11

       String zhongwen = " " ;

       //println 方法不会把内存中的 utf-16 编码输出到 console

       // 而是按照系统默认编码( gbk )编码,然后才将 gbk 编码( ced2 )输出到 console

       //cosole 接收 gbk 编码( ced2 ),再按照系统默认编码来解码,显示出正确的中文

       System . out .println(zhongwen);

       //getBytes 方法是编码的意思。

       // 下面验证 " " 这个字符的 gbk 编码是 ced2

       byte [] bytes = zhongwen.getBytes( "gbk" );

       System . out .println( "--------GBK----------" );

       for ( byte b:bytes){

           System . out .format( "%x " ,b);

       }

       System . out .println();

       // 浏览器默认按照 gbk 编码,然后将参数传到服务器

       // 浏览器将以什么编码来提交参数,和 form 表单这个 html 页面的存储方式有关。

       // 如果 form 表单存为 ansi ,即 jbk ,那么提交参数也用 gbk.

      

      

       // 服务器端接收 gbk 编码 2 个字节( ced2 ),默认按照 iso8859-1 解码

       // 所以解码出错误的 2 个字符

       System . out .println( "-------iso8859-1--------" );

       // 2 iso8859-1 字符在内存里表示为 4 个字节: 00 ce 00 d2

       zhongwen = new String(zhongwen.getBytes( "GBK" ), "iso8859-1" );

       //println 方法不会把内存中的 utf-16 编码输出到 console

       // 而是按照系统默认编码( gbk )来编码,得到 2 个字节: 3f 3f , (为什么是 3f 下面会解释)

       // 然后才将这些 gbk 编码输出到 console

       //cosole 再按照系统默认编码来解码,得到 2 ?

       // (因为 ascii 中, ? 就是 3f ,并且 gbk ascii 兼容,所以在 gbk 中, 3f 也是 ?

      

       System . out .println(zhongwen);

      

       // 内存中的 00 ce 表示的那个 iso8859-1 字符在 gbk 中没有收录,所以按照 gbk 编码就会出错。

       // 如果出错,一律编码为 3f ,所以得到 2 3f

       bytes = zhongwen.getBytes( "gbk" );

       for ( byte b:bytes){

           System . out .format( "%x " ,b);

       }

       System . out .println();

      

       // 服务器再按照 iso8859-1 编码,传到客户端浏览器

       bytes = zhongwen.getBytes( "iso8859-1" );

 

       // 最初的 gbk 编码 cede 是不是没有丢?

       // 可见有些编码解码的过程是可逆的。

       // 当然有些编码解码的过程就不可逆。

       for ( byte b:bytes){

           System . out .format( "%x " ,b);

       }

       System . out .println();

      

       // 浏览器得到传过来的字节们,再按照 gbk 解码。得到正确的中文。

       System . out .println( "-------GBK--------" );

       System . out .println( new String(bytes, "GBK" ));

    }

}

 

 

3       场景 2

 

form.html

<form action="/my/servlet/TestServlet" method="post" >

    <input name="username">

    <input type="submit" value=" 提交 ">

</form>

 

TestServlet.java

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 TestServlet extends HttpServlet {

 

    @Override

    protected void doGet(HttpServletRequest req, HttpServletResponse resp)

           throws ServletException, IOException {

       resp.setContentType( "text/html;charset=gbk" );

       PrintWriter out = resp.getWriter();

       req.setCharacterEncoding( "gbk" );

       String username = req.getParameter( "username" );

       System. out .println(username);

       out .println(username);

       out .close();

    }

 

    @Override

    protected void doPost(HttpServletRequest req, HttpServletResponse resp)

           throws ServletException, IOException {

       doGet(req, resp);

    }

}

 

web.xml

    <servlet>

      <servlet-name>TestServlet</servlet-name>

      <servlet-class>TestServlet</servlet-class>

    </servlet>

 

    <servlet-mapping>

        <servlet-name>TestServlet</servlet-name> 

        <url-pattern>/servlet/TestServlet</url-pattern>

    </servlet-mapping>

 

访问这个地址 http://127.0.0.1/my/form.html

输入“我们”然后提交。我们看到的是正确的中文,没有乱码

3.1   分析

浏览器发送 form 表单内容到服务器

服务器接收内容,进行解码

服务器将解码后得到的内容进行编码,再传到浏览器

浏览器接收内容,进行解码

详细内容略。。。。。。

4       场景 3

略。。。。。。

0
1
分享到:
评论

相关推荐

    hadoop大数据培训零基础学习hadoop-北京尚学堂.docx

    hadoop大数据培训零基础学习hadoop-北京尚学堂.docxhadoop大数据培训零基础学习hadoop-北京尚学堂.docx

    尚学堂_Sping_0200_IOC_Introduction

    【标题】:尚学堂_Spring_0200_IOC_Introduction 【内容详解】: Spring 框架是 Java 应用开发中的一个重要组件,它以其依赖注入(Dependency Injection,简称 DI)和控制反转(Inversion of Control,简称 IOC)...

    尚学堂_Spring_0700_IOC_Collections

    这在实际开发中非常重要,因为集合经常被用来存储和处理一组相关的对象。 Spring IoC容器是Spring框架的核心部分,它负责创建对象、管理对象之间的依赖关系,并控制对象的生命周期。IoC通过反转对象的创建过程,将...

    尚学堂_Spring_0300_IOC_Injection_Type

    标题中的"Spring_0300_IOC_Injection_Type"指的是Spring框架中的依赖注入(Dependency Injection,简称DI)机制,特别是关于类型注入(Type Injection)的知识点。在Spring框架中,依赖注入是核心特性之一,它使得...

    尚学堂_Spring_0800_IOC_Auto_Wire

    它们都是@Component的特例,分别对应业务层、数据访问层、存储层和视图层。 7. **基于注解的配置**:Spring允许使用注解替代传统的XML配置,使代码更简洁。比如,可以使用@Service注解标记服务类,然后用@Autowired...

    尚学堂_Spring_0600_IOC_Bean_Scope

    用于存储与用户会话相关的数据。 5. **globalSession**:在portlet环境中,全局session作用域的Bean在整个portlet会话中只创建一次。这在多portlet共享数据时很有用。 在实际应用中,选择合适的Scope对于应用的...

    hadoop大数据培训零基础学习hadoop-北京尚学堂.pdf

    在学习Hadoop大数据技术之前,首先需要理解Hadoop是一个开源框架,主要设计用于处理和存储大量数据。Hadoop的核心组件包括HDFS(分布式文件系统)和MapReduce(一种分布式计算模型)。由于Hadoop是用Java编写的,...

    百战程序员答案javase基础部分

    JavaSE(Java Standard Edition)是Java编程语言的基础部分,涵盖了从基本语法到核心特性的一系列知识。本资料集“百战程序员答案javase基础部分”是针对Java初学者和进阶者的宝贵资源,包含了从第一章到第十章的...

    Java设计模式

    1. 尚学堂_设计模式_责任链_01.avi:这个视频可能从基础开始介绍责任链模式,阐述其核心思想,比如如何定义处理器对象,以及如何建立和配置责任链。 2. 尚学堂_设计模式_责任链_02.avi:接着,可能会讲解如何在实际...

    尚学堂_Spring_0100_模拟Spring

    《尚学堂_Spring_0100_模拟Spring》 在深入探讨Spring框架之前,我们需要先理解Spring的核心理念。Spring是一个开源的Java平台,它主要为构建企业级应用提供了全面的编程和配置模型。它的核心特性是依赖注入...

    尚学堂Java笔记.pdf

    尚学堂Java笔记.pdf 本资源主要讲述Java语言的基础知识和应用,包括J2SDK、JRE、JDK、classpath、path、Java应用程序、递归调用等内容。 一、J2SDK和JRE Java2 Software Development Kit(J2SDK)是Java开发需要...

    java学习顺序.doc

    尚学堂科技提供了相关的视频教程,如"张志宇_SERVLET_JSP_视频教程",还有JDBC、MySQL和Tomcat的使用,这些是构建Web应用的基础。通过"JAVA_网上商城项目视频讲解"这样的实战教程,可以提高实际操作能力。 深入J2EE...

    Lucene_ShangXueTang.rar_文章/文档_Java_

    《尚学堂全文检索系统——深入理解Lucene》 在IT领域,搜索引擎技术是不可或缺的一部分,尤其是在大数据时代,如何高效地从海量信息中快速找到所需内容成为了一项挑战。Java平台上的Lucene,作为一款强大的开源全文...

    全网最新尚学堂hadoop大数据视频教程.doc

    4. **Hive**:是一个数据仓库工具,提供SQL查询接口,使非程序员也能访问和分析存储在Hadoop中的数据。 5. **Pig**:是一个高层的数据流语言和执行框架,适合于大数据集的并行处理。 6. **HBase**:是一个分布式的、...

    hibernate资料3

    接着,"008_尚学堂马士兵_Java视频教程_Hibernate3.3.2_常见OR框架简介.avi"中,马士兵老师会对比分析其他的ORM框架,如iBatis等,帮助你了解它们与Hibernate的区别和联系,进一步巩固对Hibernate的理解。...

    441769547180350是男人就撑20秒【尚学堂】.zip

    441769547180350是男人就撑20秒【尚学堂】.zip

    1.【尚学堂】全新2022版WEB前端HTML5.zip

    【尚学堂】全新2022版WEB前端HTML5.zip是一个专门针对Web前端开发的教程压缩包,尤其聚焦于HTML5技术。HTML5是超文本标记语言(HTML)的最新版本,它在原有的HTML4基础上引入了众多新的特性和改进,以适应现代互联网...

    JAVA视频学习顺序

    - **尚学堂科技_张志宇_SERVLET_JSP_视频教程_第一版**:介绍了Servlet和JSP的基础知识,这是构建动态网页的基础。 - **尚学堂科技_马士兵_JAVA_系列视频教程_BBS_2007**:通过实际案例,让学员了解如何运用所学知识...

    hadoop大数据培训零基础学习hadoop-北京尚学堂整理.pdf

    Hadoop是一个开源的分布式计算框架,由Apache基金会维护,专门设计用于处理和存储大规模数据。Hadoop基于Java语言实现,它允许应用程序在大量的计算机节点(集群)上并行处理数据,极大地提高了数据处理效率。对于想...

Global site tag (gtag.js) - Google Analytics