作者归档:Rick

Oracle CHAR,VARCHAR,VARCHAR2,nvarchar类型的区别与使用

1.varchar,nvarchar, 

四个类型都属于变长字符类型, varchar和varchar2的区别在与后者把所有字符都占两字节,前者只对汉字和全角等字符占两字节。 nvarchar和nvarchar2的区别和上面一样,   与上面区别在于是根据Unicode   标准所进行的定义的类型,通常用于支持多国语言类似系统的定义。 

1.char 

char的长度是固定的,比如说,你定义了char(20),即使你你插入abc,不足二十个字节,数据库也会在abc后面自动加上17个空格,以补足二十个字节; 

char是区分中英文的,中文在char中占两个字节,而英文占一个,所以char(20)你只能存20个字母或10个汉字。 

char适用于长度比较固定的,一般不含中文的情况 

2.varchar/varchar2 

varchar是长度不固定的,比如说,你定义了varchar(20),当你插入abc,则在数据库中只占3个字节。 

varchar同样区分中英文,这点同char。 

varchar2基本上等同于varchar,它是oracle自己定义的一个非工业标准varchar,不同在于,varchar2用null代替varchar的空字符串 

varchar/varchar2适用于长度不固定的,一般不含中文的情况 

3.nvarchar/nvarchar2 

nvarchar和nvarchar2是长度不固定的 

nvarchar不区分中英文,比如说:你定义了nvarchar(20),你可以存入20个英文字母/汉字或中英文组合,这个20定义的是字符数而不是字节数 

nvarchar2基本上等同于nvarchar,不同在于nvarchar2中存的英文字母也占两个字节 

nvarchar/nvarchar2适用于存放中文 

char [ ( n ) ] 

    固定长度,非 Unicode 字符数据,长度为 n 个字节。n 的取值范围为 1 至 8,000,存储大小是 n 个字节。 

varchar [ ( n | max ) ] 

    可变长度,非 Unicode 字符数据。n 的取值范围为 1 至 8,000。max 指示最大存储大小是 2^31-1 个字节。存储大小是输入数据的实际长度加 2 个字节,用于反映存储的数据的长度。所输入数据的长度可以为 0 个字符。 

    * 如果列数据项的大小一致,则使用 char。 

    * 如果列数据项的大小差异相当大,则使用 varchar。 

    * 如果列数据项大小相差很大,而且大小可能超过 8,000 字节,请使用 varchar(max)。 

如果未在数据定义或变量声明语句中char 或 varchar 数据类型指定 n,则默认长度为 1。如果在使用 CAST 和 CONVERT 函数时char 或 varchar 数据类型未指定 n,则默认长度为 30。 

当执行 CREATE TABLE 或 ALTER TABLE 时,如果 SET ANSI_PADDING 为 OFF,则定义为 NULL 的 char 列将作为 varchar 处理。 

另外帮助理解的,只供参考:转自http://www.51testing.com/?uid-258885-action-viewspace-itemid-141197 

也可参照学习http://ce.sysu.edu.cn/garden/dispbbs.asp?boardid=26&ID=8774&replyID=18180&skin=1 

1.NULL值(空值)。 

     a. char列的NULL值占用存储空间。 

     b. varcahr列的NULL值不占用存储空间。 

     c. 插入同样数量的NULL值,varchar列的插入效率明显高出char列。 

2.插入数据 

    无论插入数据涉及的列是否建立索引,char的效率都明显低于varchar。 

3. 更新数据 

     如果更新的列上未建立索引,则char的效率低于varchar,差异不大;建立索引的话,效率较高。 

4. 修改结构 

     a. 无论增加或是删除的列的类型是char还是varchar,操作都能较快的完成,而且效率上没有什么差异。 

     b. 对于增加列的宽度而言,char与varchar有非常明显的效率差异,修改varcahr列基本上不花费时间,而修改char列需要花费很长的时间。 

5.数据检索 

     无论是否通过索引,varchar类型的数据检索略优于char的扫描。 

