mirror of https://github.com/alibaba/fastjson2.git
				
				
				
			add new method JSON#parse(InputStream, Context)
This commit is contained in:
		
							parent
							
								
									9493d46ba9
								
							
						
					
					
						commit
						69538bbca6
					
				|  | @ -246,6 +246,32 @@ public interface JSON { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json stream as a {@link JSONArray} or {@link JSONObject}. | ||||
|      * Returns {@code null} if received {@link String} is {@code null} or empty. | ||||
|      * | ||||
|      * @param in the specified stream to be parsed | ||||
|      * @param context the specified custom context | ||||
|      * @return either {@link JSONArray} or {@link JSONObject} or null | ||||
|      * @throws JSONException If a parsing error occurs | ||||
|      * @throws NullPointerException If received context is null | ||||
|      * @since 2.0.47 | ||||
|      */ | ||||
|     static Object parse(InputStream in, JSONReader.Context context) { | ||||
|         if (in == null) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         ObjectReader<?> objectReader = context.getObjectReader(Object.class); | ||||
|         try (JSONReaderUTF8 reader = new JSONReaderUTF8(context, in)) { | ||||
|             Object object = objectReader.readObject(reader, null, null, 0); | ||||
|             if (reader.ch != EOI && (context.features & IgnoreCheckClose.mask) == 0) { | ||||
|                 throw new JSONException(reader.info("input not end")); | ||||
|             } | ||||
|             return object; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json string as a {@link JSONObject}. Returns {@code null} | ||||
|      * if received {@link String} is {@code null} or empty or its content is null. | ||||
|  | @ -570,6 +596,40 @@ public interface JSON { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json stream as a {@link JSONObject}. Returns {@code null} if | ||||
|      * received {@link InputStream} is {@code null} or closed or its content is null. | ||||
|      * | ||||
|      * @param input the specified stream to be parsed | ||||
|      * @param charset the specified charset of the stream | ||||
|      * @param context the specified custom context | ||||
|      * @return {@link JSONObject} or {@code null} | ||||
|      * @throws JSONException If a parsing error occurs | ||||
|      * | ||||
|      * @since 2.0.47 | ||||
|      */ | ||||
|     static JSONObject parseObject(InputStream input, Charset charset, JSONReader.Context context) { | ||||
|         if (input == null) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         try (JSONReader reader = JSONReader.of(input, charset, context)) { | ||||
|             if (reader.isEnd()) { | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             JSONObject object = new JSONObject(); | ||||
|             reader.read(object, 0); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(object); | ||||
|             } | ||||
|             if (reader.ch != EOI && (context.features & IgnoreCheckClose.mask) == 0) { | ||||
|                 throw new JSONException(reader.info("input not end")); | ||||
|             } | ||||
|             return object; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json stream of the url as a {@link JSONObject}. | ||||
|      * Returns {@code null} if received {@link URL} is {@code null}. | ||||
|  | @ -1861,6 +1921,76 @@ public interface JSON { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json stream as a {@link T}. Returns {@code null} | ||||
|      * if received {@link InputStream} is {@code null} or its content is null. | ||||
|      * | ||||
|      * @param input the specified stream to be parsed | ||||
|      * @param type the specified actual type of {@link T} | ||||
|      * @param context the specified custom context | ||||
|      * @return {@link T} or {@code null} | ||||
|      * @throws JSONException If a parsing error occurs | ||||
|      */ | ||||
|     @SuppressWarnings("unchecked") | ||||
|     static <T> T parseObject(InputStream input, Charset charset, Type type, JSONReader.Context context) { | ||||
|         if (input == null) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         boolean fieldBased = (context.features & JSONReader.Feature.FieldBased.mask) != 0; | ||||
|         ObjectReader<T> objectReader = context.provider.getObjectReader(type, fieldBased); | ||||
| 
 | ||||
|         try (JSONReader reader = JSONReader.of(input, charset, context)) { | ||||
|             if (reader.isEnd()) { | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             T object = objectReader.readObject(reader, type, null, 0); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(object); | ||||
|             } | ||||
|             if (reader.ch != EOI && (context.features & IgnoreCheckClose.mask) == 0) { | ||||
|                 throw new JSONException(reader.info("input not end")); | ||||
|             } | ||||
|             return object; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json stream as a {@link T}. Returns {@code null} | ||||
|      * if received {@link InputStream} is {@code null} or its content is null. | ||||
|      * | ||||
|      * @param input the specified stream to be parsed | ||||
|      * @param type the specified actual type of {@link T} | ||||
|      * @param context the specified custom context | ||||
|      * @return {@link T} or {@code null} | ||||
|      * @throws JSONException If a parsing error occurs | ||||
|      */ | ||||
|     @SuppressWarnings("unchecked") | ||||
|     static <T> T parseObject(InputStream input, Charset charset, Class<T> type, JSONReader.Context context) { | ||||
|         if (input == null) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         boolean fieldBased = (context.features & JSONReader.Feature.FieldBased.mask) != 0; | ||||
|         ObjectReader<T> objectReader = context.provider.getObjectReader(type, fieldBased); | ||||
| 
 | ||||
|         try (JSONReader reader = JSONReader.of(input, charset, context)) { | ||||
|             if (reader.isEnd()) { | ||||
|                 return null; | ||||
|             } | ||||
| 
 | ||||
|             T object = objectReader.readObject(reader, type, null, 0); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(object); | ||||
|             } | ||||
|             if (reader.ch != EOI && (context.features & IgnoreCheckClose.mask) == 0) { | ||||
|                 throw new JSONException(reader.info("input not end")); | ||||
|             } | ||||
|             return object; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json stream of the url as {@link T}. | ||||
|      * Returns {@code null} if received {@link URL} is {@code null}. | ||||
|  | @ -2498,6 +2628,37 @@ public interface JSON { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json stream as a {@link JSONArray}. Returns {@code null} | ||||
|      * if received {@link InputStream} is {@code null} or its content is null. | ||||
|      * | ||||
|      * @param in the specified stream to be parsed | ||||
|      * @param charset the specified charset of the stream | ||||
|      * @param context the specified custom context | ||||
|      * @return {@link JSONArray} or {@code null} | ||||
|      * @throws JSONException If an I/O error or parsing error occurs | ||||
|      */ | ||||
|     static JSONArray parseArray(InputStream in, Charset charset, JSONReader.Context context) { | ||||
|         if (in == null) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         try (JSONReader reader = JSONReader.of(in, charset, context)) { | ||||
|             if (reader.nextIfNull()) { | ||||
|                 return null; | ||||
|             } | ||||
|             JSONArray array = new JSONArray(); | ||||
|             reader.read(array); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(array); | ||||
|             } | ||||
|             if (reader.ch != EOI && (context.features & IgnoreCheckClose.mask) == 0) { | ||||
|                 throw new JSONException(reader.info("input not end")); | ||||
|             } | ||||
|             return array; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Parses the json string as a list of {@link T}. Returns | ||||
|      * {@code null} if received {@link String} is {@code null} or empty. | ||||
|  |  | |||
|  | @ -302,7 +302,6 @@ public interface JSONB { | |||
|     static Object parse(byte[] jsonbBytes, JSONReader.Feature... features) { | ||||
|         ObjectReaderProvider provider = defaultObjectReaderProvider; | ||||
|         JSONReader.Context context = new JSONReader.Context(provider, features); | ||||
|         boolean fieldBased = (context.features & JSONReader.Feature.FieldBased.mask) != 0; | ||||
| 
 | ||||
|         try (JSONReaderJSONB reader = new JSONReaderJSONB( | ||||
|                 context, | ||||
|  | @ -310,9 +309,17 @@ public interface JSONB { | |||
|                 0, | ||||
|                 jsonbBytes.length) | ||||
|         ) { | ||||
|             ObjectReader objectReader = provider.getObjectReader(Object.class, fieldBased); | ||||
|             Object object = reader.readAny(); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(object); | ||||
|             } | ||||
|             return object; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|             Object object = objectReader.readJSONBObject(reader, null, null, 0); | ||||
|     static Object parse(InputStream in, JSONReader.Context context) { | ||||
|         try (JSONReaderJSONB reader = new JSONReaderJSONB(context, in)) { | ||||
|             Object object = reader.readAny(); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(object); | ||||
|             } | ||||
|  | @ -323,7 +330,6 @@ public interface JSONB { | |||
|     static Object parse(byte[] jsonbBytes, SymbolTable symbolTable, JSONReader.Feature... features) { | ||||
|         ObjectReaderProvider provider = defaultObjectReaderProvider; | ||||
|         JSONReader.Context context = new JSONReader.Context(provider, symbolTable, features); | ||||
|         boolean fieldBased = (context.features & JSONReader.Feature.FieldBased.mask) != 0; | ||||
| 
 | ||||
|         try (JSONReaderJSONB reader = new JSONReaderJSONB( | ||||
|                 context, | ||||
|  | @ -331,9 +337,7 @@ public interface JSONB { | |||
|                 0, | ||||
|                 jsonbBytes.length) | ||||
|         ) { | ||||
|             ObjectReader objectReader = provider.getObjectReader(Object.class, fieldBased); | ||||
| 
 | ||||
|             Object object = objectReader.readJSONBObject(reader, null, null, 0); | ||||
|             Object object = reader.readAny(); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(object); | ||||
|             } | ||||
|  | @ -371,6 +375,16 @@ public interface JSONB { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     static JSONObject parseObject(InputStream in, JSONReader.Context context) { | ||||
|         try (JSONReaderJSONB reader = new JSONReaderJSONB(context, in)) { | ||||
|             JSONObject object = (JSONObject) reader.readObject(); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(object); | ||||
|             } | ||||
|             return object; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     static JSONArray parseArray(byte[] jsonbBytes) { | ||||
|         try (JSONReaderJSONB reader = new JSONReaderJSONB( | ||||
|                 new JSONReader.Context(JSONFactory.defaultObjectReaderProvider), | ||||
|  | @ -386,6 +400,16 @@ public interface JSONB { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     static JSONArray parseArray(InputStream in, JSONReader.Context context) { | ||||
|         try (JSONReaderJSONB reader = new JSONReaderJSONB(context, in)) { | ||||
|             JSONArray array = (JSONArray) reader.readArray(); | ||||
|             if (reader.resolveTasks != null) { | ||||
|                 reader.handleResolveTasks(array); | ||||
|             } | ||||
|             return array; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     static <T> List<T> parseArray(byte[] jsonbBytes, Type type) { | ||||
|         if (jsonbBytes == null || jsonbBytes.length == 0) { | ||||
|             return null; | ||||
|  |  | |||
|  | @ -2904,6 +2904,10 @@ public abstract class JSONReader | |||
|             return new JSONReaderUTF16(context, is); | ||||
|         } | ||||
| 
 | ||||
|         if (charset == StandardCharsets.US_ASCII) { | ||||
|             return new JSONReaderASCII(context, is); | ||||
|         } | ||||
| 
 | ||||
|         throw new JSONException("not support charset " + charset); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ package com.alibaba.fastjson2; | |||
| import com.alibaba.fastjson2.util.*; | ||||
| import sun.misc.Unsafe; | ||||
| 
 | ||||
| import java.io.InputStream; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| 
 | ||||
| import static com.alibaba.fastjson2.JSONFactory.*; | ||||
|  | @ -18,6 +19,12 @@ final class JSONReaderASCII | |||
|         nameAscii = true; | ||||
|     } | ||||
| 
 | ||||
|     JSONReaderASCII(Context ctx, InputStream is) { | ||||
|         super(ctx, is); | ||||
|         nameAscii = true; | ||||
|         str = null; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void next() { | ||||
|         int offset = this.offset; | ||||
|  |  | |||
|  | @ -1,11 +1,10 @@ | |||
| package com.alibaba.fastjson2.features; | ||||
| 
 | ||||
| import com.alibaba.fastjson2.JSON; | ||||
| import com.alibaba.fastjson2.JSONB; | ||||
| import com.alibaba.fastjson2.JSONObject; | ||||
| import com.alibaba.fastjson2.JSONReader; | ||||
| import com.alibaba.fastjson2.*; | ||||
| import org.junit.jupiter.api.Test; | ||||
| 
 | ||||
| import java.io.ByteArrayInputStream; | ||||
| import java.lang.reflect.Type; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| 
 | ||||
| import static org.junit.jupiter.api.Assertions.assertEquals; | ||||
|  | @ -25,13 +24,92 @@ public class TrimStringTest { | |||
|                         .getString("value")); | ||||
| 
 | ||||
|         assertEquals("a b", | ||||
|                 JSON.parseObject(utf8Bytes, 0, utf8Bytes.length, StandardCharsets.US_ASCII, JSONReader.Feature.TrimString) | ||||
|                         .getString("value")); | ||||
|                 JSON.parseObject( | ||||
|                         utf8Bytes, 0, utf8Bytes.length, StandardCharsets.US_ASCII, JSONReader.Feature.TrimString | ||||
|                 ).getString("value") | ||||
|         ); | ||||
|         assertEquals("a b", | ||||
|                 JSON.parseObject( | ||||
|                         new ByteArrayInputStream(utf8Bytes), | ||||
|                         StandardCharsets.US_ASCII, | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 ).getString("value") | ||||
|         ); | ||||
|         assertEquals("a b", | ||||
|                 ((JSONObject) JSON.parse( | ||||
|                         new ByteArrayInputStream(utf8Bytes), | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 )).getString("value") | ||||
|         ); | ||||
|         assertEquals("a b", | ||||
|                 JSON.parseObject( | ||||
|                         new ByteArrayInputStream(utf8Bytes), | ||||
|                         StandardCharsets.US_ASCII, | ||||
|                         Bean.class, | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 ).value | ||||
|         ); | ||||
|         assertEquals("a b", | ||||
|                 ((Bean) JSON.parseObject( | ||||
|                         new ByteArrayInputStream(utf8Bytes), | ||||
|                         StandardCharsets.US_ASCII, | ||||
|                         (Type) Bean.class, | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 )).value | ||||
|         ); | ||||
| 
 | ||||
|         assertEquals("a b", | ||||
|                 JSON.parseArray( | ||||
|                         new ByteArrayInputStream("[\" a b \"]".getBytes(StandardCharsets.UTF_8)), | ||||
|                         StandardCharsets.US_ASCII, | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 ).get(0) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void testJSONB() { | ||||
|         byte[] jsonbBytes = JSONObject.of("value", " a b ").toJSONBBytes(); | ||||
|         assertEquals("a b", JSONB.parseObject(jsonbBytes, JSONReader.Feature.TrimString).getString("value")); | ||||
|         String result = "a b"; | ||||
|         assertEquals( | ||||
|                 result, | ||||
|                 JSONB.parseObject( | ||||
|                         new ByteArrayInputStream(jsonbBytes), | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 ).getString("value") | ||||
|         ); | ||||
|         assertEquals( | ||||
|                 result, | ||||
|                 ((JSONObject) JSONB.parse( | ||||
|                         jsonbBytes, | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 )).getString("value") | ||||
|         ); | ||||
|         assertEquals( | ||||
|                 result, | ||||
|                 JSONB.parseObject( | ||||
|                         jsonbBytes, | ||||
|                         JSONReader.Feature.TrimString | ||||
|                 ).getString("value") | ||||
|         ); | ||||
|         assertEquals( | ||||
|                 result, | ||||
|                 ((JSONObject) JSONB.parse( | ||||
|                         new ByteArrayInputStream(jsonbBytes), | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 )).getString("value") | ||||
|         ); | ||||
| 
 | ||||
|         assertEquals( | ||||
|                 result, | ||||
|                 JSONB.parseArray( | ||||
|                         new ByteArrayInputStream(JSONArray.of(" a b ").toJSONBBytes()), | ||||
|                         new JSONReader.Context(JSONReader.Feature.TrimString) | ||||
|                 ).getString(0) | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     public static class Bean { | ||||
|         public String value; | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue