json-libのjsonConfig詳細使用
一、setCycleDetectionStrategy自己包含防止
CycleObject.javaは自分で書いたクラスです.
二、setExcludes:jsonにシーケンス化する必要がある属性を除外する
三、setIgnoreDefaultExcludes
上のコードはnameとclassを出力します.
setIgnoreDefaultExcludes(true)を外すとnameしか出力されずclassは出力されません.
四、registerJsonBeanProcessor valueタイプがjavaのbeanから変換されたとき、カスタムプロセッサを提供することができます.
注意:JsDateJsonBeanProcessorはjson-libがすでに提供しているクラスで、私たちも自分のJsonBeanProcessorを実現することができます.
五、registerJsonValueProcessor
六、registerDefaultValueProcessor
プレゼンテーションのために、まず自分で2つ実現しました. Processor
Integer向け
PlainObject(カスタムクラス)
以上の2つのクラスは、valueがnullの場合にどのように出力するかを処理するために使用されます.
普通のカスタムbeanも2つ用意されています
PlainObjectHolder:
PlainObject 自分で定義したクラスです
A,JSONObject.fromObject(null)というパラメータがnullに直接送られたら、json-libはどうしますか.
コードを見ると、空のJSOnObjectが直接返され、デフォルト値の出力は使用されません.
B,次に,Javaオブジェクトが直接JDKに存在するクラス(Enum,Annotation,JSOnObject,DynaBean,JSOnTokener,JSOnString,Map,String,Number,Arrayとは何か)である場合を見るが,null,json-libはどのように処理するか
JSONObject.java
以上のコードにより、主な発見_fromMapではDefaultValueProcessorの使用はサポートされていません.
理由コード:
JSONObject.java
私のコメントによると、 上のコードには明らかに矛盾がある.
_fromDynaBeanはDefaultValueProcessorをサポートしていますが、次のCと同じです.
C,javaオブジェクトがカスタムタイプであり,中の属性に空の値(値が割り当てられていない,デフォルトはnull)が含まれている場合,上のBがまだ貼り付けられていない最後のelseである.
テストクラスを書きました.
この場合の出力値は{"a":9999,"object":"美女瑶瑶"}つまり2つのProcessorが機能します.
========================== Json To Java ===============
一、ignoreDefaultExcludes
==========================================
私たちがプログラムを作るときは主にJava To Jsonを使う方法で、以下はセキュリティの問題を説明します.
出力内容:
{""}{":"""}
この内容を直接メモ帳に貼り付けてtestSecu.htmlと名付け、ブラウザでjsスクリプトが実行されていることを発見します.これにより、XSSセキュリティの問題が発生しやすくなります.
/**
* CycleDetectionStrategy
*/
public static void testCycleObject() {
CycleObject object = new CycleObject();
object.setMemberId("yajuntest");
object.setSex("male");
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
JSONObject json = JSONObject.fromObject(object, jsonConfig);
System.out.println(json);
}
public static void main(String[] args) {
JsonTest.testCycleObject();
}
CycleObject.javaは自分で書いたクラスです.
public class CycleObject {
private String memberId;
private String sex;
private CycleObject me = this;
…… // getters && setters
}
二、setExcludes:jsonにシーケンス化する必要がある属性を除外する
public static void testExcludeProperites() {
String str = "{'string':'JSON', 'integer': 1, 'double': 2.0, 'boolean': true}";
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExcludes(new String[] { "double", "boolean" });
JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON(str, jsonConfig);
System.out.println(jsonObject.getString("string"));
System.out.println(jsonObject.getInt("integer"));
System.out.println(jsonObject.has("double"));
System.out.println(jsonObject.has("boolean"));
}
public static void main(String[] args) {
JsonTest.testExcludeProperites();
}
三、setIgnoreDefaultExcludes
@SuppressWarnings("unchecked")
public static void testMap() {
Map map = new HashMap();
map.put("name", "json");
map.put("class", "ddd");
JsonConfig config = new JsonConfig();
config.setIgnoreDefaultExcludes(true); // false, key
JSONObject jsonObject = JSONObject.fromObject(map,config);
System.out.println(jsonObject);
}
上のコードはnameとclassを出力します.
setIgnoreDefaultExcludes(true)を外すとnameしか出力されずclassは出力されません.
private static final String[] DEFAULT_EXCLUDES = new String[] { "class", "declaringClass",
"metaClass" }; // key
四、registerJsonBeanProcessor valueタイプがjavaのbeanから変換されたとき、カスタムプロセッサを提供することができます.
public static void testMap() {
Map map = new HashMap();
map.put("name", "json");
map.put("class", "ddd");
map.put("date", new Date());
JsonConfig config = new JsonConfig();
config.setIgnoreDefaultExcludes(false);
config.registerJsonBeanProcessor(Date.class,
new JsDateJsonBeanProcessor()); // , JS
JSONObject jsonObject = JSONObject.fromObject(map, config);
System.out.println(jsonObject);
}
注意:JsDateJsonBeanProcessorはjson-libがすでに提供しているクラスで、私たちも自分のJsonBeanProcessorを実現することができます.
五、registerJsonValueProcessor
六、registerDefaultValueProcessor
プレゼンテーションのために、まず自分で2つ実現しました. Processor
Integer向け
public class MyDefaultIntegerValueProcessor implements DefaultValueProcessor {
public Object getDefaultValue(Class type) {
if (type != null && Integer.class.isAssignableFrom(type)) {
return Integer.valueOf(9999);
}
return JSONNull.getInstance();
}
}
PlainObject(カスタムクラス)
public class MyPlainObjectProcessor implements DefaultValueProcessor {
public Object getDefaultValue(Class type) {
if (type != null && PlainObject.class.isAssignableFrom(type)) {
return " " + " ";
}
return JSONNull.getInstance();
}
}
以上の2つのクラスは、valueがnullの場合にどのように出力するかを処理するために使用されます.
普通のカスタムbeanも2つ用意されています
PlainObjectHolder:
public class PlainObjectHolder {
private PlainObject object; //
private Integer a; // JDK
public PlainObject getObject() {
return object;
}
public void setObject(PlainObject object) {
this.object = object;
}
public Integer getA() {
return a;
}
public void setA(Integer a) {
this.a = a;
}
}
PlainObject 自分で定義したクラスです
public class PlainObject {
private String memberId;
private String sex;
public String getMemberId() {
return memberId;
}
public void setMemberId(String memberId) {
this.memberId = memberId;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
A,JSONObject.fromObject(null)というパラメータがnullに直接送られたら、json-libはどうしますか.
public static JSONObject fromObject( Object object, JsonConfig jsonConfig ) {
if( object == null || JSONUtils.isNull( object ) ){
return new JSONObject( true );
コードを見ると、空のJSOnObjectが直接返され、デフォルト値の出力は使用されません.
B,次に,Javaオブジェクトが直接JDKに存在するクラス(Enum,Annotation,JSOnObject,DynaBean,JSOnTokener,JSOnString,Map,String,Number,Arrayとは何か)である場合を見るが,null,json-libはどのように処理するか
JSONObject.java
}else if( object instanceof Enum ){
throw new JSONException( "'object' is an Enum. Use JSONArray instead" ); //
}else if( object instanceof Annotation || (object != null && object.getClass()
.isAnnotation()) ){
throw new JSONException( "'object' is an Annotation." ); //
}else if( object instanceof JSONObject ){
return _fromJSONObject( (JSONObject) object, jsonConfig );
}else if( object instanceof DynaBean ){
return _fromDynaBean( (DynaBean) object, jsonConfig );
}else if( object instanceof JSONTokener ){
return _fromJSONTokener( (JSONTokener) object, jsonConfig );
}else if( object instanceof JSONString ){
return _fromJSONString( (JSONString) object, jsonConfig );
}else if( object instanceof Map ){
return _fromMap( (Map) object, jsonConfig );
}else if( object instanceof String ){
return _fromString( (String) object, jsonConfig );
}else if( JSONUtils.isNumber( object ) || JSONUtils.isBoolean( object )
|| JSONUtils.isString( object ) ){
return new JSONObject(); //
}else if( JSONUtils.isArray( object ) ){
throw new JSONException( "'object' is an array. Use JSONArray instead" ); // , JSONArray
}else{
以上のコードにより、主な発見_fromMapではDefaultValueProcessorの使用はサポートされていません.
理由コード:
JSONObject.java
if( value != null ){ // ,value
JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor(
value.getClass(), key );
if( jsonValueProcessor != null ){
value = jsonValueProcessor.processObjectValue( key, value, jsonConfig );
if( !JsonVerifier.isValidJsonValue( value ) ){
throw new JSONException( "Value is not a valid JSON value. " + value );
}
}
setValue( jsonObject, key, value, value.getClass(), jsonConfig );
private static void setValue( JSONObject jsonObject, String key, Object value, Class type,
JsonConfig jsonConfig ) {
boolean accumulated = false;
if( value == null ){ // value DefaultValueProcessor
value = jsonConfig.findDefaultValueProcessor( type )
.getDefaultValue( type );
if( !JsonVerifier.isValidJsonValue( value ) ){
throw new JSONException( "Value is not a valid JSON value. " + value );
}
}
……
私のコメントによると、 上のコードには明らかに矛盾がある.
_fromDynaBeanはDefaultValueProcessorをサポートしていますが、次のCと同じです.
C,javaオブジェクトがカスタムタイプであり,中の属性に空の値(値が割り当てられていない,デフォルトはnull)が含まれている場合,上のBがまだ貼り付けられていない最後のelseである.
else {return _fromBean( object, jsonConfig );}
テストクラスを書きました.
public static void testDefaultValueProcessor() {
PlainObjectHolder holder = new PlainObjectHolder();
JsonConfig config = new JsonConfig();
config.registerDefaultValueProcessor(PlainObject.class,
new MyPlainObjectProcessor());
config.registerDefaultValueProcessor(Integer.class,
new MyDefaultIntegerValueProcessor());
JSONObject json = JSONObject.fromObject(holder, config);
System.out.println(json);
}
この場合の出力値は{"a":9999,"object":"美女瑶瑶"}つまり2つのProcessorが機能します.
========================== Json To Java ===============
一、ignoreDefaultExcludes
public static void json2java() {
String jsonString = "{'name':'hello','class':'ddd'}";
JsonConfig config = new JsonConfig();
config.setIgnoreDefaultExcludes(true); // JAVA To Json , class
JSONObject json = (JSONObject) JSONSerializer.toJSON(jsonString,config);
System.out.println(json);
}
==========================================
私たちがプログラムを作るときは主にJava To Jsonを使う方法で、以下はセキュリティの問題を説明します.
@SuppressWarnings("unchecked")
public static void testSecurity() {
Map map = new HashMap();
map.put("\"}<IMG src='x.jpg' onerror=javascript:alert(' ') border=0> {", "");
JSONObject jsonObject = JSONObject.fromObject(map);
System.out.println(jsonObject);
}
public static void main(String[] args) {
JsonTest.testSecurity();
}
出力内容:
{""}{":"""}
この内容を直接メモ帳に貼り付けてtestSecu.htmlと名付け、ブラウザでjsスクリプトが実行されていることを発見します.これにより、XSSセキュリティの問題が発生しやすくなります.