选择char还是选择varchar的建议 

    1.适宜于char的情况: 

     a. 列中的各行数据长度基本一致,长度变化不超过50字节; 

     b. 数据变更频繁,数据检索的需求较少。 

     c. 列的长度不会变化,修改char类型列的宽度的代价比较大。 

     d. 列中不会出现大量的NULL值。 

     e. 列上不需要建立过多的索引,过多的索引对char列的数据变更影响较大。 

    2.适宜于varchar的情况; 

     a. 列中的各行数据的长度差异比较大。 

     b. 列中数据的更新非常少,但查询非常频繁。 

     c. 列中经常没有数据,为NULL值或为空值 

nchar [ ( n ) ] 

    n 个字符的固定长度的 Unicode 字符数据。n 值必须在 1 到 4,000 之间(含)。存储大小为两倍 n 字节。 

nvarchar [ ( n | max ) ] 

    可变长度 Unicode 字符数据。n 值在 1 到 4,000 之间(含)。max 指示最大存储大小为 2^31-1 字节。存储大小是所输入字符个数的两倍 + 2 个字节。所输入数据的长度可以为 0 个字符。 

注释 

如果没有在数据定义或变量声明语句中指定 n,则默认长度为 1。如果没有使用 CAST 函数指定 n,则默认长度为 30。 

如果列数据项的大小可能相同,请使用 nchar。 

如果列数据项的大小可能差异很大,请使用 nvarchar。 

sysname 是系统提供的用户定义数据类型,除了不可为空值外,在功能上与 nvarchar(128) 相同。sysname 用于引用数据库对象名。 

为使用 nchar 或 nvarchar 的对象分配的是默认的数据库排序规则,但可使用 COLLATE 子句分配特定的排序规则。 

SET ANSI_PADDING ON 永远适用于 nchar 和 nvarchar。SET ANSI_PADDING OFF 不适用于 nchar 或 nvarchar 数据类型。 

在Oracle中CHAR,NCHAR,VARCHAR,VARCHAR2,NVARCHAR2这五种类型的区别 

1.CHAR(size)和VARCHAR(size)的区别 

    CHAR为定长的字段,最大长度为2K字节; 

    VARCHAR为可变长的字段,最大长度为4K字节; 

2.CHAR(size)和NCHAR(size)的区别 

    CHAR如果存放字母数字占1个字节,存放GBK编码的汉字存放2个字节,存放UTF-8编码的汉字占用3个字节; 

    NCHAR根据所选字符集来定义存放字符的占用字节数,一般都为2个字节存放一个字符(不管字符或者汉字) 

3.VARCHAR(size)和VARCHAR2(size)的区别 

    在现在的版本中,两者是没有区别的;最大长度为4K字节;推荐使用VARCHAR2; 

4.VARCHAR2(size)和NVARCHAR2(size)的区别 

    最大长度为4K字节,区别同CHAR与NCHAR的区别;(如果数据库字符集长度是2,则NVARCHAR2最大为2K) 

5.共同特性 

    当执行insert的时候,插入的值为”,则转变成null,即insert … values(”) <=> insert … values(null) 

    搜索的条件须用where xx is null 

6.例子 

    比如有一个性别字段,里面存放“男,女”的其中一个值,两种常用选择 

        CHAR(2)    和 NCHAR(1)


转载自http://winie.iteye.com/blog/540340

ORACLE详解:数据库名、实例名、ORACLE_SID、数据库域名、全局数据库名、服务名(转)

数据库名、实例名、ORACLE_SID、数据库域名、全局数据库名、服务名 

数据库名、实例名、数据库域名、全局数据库名、服务名 ,

这是几个令很多初学者容易混淆的概念。相信很多初学者都与我一样被标题上这些个概念搞得一头雾水。我们现在就来把它们弄个明白。

一、数据库名

什么是数据库名?
数据库名就是一个数据库的标识,就像人的身份证号一样。他用参数DB_NAME表示,如果一台机器上装了多个数据库,那么每一个数据库都有一个数据库名。在数据库安装或创建完成之后,参数DB_NAME被写入参数文件之中。格式如下:
DB_NAME=myorcl

