diff --git a/pom.xml b/pom.xml index 863c1af63..d8c1831d7 100755 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ com.alibaba fastjson - 1.2.4 + 1.2.5 jar fastjson diff --git a/src/main/java/com/alibaba/fastjson/JSON.java b/src/main/java/com/alibaba/fastjson/JSON.java index 510184f41..a46a8b3ee 100755 --- a/src/main/java/com/alibaba/fastjson/JSON.java +++ b/src/main/java/com/alibaba/fastjson/JSON.java @@ -88,7 +88,7 @@ public abstract class JSON implements JSONStreamAware, JSONAware { int features = 0; features |= SerializerFeature.QuoteFieldNames.getMask(); features |= SerializerFeature.SkipTransientField.getMask(); - features |= SerializerFeature.WriteEnumUsingToString.getMask(); + features |= SerializerFeature.WriteEnumUsingName.getMask(); features |= SerializerFeature.SortField.getMask(); // features |= // com.alibaba.fastjson.serializer.SerializerFeature.WriteSlashAsSpecial.getMask(); @@ -737,5 +737,5 @@ public abstract class JSON implements JSONStreamAware, JSONAware { } } - public final static String VERSION = "1.2.4"; + public final static String VERSION = "1.2.5"; } diff --git a/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java b/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java index e64e9a67f..fc69f957c 100755 --- a/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java +++ b/src/main/java/com/alibaba/fastjson/parser/DefaultJSONParser.java @@ -281,7 +281,7 @@ public class DefaultJSONParser extends AbstractJSONParser implements Closeable { lexer.resetStringPosition(); - if (key == JSON.DEFAULT_TYPE_KEY) { + if (key == JSON.DEFAULT_TYPE_KEY && !isEnabled(Feature.DisableSpecialKeyDetect)) { String typeName = lexer.scanSymbol(symbolTable, '"'); Class clazz = TypeUtils.loadClass(typeName); @@ -326,7 +326,7 @@ public class DefaultJSONParser extends AbstractJSONParser implements Closeable { return deserializer.deserialze(this, clazz, fieldName); } - if (key == "$ref") { + if (key == "$ref" && !isEnabled(Feature.DisableSpecialKeyDetect)) { lexer.nextToken(JSONToken.LITERAL_STRING); if (lexer.token() == JSONToken.LITERAL_STRING) { String ref = lexer.stringVal(); diff --git a/src/main/java/com/alibaba/fastjson/parser/Feature.java b/src/main/java/com/alibaba/fastjson/parser/Feature.java index 507c4c0ed..90563e606 100755 --- a/src/main/java/com/alibaba/fastjson/parser/Feature.java +++ b/src/main/java/com/alibaba/fastjson/parser/Feature.java @@ -90,7 +90,13 @@ public enum Feature { * @since 1.2.3 * */ - OrderedField + OrderedField, + + /** + * @since 1.2.5 + * + */ + DisableSpecialKeyDetect ; private Feature(){ diff --git a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java index 006a37bfd..daa2be258 100755 --- a/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java +++ b/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java @@ -243,6 +243,8 @@ public class ParserConfig { derializers.put(Object.class, JavaObjectDeserializer.instance); derializers.put(String.class, StringCodec.instance); + derializers.put(StringBuffer.class, StringCodec.instance); + derializers.put(StringBuilder.class, StringCodec.instance); derializers.put(char.class, CharacterCodec.instance); derializers.put(Character.class, CharacterCodec.instance); derializers.put(byte.class, NumberDeserializer.instance); diff --git a/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java b/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java index 7de1b4f75..6ee0d6026 100755 --- a/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java +++ b/src/main/java/com/alibaba/fastjson/parser/deserializer/MapDeserializer.java @@ -128,7 +128,7 @@ public class MapDeserializer implements ObjectDeserializer { lexer.resetStringPosition(); - if (key == JSON.DEFAULT_TYPE_KEY) { + if (key == JSON.DEFAULT_TYPE_KEY && !parser.isEnabled(Feature.DisableSpecialKeyDetect)) { String typeName = lexer.scanSymbol(parser.getSymbolTable(), '"'); Class clazz = TypeUtils.loadClass(typeName); @@ -205,7 +205,8 @@ public class MapDeserializer implements ObjectDeserializer { break; } - if (lexer.token() == JSONToken.LITERAL_STRING && lexer.isRef()) { + if (lexer.token() == JSONToken.LITERAL_STRING && lexer.isRef() + && !parser.isEnabled(Feature.DisableSpecialKeyDetect)) { Object object = null; lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); @@ -243,7 +244,8 @@ public class MapDeserializer implements ObjectDeserializer { if (map.size() == 0 // && lexer.token() == JSONToken.LITERAL_STRING // - && JSON.DEFAULT_TYPE_KEY.equals(lexer.stringVal())) { + && JSON.DEFAULT_TYPE_KEY.equals(lexer.stringVal()) // + && !parser.isEnabled(Feature.DisableSpecialKeyDetect)) { lexer.nextTokenWithColon(JSONToken.LITERAL_STRING); lexer.nextToken(JSONToken.COMMA); if (lexer.token() == JSONToken.RBRACE) { diff --git a/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java b/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java index 491f754bd..fab02e150 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/CalendarCodec.java @@ -9,33 +9,104 @@ import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.deserializer.DateDeserializer; import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer; +import com.alibaba.fastjson.util.IOUtils; public class CalendarCodec implements ObjectSerializer, ObjectDeserializer { public final static CalendarCodec instance = new CalendarCodec(); - public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { + SerializeWriter out = serializer.getWriter(); + + if (object == null) { + out.writeNull(); + return; + } + Calendar calendar = (Calendar) object; - Date date = calendar.getTime(); - serializer.write(date); + + if (serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) { + if (serializer.isEnabled(SerializerFeature.UseSingleQuotes)) { + out.append('\''); + } else { + out.append('\"'); + } + + int year = calendar.get(Calendar.YEAR); + int month = calendar.get(Calendar.MONTH) + 1; + int day = calendar.get(Calendar.DAY_OF_MONTH); + int hour = calendar.get(Calendar.HOUR_OF_DAY); + int minute = calendar.get(Calendar.MINUTE); + int second = calendar.get(Calendar.SECOND); + int millis = calendar.get(Calendar.MILLISECOND); + + char[] buf; + if (millis != 0) { + buf = "0000-00-00T00:00:00.000".toCharArray(); + IOUtils.getChars(millis, 23, buf); + IOUtils.getChars(second, 19, buf); + IOUtils.getChars(minute, 16, buf); + IOUtils.getChars(hour, 13, buf); + IOUtils.getChars(day, 10, buf); + IOUtils.getChars(month, 7, buf); + IOUtils.getChars(year, 4, buf); + + } else { + if (second == 0 && minute == 0 && hour == 0) { + buf = "0000-00-00".toCharArray(); + IOUtils.getChars(day, 10, buf); + IOUtils.getChars(month, 7, buf); + IOUtils.getChars(year, 4, buf); + } else { + buf = "0000-00-00T00:00:00".toCharArray(); + IOUtils.getChars(second, 19, buf); + IOUtils.getChars(minute, 16, buf); + IOUtils.getChars(hour, 13, buf); + IOUtils.getChars(day, 10, buf); + IOUtils.getChars(month, 7, buf); + IOUtils.getChars(year, 4, buf); + } + } + + out.write(buf); + + int timeZone = calendar.getTimeZone().getRawOffset() / (3600 * 1000); + if (timeZone == 0) { + out.append("Z"); + } else if (timeZone > 0) { + out.append("+").append(String.format("%02d", timeZone)).append(":00"); + } else { + out.append("-").append(String.format("%02d", -timeZone)).append(":00"); + } + + if (serializer.isEnabled(SerializerFeature.UseSingleQuotes)) { + out.append('\''); + } else { + out.append('\"'); + } + } else { + Date date = calendar.getTime(); + serializer.write(date); + } } @SuppressWarnings("unchecked") public T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { Object value = DateDeserializer.instance.deserialze(parser, type, fieldName); - + if (value instanceof Calendar) { return (T) value; } - + Date date = (Date) value; if (date == null) { return null; } - + Calendar calendar = Calendar.getInstance(); calendar.setTime(date); - + return (T) calendar; } diff --git a/src/main/java/com/alibaba/fastjson/serializer/DateSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/DateSerializer.java index 67fee1412..ace2f2cf7 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/DateSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/DateSerializer.java @@ -114,8 +114,17 @@ public class DateSerializer implements ObjectSerializer { IOUtils.getChars(year, 4, buf); } } - + out.write(buf); + + int timeZone = calendar.getTimeZone().getRawOffset()/(3600*1000); + if (timeZone == 0) { + out.append("Z"); + } else if (timeZone > 0) { + out.append("+").append(String.format("%02d", timeZone)).append(":00"); + } else { + out.append("-").append(String.format("%02d", -timeZone)).append(":00"); + } if (serializer.isEnabled(SerializerFeature.UseSingleQuotes)) { out.append('\''); diff --git a/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java index 987767a76..0cf249729 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/EnumSerializer.java @@ -32,11 +32,12 @@ public class EnumSerializer implements ObjectSerializer { return; } - if (serializer.isEnabled(SerializerFeature.WriteEnumUsingToString)) { - Enum e = (Enum) object; + Enum e = (Enum) object; + if(serializer.isEnabled(SerializerFeature.WriteEnumUsingName)){ + serializer.write(e.name()); + } else if (serializer.isEnabled(SerializerFeature.WriteEnumUsingToString)) { serializer.write(e.toString()); } else { - Enum e = (Enum) object; out.writeInt(e.ordinal()); } } diff --git a/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java b/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java index 1d0708b82..184cb7c8a 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java +++ b/src/main/java/com/alibaba/fastjson/serializer/ObjectFieldSerializer.java @@ -15,11 +15,11 @@ */ package com.alibaba.fastjson.serializer; -import java.util.Collection; - import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.util.FieldInfo; +import java.util.Collection; + /** * @author wenshao[szujobs@hotmail.com] */ @@ -31,6 +31,7 @@ public class ObjectFieldSerializer extends FieldSerializer { boolean writeNullBooleanAsFalse = false; boolean writeNullListAsEmpty = false; boolean writeEnumUsingToString = false; + boolean writeEnumUsingName = false; private RuntimeSerializerInfo runtimeInfo; @@ -57,6 +58,8 @@ public class ObjectFieldSerializer extends FieldSerializer { writeNullListAsEmpty = true; } else if (feature == SerializerFeature.WriteEnumUsingToString) { writeEnumUsingToString = true; + }else if(feature == SerializerFeature.WriteEnumUsingName){ + writeEnumUsingName = true; } } } @@ -110,9 +113,15 @@ public class ObjectFieldSerializer extends FieldSerializer { return; } - if (writeEnumUsingToString == true && runtimeInfo.runtimeFieldClass.isEnum()) { - serializer.getWriter().writeString(((Enum) propertyValue).name()); - return; + if(runtimeInfo.runtimeFieldClass.isEnum()){ + if(writeEnumUsingName){ + serializer.getWriter().writeString(((Enum) propertyValue).name()); + return; + } + if(writeEnumUsingToString){ + serializer.getWriter().writeString(((Enum) propertyValue).toString()); + return; + } } Class valueClass = propertyValue.getClass(); diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java index f6ed80a9b..7955660e0 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java @@ -115,6 +115,12 @@ public final class SerializeWriter extends Writer { public void config(SerializerFeature feature, boolean state) { if (state) { features |= feature.getMask(); + //由于枚举序列化特性WriteEnumUsingToString和WriteEnumUsingName不能共存,需要检查 + if(feature == SerializerFeature.WriteEnumUsingToString){ + features &= ~SerializerFeature.WriteEnumUsingName.getMask(); + }else if(feature == SerializerFeature.WriteEnumUsingName){ + features &= ~SerializerFeature.WriteEnumUsingToString.getMask(); + } } else { features &= ~feature.getMask(); } @@ -499,25 +505,34 @@ public final class SerializeWriter extends Writer { return; } - if (isEnabled(SerializerFeature.WriteEnumUsingToString)) { - if (isEnabled(SerializerFeature.UseSingleQuotes)) { - write('\''); - write(value.name()); - write('\''); - write(c); + if (isEnabled(SerializerFeature.WriteEnumUsingName)) { + writeEnumValue(value.name(),c); + return; + } - } else { - write('\"'); - write(value.name()); - write('\"'); - write(c); - } + if (isEnabled(SerializerFeature.WriteEnumUsingToString)) { + writeEnumValue(value.toString(),c); return; } writeIntAndChar(value.ordinal(), c); } + private void writeEnumValue(String value,char c){ + if (isEnabled(SerializerFeature.UseSingleQuotes)) { + write('\''); + write(value); + write('\''); + write(c); + + } else { + write('\"'); + write(value); + write('\"'); + write(c); + } + } + public void writeIntAndChar(int i, char c) { if (i == Integer.MIN_VALUE) { write("-2147483648"); @@ -1423,20 +1438,23 @@ public final class SerializeWriter extends Writer { return; } - if (isEnabled(SerializerFeature.WriteEnumUsingToString)) { - if (isEnabled(SerializerFeature.UseSingleQuotes)) { - writeFieldValue(seperator, name, value.name()); - } else { - writeFieldValueStringWithDoubleQuote(seperator, name, value.name(), false); - return; - } - - // writeStringWithDoubleQuote + if (isEnabled(SerializerFeature.WriteEnumUsingName)) { + writeEnumFieldValue(seperator,name,value.name()); + }else if(isEnabled(SerializerFeature.WriteEnumUsingToString)){ + writeEnumFieldValue(seperator,name,value.toString()); } else { writeFieldValue(seperator, name, value.ordinal()); } } + private void writeEnumFieldValue(char seperator,String name,String value){ + if (isEnabled(SerializerFeature.UseSingleQuotes)) { + writeFieldValue(seperator, name, value); + } else { + writeFieldValueStringWithDoubleQuote(seperator, name, value, false); + } + } + public void writeFieldValue(char seperator, String name, BigDecimal value) { write(seperator); writeFieldName(name); diff --git a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java index 3c2b045a7..dd5d67969 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java +++ b/src/main/java/com/alibaba/fastjson/serializer/SerializerFeature.java @@ -29,9 +29,13 @@ public enum SerializerFeature { */ WriteMapNullValue, /** - * + * 用枚举toString()值输出 */ WriteEnumUsingToString, + /** + * 用枚举name()输出 + */ + WriteEnumUsingName, /** * */ diff --git a/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java b/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java index 1eb4525c5..d07d954fe 100755 --- a/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java +++ b/src/main/java/com/alibaba/fastjson/serializer/StringCodec.java @@ -30,7 +30,8 @@ public class StringCodec implements ObjectSerializer, ObjectDeserializer { public static StringCodec instance = new StringCodec(); - public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { + public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) + throws IOException { write(serializer, (String) object); } @@ -48,12 +49,48 @@ public class StringCodec implements ObjectSerializer, ObjectDeserializer { out.writeString(value); } - + @SuppressWarnings("unchecked") public T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) { + if (clazz == StringBuffer.class) { + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.LITERAL_STRING) { + String val = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + + return (T) new StringBuffer(val); + } + + Object value = parser.parse(); + + if (value == null) { + return null; + } + + return (T) new StringBuffer(value.toString()); + } + + if (clazz == StringBuilder.class) { + final JSONLexer lexer = parser.getLexer(); + if (lexer.token() == JSONToken.LITERAL_STRING) { + String val = lexer.stringVal(); + lexer.nextToken(JSONToken.COMMA); + + return (T) new StringBuilder(val); + } + + Object value = parser.parse(); + + if (value == null) { + return null; + } + + return (T) new StringBuilder(value.toString()); + } + return (T) deserialze(parser); } - + @SuppressWarnings("unchecked") public static T deserialze(DefaultJSONParser parser) { final JSONLexer lexer = parser.getLexer(); @@ -62,7 +99,7 @@ public class StringCodec implements ObjectSerializer, ObjectDeserializer { lexer.nextToken(JSONToken.COMMA); return (T) val; } - + if (lexer.token() == JSONToken.LITERAL_INT) { String val = lexer.numberString(); lexer.nextToken(JSONToken.COMMA); diff --git a/src/test/java/com/alibaba/json/bvt/DisableSpecialKeyDetectTest.java b/src/test/java/com/alibaba/json/bvt/DisableSpecialKeyDetectTest.java new file mode 100644 index 000000000..99a537715 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/DisableSpecialKeyDetectTest.java @@ -0,0 +1,47 @@ +package com.alibaba.json.bvt; + +import java.util.Map; +import java.util.Set; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.parser.Feature; + +public class DisableSpecialKeyDetectTest extends TestCase { + + public void test_0() throws Exception { + String json = "{\"schema\":{\"$ref\":{\"@title\":\"类目ID\",\"@type\":\"string\"},\"$\":{\"@\":\"类目名称\",\"type\":\"string\"},\"cat_desc\":{\"title\":\"类目描述\",\"type\":\"string\"}}}"; + JSONObject errorJson = JSON.parseObject(json, Feature.DisableSpecialKeyDetect); + JSONObject schema = errorJson.getJSONObject("schema"); + Set> es2 = schema.entrySet(); + for (Map.Entry entry : es2) { + System.out.println(entry.getKey() + "_" + entry.getValue()); + } + } + + public void test_1() throws Exception { + String text = "{\"@v1\":\"v1\",\"@type\":\"v2\", \"@\":\"v3\",\"$\":\"v4\",\"$ref\":\"v5\"}"; + JSONObject json = JSON.parseObject(text, Feature.DisableSpecialKeyDetect); + Assert.assertEquals("v1", json.getString("@v1")); + Assert.assertEquals("v2", json.getString("@type")); + Assert.assertEquals("v3", json.getString("@")); + Assert.assertEquals("v4", json.getString("$")); + Assert.assertEquals("v5", json.getString("$ref")); + } + + public void test_2() throws Exception { + String text = "{\"@v1\":\"v1\",\"@type\":\"v2\", \"@\":\"v3\",\"$\":\"v4\",\"$ref\":\"v5\"}"; + Map map = JSON.parseObject(text, new TypeReference>(){}, Feature.DisableSpecialKeyDetect); + Assert.assertEquals("v1", map.get("@v1")); + Assert.assertEquals("v2", map.get("@type")); + Assert.assertEquals("v3", map.get("@")); + Assert.assertEquals("v4", map.get("$")); + Assert.assertEquals("v5", map.get("$ref")); + } + +} diff --git a/src/test/java/com/alibaba/json/bvt/StringBufferFieldTest.java b/src/test/java/com/alibaba/json/bvt/StringBufferFieldTest.java new file mode 100644 index 000000000..b004b5cbf --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/StringBufferFieldTest.java @@ -0,0 +1,86 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class StringBufferFieldTest extends TestCase { + + public void test_codec_null() throws Exception { + V0 v = new V0(); + + SerializeConfig mapping = new SerializeConfig(); + mapping.setAsmEnable(false); + + String text = JSON.toJSONString(v, mapping, SerializerFeature.WriteMapNullValue); + Assert.assertEquals("{\"value\":null}", text); + + ParserConfig config = new ParserConfig(); + config.setAsmEnable(false); + + V0 v1 = JSON.parseObject(text, V0.class, config, JSON.DEFAULT_PARSER_FEATURE); + + Assert.assertEquals(v1.getValue(), v.getValue()); + } + + public void test_codec_null_1() throws Exception { + V0 v = new V0(); + + SerializeConfig mapping = new SerializeConfig(); + mapping.setAsmEnable(false); + + String text = JSON.toJSONString(v, mapping, SerializerFeature.WriteMapNullValue, + SerializerFeature.WriteNullStringAsEmpty); + Assert.assertEquals("{\"value\":\"\"}", text); + } + + public void test_deserialize_1() throws Exception { + String json = "{\"value\":\"\"}"; + + V0 vo = JSON.parseObject(json, V0.class); + Assert.assertNotNull(vo.getValue()); + Assert.assertEquals("", vo.getValue().toString()); + } + + public void test_deserialize_2() throws Exception { + String json = "{\"value\":null}"; + + V0 vo = JSON.parseObject(json, V0.class); + Assert.assertNull(vo.getValue()); + } + + public void test_deserialize_3() throws Exception { + String json = "{\"value\":\"true\"}"; + + V0 vo = JSON.parseObject(json, V0.class); + Assert.assertNotNull(vo.getValue()); + Assert.assertEquals("true", vo.getValue().toString()); + } + + public void test_deserialize_4() throws Exception { + String json = "{\"value\":\"123\"}"; + + V0 vo = JSON.parseObject(json, V0.class); + Assert.assertNotNull(vo.getValue()); + Assert.assertEquals("123", vo.getValue().toString()); + } + + public static class V0 { + + private StringBuffer value; + + public StringBuffer getValue() { + return value; + } + + public void setValue(StringBuffer value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/StringBuilderFieldTest.java b/src/test/java/com/alibaba/json/bvt/StringBuilderFieldTest.java new file mode 100644 index 000000000..4081db457 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/StringBuilderFieldTest.java @@ -0,0 +1,86 @@ +package com.alibaba.json.bvt; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializeConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class StringBuilderFieldTest extends TestCase { + + public void test_codec_null() throws Exception { + V0 v = new V0(); + + SerializeConfig mapping = new SerializeConfig(); + mapping.setAsmEnable(false); + + String text = JSON.toJSONString(v, mapping, SerializerFeature.WriteMapNullValue); + Assert.assertEquals("{\"value\":null}", text); + + ParserConfig config = new ParserConfig(); + config.setAsmEnable(false); + + V0 v1 = JSON.parseObject(text, V0.class, config, JSON.DEFAULT_PARSER_FEATURE); + + Assert.assertEquals(v1.getValue(), v.getValue()); + } + + public void test_codec_null_1() throws Exception { + V0 v = new V0(); + + SerializeConfig mapping = new SerializeConfig(); + mapping.setAsmEnable(false); + + String text = JSON.toJSONString(v, mapping, SerializerFeature.WriteMapNullValue, + SerializerFeature.WriteNullStringAsEmpty); + Assert.assertEquals("{\"value\":\"\"}", text); + } + + public void test_deserialize_1() throws Exception { + String json = "{\"value\":\"\"}"; + + V0 vo = JSON.parseObject(json, V0.class); + Assert.assertNotNull(vo.getValue()); + Assert.assertEquals("", vo.getValue().toString()); + } + + public void test_deserialize_2() throws Exception { + String json = "{\"value\":null}"; + + V0 vo = JSON.parseObject(json, V0.class); + Assert.assertNull(vo.getValue()); + } + + public void test_deserialize_3() throws Exception { + String json = "{\"value\":\"true\"}"; + + V0 vo = JSON.parseObject(json, V0.class); + Assert.assertNotNull(vo.getValue()); + Assert.assertEquals("true", vo.getValue().toString()); + } + + public void test_deserialize_4() throws Exception { + String json = "{\"value\":\"123\"}"; + + V0 vo = JSON.parseObject(json, V0.class); + Assert.assertNotNull(vo.getValue()); + Assert.assertEquals("123", vo.getValue().toString()); + } + + public static class V0 { + + private StringBuilder value; + + public StringBuilder getValue() { + return value; + } + + public void setValue(StringBuilder value) { + this.value = value; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java b/src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java index 31b7f9b7c..f98e02790 100755 --- a/src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java +++ b/src/test/java/com/alibaba/json/bvt/StringDeserializerTest.java @@ -12,4 +12,38 @@ public class StringDeserializerTest extends TestCase { Assert.assertEquals("true", JSON.parseObject("true", String.class)); Assert.assertEquals(null, JSON.parseObject("null", String.class)); } + + public void test_StringBuffer() throws Exception { + Assert.assertTrue(equals(new StringBuffer("123"), JSON.parseObject("123", StringBuffer.class))); + Assert.assertTrue(equals(new StringBuffer("true"), JSON.parseObject("true", StringBuffer.class))); + Assert.assertEquals(null, JSON.parseObject("null", StringBuffer.class)); + } + + public void test_StringBuilder() throws Exception { + Assert.assertTrue(equals(new StringBuilder("123"), JSON.parseObject("123", StringBuilder.class))); + Assert.assertTrue(equals(new StringBuilder("true"), JSON.parseObject("true", StringBuilder.class))); + Assert.assertEquals(null, JSON.parseObject("null", StringBuilder.class)); + } + + private boolean equals(StringBuffer sb1, StringBuffer sb2) { + if (sb1 == null && sb2 == null) { + return true; + } + if ((sb1 == null && sb2 != null) || (sb1 != null && sb2 == null)) { + return false; + } + + return sb1.toString().equals(sb2.toString()); + } + + private boolean equals(StringBuilder sb1, StringBuilder sb2) { + if (sb1 == null && sb2 == null) { + return true; + } + if ((sb1 == null && sb2 != null) || (sb1 != null && sb2 == null)) { + return false; + } + + return sb1.toString().equals(sb2.toString()); + } } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateTest.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest.java index f29e882d3..c67ef6d20 100755 --- a/src/test/java/com/alibaba/json/bvt/serializer/DateTest.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest.java @@ -31,7 +31,7 @@ public class DateTest extends TestCase { Assert.assertEquals(true, serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)); serializer.write(new Date(1294552193254L)); - Assert.assertEquals("\"2011-01-09T13:49:53.254\"", out.toString()); + Assert.assertEquals("\"2011-01-09T13:49:53.254+08:00\"", out.toString()); } public void test_2() throws Exception { @@ -42,7 +42,7 @@ public class DateTest extends TestCase { Assert.assertEquals(true, serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)); serializer.write(new Date(1294552193000L)); - Assert.assertEquals("\"2011-01-09T13:49:53\"", out.toString()); + Assert.assertEquals("\"2011-01-09T13:49:53+08:00\"", out.toString()); } public void test_3() throws Exception { @@ -53,7 +53,7 @@ public class DateTest extends TestCase { Assert.assertEquals(true, serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)); serializer.write(new Date(1294502400000L)); - Assert.assertEquals("\"2011-01-09\"", out.toString()); + Assert.assertEquals("\"2011-01-09+08:00\"", out.toString()); } public void test_4() throws Exception { @@ -65,7 +65,7 @@ public class DateTest extends TestCase { Assert.assertEquals(true, serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)); serializer.write(new Date(1294502400000L)); - Assert.assertEquals("'2011-01-09'", out.toString()); + Assert.assertEquals("'2011-01-09+08:00'", out.toString()); } public void test_5() throws Exception { @@ -76,7 +76,7 @@ public class DateTest extends TestCase { Assert.assertEquals(true, serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)); serializer.write(new Date(1294502401000L)); - Assert.assertEquals("\"2011-01-09T00:00:01\"", out.toString()); + Assert.assertEquals("\"2011-01-09T00:00:01+08:00\"", out.toString()); } public void test_6() throws Exception { @@ -87,7 +87,7 @@ public class DateTest extends TestCase { Assert.assertEquals(true, serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)); serializer.write(new Date(1294502460000L)); - Assert.assertEquals("\"2011-01-09T00:01:00\"", out.toString()); + Assert.assertEquals("\"2011-01-09T00:01:00+08:00\"", out.toString()); } public void test_7() throws Exception { @@ -98,17 +98,17 @@ public class DateTest extends TestCase { Assert.assertEquals(true, serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)); serializer.write(new Date(1294506000000L)); - Assert.assertEquals("\"2011-01-09T01:00:00\"", out.toString()); + Assert.assertEquals("\"2011-01-09T01:00:00+08:00\"", out.toString()); } public void test_8() throws Exception { String text = JSON.toJSONString(new Date(1294506000000L), SerializerFeature.UseISO8601DateFormat); - Assert.assertEquals("\"2011-01-09T01:00:00\"", text); + Assert.assertEquals("\"2011-01-09T01:00:00+08:00\"", text); } public void test_9() throws Exception { String text = JSON.toJSONString(new Entity(new Date(1294506000000L)), SerializerFeature.UseISO8601DateFormat); - Assert.assertEquals("{\"date\":\"2011-01-09T01:00:00\"}", text); + Assert.assertEquals("{\"date\":\"2011-01-09T01:00:00+08:00\"}", text); Entity entity = JSON.parseObject(text, Entity.class); Assert.assertEquals(new Date(1294506000000L), entity.getDate()); diff --git a/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_TimeZone.java b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_TimeZone.java new file mode 100644 index 000000000..f5ddfb0e1 --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/DateTest_ISO8601_TimeZone.java @@ -0,0 +1,70 @@ +package com.alibaba.json.bvt.serializer; + +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.TimeZone; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.TypeReference; +import com.alibaba.fastjson.serializer.SerializerFeature; + +public class DateTest_ISO8601_TimeZone extends TestCase { + + public void test_date1() throws Exception { + Map map = new HashMap(); + map.put("date", new Date(1425886057586l)); + + String json = JSON.toJSONString(map, SerializerFeature.UseISO8601DateFormat); + + Assert.assertEquals("{\"date\":\"2015-03-09T15:27:37.586+08:00\"}", json); + + Map newMap = JSON.parseObject(json, new TypeReference>(){}); + + Assert.assertEquals(1425886057586l, newMap.get("date").getTime()); + } + + public void test_date2() throws Exception { + Calendar c = Calendar.getInstance(); + c.setTimeZone(TimeZone.getTimeZone("GMT+10")); + VO v = new VO(); + v.setGmtCreate(c); + String json = JSON.toJSONString(v, SerializerFeature.UseISO8601DateFormat); + System.out.println(json); + + Calendar cal = JSON.parseObject(json, VO.class).getGmtCreate(); + + Assert.assertEquals(10, cal.getTimeZone().getRawOffset() / (3600 * 1000)); + } + + public void test_date3() throws Exception { + Calendar c = Calendar.getInstance(); + VO v = new VO(); + v.setGmtCreate(c); + String json = JSON.toJSONString(v, SerializerFeature.UseISO8601DateFormat); + System.out.println(json); + + Calendar cal = JSON.parseObject(json, VO.class).getGmtCreate(); + + Assert.assertEquals(8, cal.getTimeZone().getRawOffset() / (3600 * 1000)); + } + + public static class VO { + + private Calendar gmtCreate; + + public Calendar getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(Calendar gmtCreate) { + this.gmtCreate = gmtCreate; + } + + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/EnumTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest2.java index 5f2a813ac..e2fd93fd6 100755 --- a/src/test/java/com/alibaba/json/bvt/serializer/EnumTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest2.java @@ -26,8 +26,8 @@ public class EnumTest2 extends TestCase { Date date = new Date(1308841916550L); Assert.assertEquals("1308841916550", JSON.toJSONString(date, mapping)); // 1308841916550 - Assert.assertEquals("\"2011-06-23T23:11:56.550\"", JSON.toJSONString(date, mapping, SerializerFeature.UseISO8601DateFormat)); // "2011-06-23T23:11:56.550" + Assert.assertEquals("\"2011-06-23T23:11:56.550+08:00\"", JSON.toJSONString(date, mapping, SerializerFeature.UseISO8601DateFormat)); // "2011-06-23T23:11:56.550" SerializerFeature[] features = {SerializerFeature.UseISO8601DateFormat, SerializerFeature.UseSingleQuotes }; - Assert.assertEquals("'2011-06-23T23:11:56.550'", JSON.toJSONString(date, mapping, features)); // '2011-06-23T23:11:56.550' + Assert.assertEquals("'2011-06-23T23:11:56.550+08:00'", JSON.toJSONString(date, mapping, features)); // '2011-06-23T23:11:56.550' } } diff --git a/src/test/java/com/alibaba/json/bvt/serializer/EnumTest3.java b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest3.java new file mode 100644 index 000000000..62c7152bd --- /dev/null +++ b/src/test/java/com/alibaba/json/bvt/serializer/EnumTest3.java @@ -0,0 +1,129 @@ +/* + * www.yiji.com Inc. + * Copyright (c) 2014 All Rights Reserved + */ + +/* + * 修订记录: + * qzhanbo@yiji.com 2015-03-01 00:55 创建 + * + */ +package com.alibaba.json.bvt.serializer; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializeWriter; +import com.alibaba.fastjson.serializer.SerializerFeature; +import org.junit.Assert; +import org.junit.Test; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +/** + * @author bohr.qiu@gmail.com + */ +public class EnumTest3 { + @Test + public void testDefault() throws Exception { + String json = JSON.toJSONString(Sex.M); + Assert.assertEquals(json, "\"M\""); + + Pojo pojo = new Pojo(); + pojo.setSex(Sex.M); + json = JSON.toJSONString(pojo); + Assert.assertEquals(json, "{\"sex\":\"M\"}"); + + try { + JSON.parseObject(json, Pojo.class); + Assert.assertTrue(true); + } catch (Exception e) { + Assert.fail("枚举默认序列化name值,可以反序列化成功"); + } + + Map map = new HashMap(); + map.put("a", pojo); + json = JSON.toJSONString(map); + Assert.assertEquals(json, "{\"a\":{\"sex\":\"M\"}}"); + + Map enumMap = new EnumMap(Sex.class); + enumMap.put(Sex.M, pojo); + json = JSON.toJSONString(enumMap); + Assert.assertEquals(json, "{\"M\":{\"sex\":\"M\"}}"); + } + + @Test + public void testDefault1() throws Exception { + JSON.DUMP_CLASS = "/Users/bohr/Downloads/tmp"; + String json = JSON.toJSONString(Sex.M, SerializerFeature.WriteEnumUsingToString); + Assert.assertEquals(json, "\"男\""); + + Pojo pojo = new Pojo(); + pojo.setSex(Sex.M); + json = JSON.toJSONString(pojo, SerializerFeature.WriteEnumUsingToString); + Assert.assertEquals(json, "{\"sex\":\"男\"}"); + + try { + JSON.parseObject(json, Pojo.class); + Assert.fail("toString的结果不能转换成枚举"); + } catch (Exception e) { + Assert.assertTrue(true); + } + + Map map = new HashMap(); + map.put("a", pojo); + json = JSON.toJSONString(map, SerializerFeature.WriteEnumUsingToString); + Assert.assertEquals(json, "{\"a\":{\"sex\":\"男\"}}"); + + Map enumMap = new EnumMap(Sex.class); + enumMap.put(Sex.M, pojo); + json = JSON.toJSONString(enumMap, SerializerFeature.WriteEnumUsingToString); + Assert.assertEquals(json, "{\"男\":{\"sex\":\"男\"}}"); + } + + @Test + public void testName() throws Exception { + Assert.assertEquals("\"男\"", JSON.toJSONString(Sex.M, SerializerFeature.WriteEnumUsingToString)); + Assert.assertEquals("\"女\"", JSON.toJSONString(Sex.W, SerializerFeature.WriteEnumUsingToString)); + } + + @Test + public void testWriterSerializerFeature() throws Exception { + SerializeWriter writer=new SerializeWriter(); + writer.config(SerializerFeature.WriteEnumUsingToString,true); + Assert.assertTrue(writer.isEnabled(SerializerFeature.WriteEnumUsingToString)); + writer.config(SerializerFeature.WriteEnumUsingName,true); + Assert.assertTrue(writer.isEnabled(SerializerFeature.WriteEnumUsingName)); + Assert.assertFalse(writer.isEnabled(SerializerFeature.WriteEnumUsingToString)); + writer.config(SerializerFeature.WriteEnumUsingToString,true); + Assert.assertTrue(writer.isEnabled(SerializerFeature.WriteEnumUsingToString)); + Assert.assertFalse(writer.isEnabled(SerializerFeature.WriteEnumUsingName)); + } + + public static enum Sex { + M("男"), + W("女"); + private String msg; + + Sex(String msg) { + this.msg = msg; + } + + @Override + public String toString() { + return msg; + } + } + + public static class Pojo { + private Sex sex; + + public Sex getSex() { + return sex; + } + + public void setSex(Sex sex) { + this.sex = sex; + } + } +} diff --git a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java index 87151b5e7..d7add8089 100755 --- a/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java +++ b/src/test/java/com/alibaba/json/bvt/serializer/JSONSerializerTest2.java @@ -17,6 +17,7 @@ public class JSONSerializerTest2 extends TestCase { int size = serializer.getMapping().size(); serializer.config(SerializerFeature.WriteEnumUsingToString, false); + serializer.config(SerializerFeature.WriteEnumUsingName, false); serializer.write(Type.A); Assert.assertTrue(size < serializer.getMapping().size()); @@ -27,6 +28,7 @@ public class JSONSerializerTest2 extends TestCase { public void test_1() throws Exception { JSONSerializer serializer = new JSONSerializer(); serializer.config(SerializerFeature.WriteEnumUsingToString, false); + serializer.config(SerializerFeature.WriteEnumUsingName, false); serializer.write(new A(Type.B)); Assert.assertEquals("{\"type\":" + Integer.toString(Type.B.ordinal()) + "}", serializer.getWriter().toString());