JSON学习笔记
JsonResponseUtil 和JsonUtil,这两个工具类都实现接口InitializingBean!
Spring的InitializingBean和init-method
1、Spring在设置完一个bean所有的属性后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。(这个接口只有一个方法 afterPropertiesSet,这个方法会在 Bean 完成属性设置之后执行)另外,如果bean是单例的,则afterPropertiesSet方法只会被调用一次;否则每次创建bean时afterPropertiesSet方法都会被重新调用.
Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。通常情况下不建议直接实现InitializingBean,而是用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法,这可以在一个bean的配置文件中通过init-method声明:
spring要求这个init-method方法是一个无参数的方法
如果一个bean同时实现了这两种方式的初始化配置,则spring会先调用afterPropertiesSet方法,然后通过反射调用init-method,任何一个方法出错都会导致spring创建bean失败.如果afterPropertiesSet方法调用失败,也不会再继续执行init-mehtod方法.
2、实现org.springframework.beans.factory.InitializingBean接口允许一个bean在他的所有必需的属性被BeanFactory设置后,来执行初始化的工作。当然可以使用init-method来取代实现这个接口,以让应用不与spring产生耦合。如果一个bean既实现了InitializingBean,又指定了init-method,则spring会先调InitializingBean的方法,在调init-method指定的方法。
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于阅读和编写。同时也易于机器解析和生成。它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
JSON建构于两种结构:
• “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
• 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
JSON具有以下这些形式:
对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
数组是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
值(value)可以是双引号括起来的字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)。这些结构可以嵌套。
字符串(string)是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。
字符串(string)与C或者Java的字符串非常相似。
数值(number)也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。
空白可以加入到任何符号之间。 以下描述了完整的语言。
P17系统的实现说明:
Web层的调用类JsonResponseUtil.java
工具类:JsonUtil.java
原理是通过工具类JsonUtil进行对象装换,全部转为字符串,通过调用类JsonResponseUtil将字符串写入response,在通过Ajax回调。
在设置过程中需要设置response的contentType、charsetName!这两个字段不用指定在代码中,配置在xml文件中
通过Spring注入:
设置自定义的Json转换时的处理类
JsonConfig类是用于配置这些规则的,P17使用了时间格式的显示规则,使用方法registerJsonValueProcessor注册JsonValueProcessor,使用JsonValueProcessor处理Bean对象的属性值的转换
registerJsonValueProcessor(propertyType, jsonValueProcessor),第一参数是类的类型(我的理解是基本类型的包装类),第二个是JsonValueProcessor接口
说明:两个时间格式类:DateJsonValueProcessor和TimeStampJsonValueProcessor,通过上面的xml,并通过Spring初始化格式
/**
* 设置自定义的Json转换时的处理类 *
* @param jsonProcessorList
*/
P17主要使用了jsonConfig.registerJsonValueProcessor(clazz[j],(JsonValueProcessor)jsonProcessorProvider);
指定包装类的转换格式()
在JsonUtil.java中主要使用JSON包提供的方法有两个:
1、 生成Json对象的串,注意:对象串是以{}包围的
JSONObject.fromObject(data, jsonConfig).toString();
2、 生成Json数组的串,注意:数组串是以[]包围的
JSONArray.fromObject(arrayObject, jsonConfig).toString();
在JsonResponseUtil.java中需要将上面方法创建的json串返回页面
/**
* 直接将Json的串发送给客户端
* @param jsonString json的串
*/
public void responseJsonString(String jsonString) {
HttpServletResponse response = ServletActionContext.getResponse();
responseJsonString(response, jsonString);
}
/**
* 直接将字Json的字符串写入到Response中
* @param response
* @param jsonString Json的字符串
*/
public void responseJsonString(HttpServletResponse response, String jsonString) {
response.setContentType(contentType);
byte[] bytes;
try {
bytes = jsonString.getBytes(charsetName);
} catch (UnsupportedEncodingException e) {
throw new UncheckedException(e);
}
response.setContentLength(bytes.length);
try {
OutputStream os = response.getOutputStream();
os.write(bytes);
os.flush();
if(logger.isDebugEnabled()) {
logger.debug("往客户端发送的Json串为:" + jsonString);
}
} catch (IOException e) {
logger.error("在往Response中写入Json字符串的时候发生异常。", e);
throw new UncheckedException(e);
}
}
通过以上方法将获取的JSON数据,根据Ajax方法的调用,返回页面。
这个Ajax的请求及回调数据的过程都是通过prototype.js提供的类Ajax.Request实现的!
new Ajax.Request(pageUrl, pf.ajaxRequestOptions({
method : 'post',
parameters : params,
onSuccess : function(transport) {
closepageloading();//关闭滚动条
try {
func(transport);
} catch (e) {
pf.log(e.name + ':' + e.message);
}
},
onFailure : ajaxOnFailure
}));
说明:提交URL,获取JSON,也就是使用XMLHttpRequest对象去调用参数和获取返回的数据,在js中使用transport来接收该对象,然后引用XMLHttpRequest对象的方法responseText来获取信息
例:var jsonObj = transport.responseText;// XMLHttpRequest.responseText
jsonObj 显示的就是{**:**,**:**},但是字符串
var recallEndParameterVo = jsonObj.evalJSON();//evalJSON()将字符串转化为json对象,该方法是prototype提供。
对于Ajax.Request的描述如下:
Ajax.Request构造方法的第二个对象了吗? 参数{method: 'get', parameters: pars, onComplete: showResponse} 表示一个匿名对象的真实写法。他表示你传入的这个对象有一个名为 method 值为 'get'的属性,另一个属性名为 parameters 包含HTTP请求的查询字符串,和一个onComplete 属性/方法包含函数showResponse。
还有一些其它的属性可以在这个对象里面定义和设置,如 asynchronous,可以为true 或 false 来决定AJAX对服务器的调用是否是异步的(默认值是 true)。
这个参数定义AJAX调用的选项。在我们的例子中,在第一个参数通过HTTP GET命令请求那个url,传入了变量 pars包含的查询字符串, Ajax.Request 对象在它完成接收响应的时候将调用showResponse 方法。
也许你知道, XMLHttpRequest在HTTP请求期间将报告进度情况。这个进度被描述为四个不同阶段:Loading, Loaded, Interactive, 或 Complete。你可以使 Ajax.Request 对象在任何阶段调用自定义方法 ,Complete 是最常用的一个。想调用自定义的方法只需要简单的在请求的选项参数中的名为 onXXXXX 属性/方法中提供自定义的方法对象。 就像我们例子中的 onComplete 。你传入的方法将会被用一个参数调用,这个参数是 XMLHttpRequest 对象自己。你将会用这个对象去得到返回的数据并且或许检查包含有在这次调用中的HTTP结果代码的 status 属性。
还有另外两个有用的选项用来处理结果。我们可以在onSuccess 选项处传入一个方法,当AJAX无误的执行完后调用, 相反的,也可以在onFailure选项处传入一个方法,当服务器端出现错误时调用。正如onXXXXX 选项传入的方法一样,这两个在被调用的时候也传入一个带有AJAX请求的XMLHttpRequest对象。
我们的例子没有用任何有趣的方式处理这个 XML响应, 我们只是把这段XML放进了一个文本域里面。对这个响应的一个典型的应用很可能就是找到其中的想要的信息,然后更新页面中的某些元素, 或者甚至可能做某些XSLT转换而在页面中产生一些HTML。