在创建数据库时就应考虑好数据库名,并且在创建完数据库之后,数据库名不宜修改,即使要修改也会很麻烦。因为,数据库名还被写入控制文件中,控制文件是以二进制型式存储的,用户无法修改控制文件的内容。假设用户修改了参数文件中的数据库名,即修改DB_NAME的值。但是在Oracle启动时,由于参数文件中的DB_NAME与控制文件中的数据库名不一致,导致数据库启动失败,将返回ORA-01103错误。

数据库名的作用
数据库名是在安装数据库、创建新的数据库、创建数据库控制文件、修改数据结构、备份与恢复数据库时都需要使用到的。
有很多Oracle安装文件目录是与数据库名相关的,如:
winnt: d:\oracle\product\10.1.0\oradata\DB_NAME\…
Unix: /home/app/oracle/product/10.1.0/oradata/DB_NAME/…
pfile:
winnt: d:\oracle\product\10.1.0\admin\DB_NAME\pfile\ini.ora
Unix: /home/app/oracle/product/10.1.0/admin/DB_NAME/pfile/init$ORACLE_SID.ora
跟踪文件目录:
winnt: /home/app/oracle/product/10.1.0/admin/DB_NAME/bdump/…
另外,在创建数据时,careate database命令中的数据库名也要与参数文件中DB_NAME参数的值一致,否则将产生错误。
同样,修改数据库结构的语句alter database, 当然也要指出要修改的数据库的名称。
如果控制文件损坏或丢失,数据库将不能加载,这时要重新创建控制文件,方法是以nomount方式启动实例,然后以create controlfile命令创建控制文件,当然这个命令中也是指指DB_NAME。
还有在备份或恢复数据库时,都需要用到数据库名。
总之,数据库名很重要,要准确理解它的作用。

查询当前数据名
方法一:select name from v$database;
方法二:show parameter db
方法三:查看参数文件。

修改数据库名
前面建议:应在创建数据库时就确定好数据库名,数据库名不应作修改,因为修改数据库名是一件比较复杂的事情。那么现在就来说明一下,如何在已创建数据之后,修改数据库名。步骤如下:
1.关闭数据库。
2.修改数据库参数文件中的DB_NAME参数的值为新的数据库名。
3.以NOMOUNT方式启动实例,修建控制文件(有关创建控制文件的命令语法,请参考oracle文档)

二、数据库实例名

什么是数据库实例名?
数据库实例名是用于和操作系统进行联系的标识,就是说数据库和操作系统之间的交互用的是数据库实例名。实例名也被写入参数文件中,该参数为instance_name,在winnt平台中,实例名同时也被写入注册表。
数据库名和实例名可以相同也可以不同。
在一般情况下,数据库名和实例名是一对一的关系,但如果在oracle并行服务器架构(即oracle实时应用集群)中,数据库名和实例名是一对多的关系。这一点在第一篇中已有图例说明。

查询当前数据库实例名
方法一:select instance_name from v$instance;
方法二:show parameter instance
方法三:在参数文件中查询。

数据库实例名与ORACLE_SID
虽然两者都表是oracle实例,但两者是有区别的。instance_name是oracle数据库参数。而ORACLE_SID是操作系统的环境变量。ORACLD_SID用于与操作系统交互,也就是说,从操作系统的角度访问实例名,必须通过ORACLE_SID。在winnt不台,ORACLE_SID还需存在于注册表中。
且ORACLE_SID必须与instance_name的值一致,否则,你将会收到一个错误,在unix平台,是“ORACLE not available”,在winnt平台,是“TNS:协议适配器错误”。

数据库实例名与网络连接
数据库实例名除了与操作系统交互外,还用于网络连接的oracle服务器标识。当你配置oracle主机连接串的时候,就需要指定实例名。当然8i以后版本的网络组件要求使用的是服务名SERVICE_NAME。这个概念接下来说明 。

三、数据库域名

什么是数据库域名?
在分布工数据库系统中,不同版本的数据库服务器之间,不论运行的操作系统是unix或是windows,各服务器之间都可以通过数据库链路进行远程复制,数据库域名主要用于oracle分布式环境中的复制。举例说明如:
全国交通运政系统的分布式数据库,其中:
福建节点: fj.jtyz
福建厦门节点: xm.fj.jtyz
江西: jx.jtyz
江西上饶:sr.jx.jtyz
这就是数据库域名。
数据库域名在存在于参数文件中,他的参数是db_domain.

查询数据库域名
方法一:select value from v$parameter where name = ‘db_domain';
方法二:show parameter domain
方法三:在参数文件中查询。

全局数据库名
全局数据库名=数据库名+数据库域名,如前述福建节点的全局数据库名是:oradb.fj.jtyz

四、数据库服务名

什么是数据库服务名?
从oracle9i版本开始,引入了一个新的参数,即数据库服务名。参数名是SERVICE_NAME。
如果数据库有域名,则数据库服务名就是全局数据库名;否则,数据库服务名与数据库名相同。

查询数据库服务名
方法一:select value from v$parameter where name = ‘service_name';
方法二:show parameter service_name
方法三:在参数文件中查询。

数据库服务名与网络连接
从oracle8i开始的oracle网络组件,数据库与客户端的连接主机串使用数据库服务名。之前用的是ORACLE_SID,即数据库实例名。

MetaQ使用范例

MetaQ下载地址:http://fnil.net/downloads/index.html

ZooKeeper下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/

入门学习地址:https://github.com/killme2008/Metamorphosis/wiki

消息中间件

    为了考虑web架构的伸缩性,扩展性及重用性,目前许多大型门户网站及大平台,如淘宝网,天猫网,京东商城,当当网,及腾讯,Facebook等电商或社交网站,均大量采用中间件的设计,中间件又细分为业务流中间件,服务中间件,消息队列中间件,缓存中间件,数据库中间件,可以这样说,中间件在整个web架构设计中占有十分重要的地位,中间件设计的好坏直接影响到大型门户网站架构水平的高低和优劣。由于时间和精力的关系,这里阿堂主要是分享下对消息队列中间件的应用认识和理解。

    消息中间件在web分布式架构设计及性能优化方面有着非常重要的地位,目前,在很多大型网门户网站和商业大平台都有及为广泛的应用,如淘宝网,天猫网,京东商城,当当网,及腾讯,Facebook等电商或社交网站,都在大量使用。常见的开源消息中间件有mom4j,OpenJMS,UBerMQ,Hermes JMS, Presumo,JORAM,JMS4Spread,Open Message Queue,FFMQ,MQSSave/MQSLoad,HornetQ,Apache Qpid,Spring AMQP,Kafka,play-rabbitmq,队列消息系统 FQueue,ActiveMQ,Somnifugi ,MantaRay,MetaQ等

消息队列的相关概念

   为了了解MetaQ的使用,下面让我们先要了解和理解其中的一些重要概念解释。
   消息生产者
        也称为Message Producer,一般简称为producer,负责产生消息并发送消息到meta服务器。
   消息消费者
        也称为Message Consumer,一般简称为consumer,负责消息的消费,meta采用pull模型,由消费者主动从meta服务器拉取数据并解析成消息并消费。
    Topic
         消息的主题,由用户定义并在服务端配置。producer发送消息到某个topic下,consumer从某个topic下  消费消息。
    分区(partition)
         同一个topic下面还分为多个分区,如meta-test这个topic我们可以分为10个分区,分别有两台服务器提供,那么可能每台服务器提供5个分区,假设服务器id分别为0和1,则所有分区为0-0、0-1、0-2、0-3、0-4、1-0、1-1、1-2、1-3、1-4。
分区跟消费者的负载均衡机制有很大关系,具体见集群和负载均衡。
      Message
           消息,负载用户数据并在生产者、服务端和消费者之间传输。
      Broker
就是meta的服务端或者说服务器,在消息中间件中也通常称为broker。
      消费者分组(Group)
消费者可以是多个消费者共同消费一个topic下的消息,每个消费者消费部分消息。这些消费者就组成一个分组,拥有同一个分组名称,通常也称为消费者集群
      Offset
      消息在broker上的每个分区都是组织成一个文件列表,消费者拉取数据需要知道数据在文件中的偏移量,这个偏移量就是所谓offset。Offset是绝对偏移量,服务器会将offset转化为具体文件的相对偏移量。详细内容参见#消息的存储结构

MetaQ简介

    MetaQ(全称Metamorphosis)是一个高性能、高可用、可扩展的分布式消息中间件,思路起源于LinkedIn的Kafka,但并不是Kafka的一个Copy。MetaQ具有消息存储顺序写、吞吐量大和支持本地和XA事务等特性,适用于大吞吐量、顺序消息、广播和日志数据传输等场景,目前在淘宝和支付宝有着广泛的应用。
MetaQ是一款完全的队列模型消息中间件,服务器使用Java语言编写,可在多种软硬件平台上部署。客户端支持Java、C++编程语言。单台服务器可支持1万以上个消息队列,通过扩容服务器,队列数几乎可任意横向扩展。每个队列都是持久化、长度无限(取决于磁盘空间大小)、并且可从队列任意位置开始消费。
     它具有的优势如下
     (1)文本协议设计,非常透明,支持类似memcached stats的协议来监控broker。
     (2)纯Java实现,从通讯到存储,从client到server都是重新实现。
     (3)提供事务支持,包括本地事务和XA分布式事务。
     (4)支持HA复制,包括异步复制和同步复制,保证消息的可靠性。
     (5)支持异步发送消息。
     (6)消费消息失败,支持本地恢复。
     (7)多种offset存储支持,数据库、磁盘、zookeeper,可自定义实现。
     (8)支持group commit,提升数据可靠性和吞吐量。(目前kafka已实现)
     (9)支持消息广播模式。
     (10)一系列配套项目:Python/Ruby/C/C++客户端、Twitter Storm的Spout、Tail4j等。

关于消息队列应用的场景,实际上在商业应用中很多网站都在大量应用。阿堂这里随更举几个例子,大家就明白了。12306铁路购票网站,想必大家耳熟能详,去年及以前由于12306网站架构设计不好,经常出现网站并发访问量大时出现网站崩溃,提示服务出错或者说网站根本登录不进去,或者说抢到票时提交没有反应了。今年12306抢票网站就采用“消息队列中间件”来重构了12306网站,采用消息队列的排队机制,抢票时会提示“只有多少张票,目前已经有多少人在排队抢购了,票源不足”,比如说某车次只有10张票了,你前面已经有11人排队抢票了,当然输到你时就没有票了。这样一方面可以缓冲瞬时大量的高并发访问购票,二来对用户来说体验也比较好,因为人家是在你前面排队了,先来先得嘛。还有小米官网抢购手机时,也是用的这种“消息队列中间件”设计,先抢先得。还有一些电商平台的“秒杀抢购”,都是在使用“消息队列中间件”来设计的web架构,这样就可以解决瞬时涌入的大量高并发访问造成的网站压力。看到上面阿堂的举例,大家应该对“消息队列中间件”在大型网站中的重要性有了一个比较感官的认识了。

测试MetaQ

  1.   下载ZooKeeper,修改相关配置文件

    (新的版本的已经提供了Windows下的启动)单机安装非常简单,只要获取到 Zookeeper 的压缩包并解压到某个目录如:/home/zookeeper-3.2.2 下,Zookeeper 的启动脚本在 bin 目录下,Linux 下的启动脚本是 zkServer.sh,在 3.2.2 这个版本 Zookeeper 没有提供 windows 下的启动脚本,所以要想在 windows 下启动 Zookeeper 要自己手工写一个,如清单 1 所示:

 setlocal 
 set ZOOCFGDIR=%~dp0%..\conf 
 set ZOO_LOG_DIR=%~dp0%.. 
 set ZOO_LOG4J_PROP=INFO,CONSOLE 
 set CLASSPATH=%ZOOCFGDIR% 

 set CLASSPATH=%~dp0..\*;%~dp0..\lib\*;%CLASSPATH% 
 set CLASSPATH=%~dp0..\build\classes;%~dp0..\build\lib\*;%CLASSPATH% 
 set ZOOCFG=%ZOOCFGDIR%\zoo.cfg 
 set ZOOMAIN=org.apache.zookeeper.server.ZooKeeperServerMain 
 java "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" 
 -cp "%CLASSPATH%" %ZOOMAIN% "%ZOOCFG%" %* 
 endlocal

    在你执行启动脚本之前,还有几个基本的配置项需要配置一下,Zookeeper 的配置文件在 conf 目录下,这个目录下有 zoo_sample.cfg 和 log4j.properties,你需要做的就是将 zoo_sample.cfg 改名为 zoo.cfg,因为 Zookeeper 在启动时会找这个文件作为默认配置文件。下面详细介绍一下,这个配置文件中各个配置项的意义。

 tickTime=2000 
 dataDir=D:/devtools/zookeeper-3.2.2/build 
 clientPort=2181
  • tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
  • dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  • clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

当这些配置项配置好后,你现在就可以启动 Zookeeper 了,启动后要检查 Zookeeper 是否已经在服务,可以通过 netstat – ano 命令查看是否有你配置的 clientPort 端口号在监听服务。

        点击bin/zkServer.cmd

更多安装信息:http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

  1. 安装启动metaq服务器

         点击bin/metaServer.bat

  1. 编写测试代码

      Producer.java

public class Producer {
    public static void main(String[] args) throws Exception {
        final MetaClientConfig metaClientConfig = new MetaClientConfig();
        final ZKConfig zkConfig = new ZKConfig();
        //设置zookeeper地址
        zkConfig.zkConnect = "127.0.0.1:2181";
        metaClientConfig.setZkConfig(zkConfig);
        // New session factory,强烈建议使用单例
        MessageSessionFactory sessionFactory = new MetaMessageSessionFactory(metaClientConfig);
        // create producer,强烈建议使用单例
        MessageProducer producer = sessionFactory.createProducer();
        // publish topic
        final String topic = "test";
        producer.publish(topic);

        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while ((line = reader.readLine()) != null) {
            // send message
            SendResult sendResult = producer.sendMessage(new Message(topic, line.getBytes()));
            // check result
            if (!sendResult.isSuccess()) {
                System.err.println("Send message failed,error message:" + sendResult.getErrorMessage());
            }
            else {
                System.out.println("Send message successfully,sent to " + sendResult.getPartition());
            }
        }
    }

}

AsyncConsumer.java

public class AsyncConsumer {
    public static void main(String[] args) throws Exception {
        final MetaClientConfig metaClientConfig = new MetaClientConfig();
        final ZKConfig zkConfig = new ZKConfig();
        //设置zookeeper地址
        zkConfig.zkConnect = "127.0.0.1:2181";
        metaClientConfig.setZkConfig(zkConfig);
        // New session factory,强烈建议使用单例
        MessageSessionFactory sessionFactory = new MetaMessageSessionFactory(metaClientConfig);
        // subscribed topic
        final String topic = "test";
        // consumer group
        final String group = "meta-example";
        // create consumer,强烈建议使用单例
        MessageConsumer consumer = sessionFactory.createConsumer(new ConsumerConfig(group));
        // subscribe topic
        consumer.subscribe(topic, 1024 * 1024, new MessageListener() {

            public void recieveMessages(Message message) {
                System.out.println("Receive message " + new String(message.getData()));
            }


            public Executor getExecutor() {
                // Thread pool to process messages,maybe null.
                return null;
            }
        });
        // complete subscribe
        consumer.completeSubscribe();
    }
}

复杂JSON提交SpringMVC参数接收

简单json:

{"username":"zhangsan"}

复杂json

{
[{"username":"zhangsan"},
{"username":"lisi"}
]
}

简单json提交数据

前端:

var param = {"username":"zhangsan"};   

 $.ajax({
        type : 'POST',
        url : '${pageContext.request.contextPath}/shop/sku/skumgr/',
        data: param,
        success : function(result) {
               
        }
    });

controller:

 public String getUserData(User user) {

 }

复杂jsont提交数据

前端:

var param = {"users":[
{"username":"zhangsan"},
{"username":"lisi"}
]
}
    $.ajax({
        type : 'POST',
        url : '${pageContext.request.contextPath}/shop/sku/skumgr/', 
        contentType : "application/json",
        data: JSON.stringify(param), 
        success : function(result) {
                
        }
    });

controller:

public class VO {
   List<User> users;
   getter();
   setter();
}

 public void updateSku(@RequestBody VO vo) {

 }

Json数组映射到java的List或者数组

至此:有可能会报错,media not support,那就需要Spring对Content-Type支持

    <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>text/html;charset=UTF-8</value>
                <value>application/json;charset=UTF-8</value>
            </list>
        </property>
    </bean>

相关资料:

http://www.cnblogs.com/dayou123123/p/3443939.html

  •  Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些Asp网页点击的结果却是下载到的一个文件或一张图片的原因。

 ContentType属性指定响应的 HTTP内容类型。如果未指定 ContentType,默认为TEXT/HTML。

  •  ajax请求默认是application/x-www-form-urlencoded.Form Data
  •  get方式,参数是跟在url后边,与Content-Type无关。
  •  如果Content-Type : “application/json; charset=utf-8″,Request Paload提交JSON字符串。

JSON对象与字符串的转换

什么是JSON

  JSON(JavaScript Object Notation)是一种优美的JavaScript对象创建方法。JSON也是一种轻量级数据交换格式。JSON非常易于人阅读与编写,同时利于机器解析与生成。JSON是在AJAX中代替XML交换数据的更佳方案。

JSON格式与语法

var jsonobject= {

      //对象内的属性语法(属性名与属性值是成对出现的)

      propertyname:value,

      //对象内的函数语法(函数名与函数内容是成对出现的)

      functionname:function(){…;}

};

jsonobject — JSON对象名称

propertyname — 属性名称

functionname — 函数名称

一对大括号,括起多个”名称/值”的集合

JSON使用”名称/值”对的集合表示,也可以被理解为数组(Array)

属性名或函数名可以是任意字符串,甚至是空字符串(见下面示例)

逗号用于隔开每对”名称/值”对

标准JSON字符串

{test: 1}  (test 没有包围双引号)

{‘test': 1} (使用了单引号而不是双引号)

{“test”:1} 合法,key要用双引号表示

字符串格式json转化成json对象有3种方式:

1. js下用eval生成JSON对象  —通过eval() 函数可以将JSON字符串转化为对象。
2. 使用函数方式
3. 使用js的json库或者jQuery提供的js库  — 如果基于安全的考虑的话,最好是使用一个 JSON 解析器。 一个 JSON 解析器将只接受 JSON 文本。所以是更安全的。所谓接收JSON文本,就是合法的json字符串!!!

方法1:正常文本

//方法1:js下用eval生成JSON对象
        function strJsonToJsonByEval(jsonData){  
              var json = eval("(" + jsonData +")");//转换为json对象    
              return json;
        }

方法2:正常文本

//方法2:使用函数方式
      function strJsonToJsonByFunction(jsonData){
           return ( new Function("return "+jsonData) )();
      }

方法3:标准格式的 JSON 字符串

//json2或浏览器自带函数
var param = JSON.parse(data )
/*
jquery-1.9.1.js 提供的方法。
jQuery.parseJSON( json ) 返回: Object
接受一个标准格式的 JSON 字符串,并返回解析后的 JavaScript 对象。

传入格式有误的 JSON 字符串可能导致抛出异常。例如,下面这些 JSON 字符串格式都不对:
{test: 1} (test 没有使用双引号包裹).
{'test': 1} ('test' 用了单引号而不是双引号包裹).
另外,如果你什么都不传入,或者传入空字符串、null、undefined 等,parseJSON 都会返回 null 。如果浏览器原生实现了 JSON.parse, jQuery 则会使用它来解析字符串。
*/

Jquery中$.data()

结合html,经常做控件配置,如EasyUI

html

<input id="test" data-options="min:0,precision:2">

javascript

$(function() { var data = "{" + $("#test").data("options") + "}";
  alert(strJsonToJsonByFunction(data).min);
});

由于不是标准JSON格式,只能用方法1、2解析。

其他示例

$("#btn1").click(function(){
$("div").data("greeting", "Hello World");
});
$("#btn2").click(function(){
alert($("div").data("greeting"));
});

在执行过程中,存取临时数据,用处很大。