JsonUtil.java 13.0 KB
Newer Older
如梦技术's avatar
如梦技术 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.dreamlu.mica.core.utils;

19
import com.fasterxml.jackson.core.JsonFactory;
如梦技术's avatar
如梦技术 已提交
20 21
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
如梦技术's avatar
如梦技术 已提交
22
import com.fasterxml.jackson.core.TreeNode;
23
import com.fasterxml.jackson.core.json.JsonReadFeature;
如梦技术's avatar
如梦技术 已提交
24
import com.fasterxml.jackson.core.type.TypeReference;
25
import com.fasterxml.jackson.databind.*;
如梦技术's avatar
如梦技术 已提交
26 27
import com.fasterxml.jackson.databind.type.CollectionLikeType;
import com.fasterxml.jackson.databind.type.MapType;
如梦技术's avatar
如梦技术 已提交
28
import lombok.experimental.UtilityClass;
如梦技术's avatar
如梦技术 已提交
29
import org.springframework.lang.Nullable;
如梦技术's avatar
如梦技术 已提交
30 31 32 33 34

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
如梦技术's avatar
如梦技术 已提交
35
import java.util.*;
如梦技术's avatar
如梦技术 已提交
36 37 38

/**
 * json 工具类
如梦技术's avatar
如梦技术 已提交
39
 *
如梦技术's avatar
如梦技术 已提交
40 41 42 43 44 45 46 47 48 49 50
 * @author L.cm
 */
@UtilityClass
public class JsonUtil {

	/**
	 * 将对象序列化成json字符串
	 *
	 * @param object javaBean
	 * @return jsonString json字符串
	 */
如梦技术's avatar
如梦技术 已提交
51 52 53 54 55
	@Nullable
	public static String toJson(@Nullable Object object) {
		if (object == null) {
			return null;
		}
如梦技术's avatar
如梦技术 已提交
56 57 58 59 60 61 62 63 64 65 66 67 68
		try {
			return getInstance().writeValueAsString(object);
		} catch (JsonProcessingException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将对象序列化成 json byte 数组
	 *
	 * @param object javaBean
	 * @return jsonString json字符串
	 */
如梦技术's avatar
如梦技术 已提交
69 70
	public static byte[] toJsonAsBytes(@Nullable Object object) {
		if (object == null) {
71
			return new byte[0];
如梦技术's avatar
如梦技术 已提交
72
		}
如梦技术's avatar
如梦技术 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86
		try {
			return getInstance().writeValueAsBytes(object);
		} catch (JsonProcessingException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json字符串转成 JsonNode
	 *
	 * @param jsonString jsonString
	 * @return jsonString json字符串
	 */
	public static JsonNode readTree(String jsonString) {
如梦技术's avatar
如梦技术 已提交
87
		Objects.requireNonNull(jsonString, "jsonString is null");
如梦技术's avatar
如梦技术 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101
		try {
			return getInstance().readTree(jsonString);
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json字符串转成 JsonNode
	 *
	 * @param in InputStream
	 * @return jsonString json字符串
	 */
	public static JsonNode readTree(InputStream in) {
如梦技术's avatar
如梦技术 已提交
102
		Objects.requireNonNull(in, "InputStream in is null");
如梦技术's avatar
如梦技术 已提交
103 104 105 106 107 108 109 110 111 112 113 114 115 116
		try {
			return getInstance().readTree(in);
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json字符串转成 JsonNode
	 *
	 * @param content content
	 * @return jsonString json字符串
	 */
	public static JsonNode readTree(byte[] content) {
如梦技术's avatar
如梦技术 已提交
117
		Objects.requireNonNull(content, "byte[] content is null");
如梦技术's avatar
如梦技术 已提交
118 119 120 121 122 123 124 125 126 127 128 129 130 131
		try {
			return getInstance().readTree(content);
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json字符串转成 JsonNode
	 *
	 * @param jsonParser JsonParser
	 * @return jsonString json字符串
	 */
	public static JsonNode readTree(JsonParser jsonParser) {
如梦技术's avatar
如梦技术 已提交
132
		Objects.requireNonNull(jsonParser, "jsonParser is null");
如梦技术's avatar
如梦技术 已提交
133 134 135 136 137 138 139 140 141 142
		try {
			return getInstance().readTree(jsonParser);
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json byte 数组反序列化成对象
	 *
如梦技术's avatar
如梦技术 已提交
143 144 145
	 * @param content   json bytes
	 * @param valueType class
	 * @param <T>       T 泛型标记
如梦技术's avatar
如梦技术 已提交
146 147
	 * @return Bean
	 */
如梦技术's avatar
如梦技术 已提交
148 149 150 151 152
	@Nullable
	public static <T> T readValue(@Nullable byte[] content, Class<T> valueType) {
		if (ObjectUtil.isEmpty(content)) {
			return null;
		}
如梦技术's avatar
如梦技术 已提交
153
		try {
如梦技术's avatar
如梦技术 已提交
154
			return getInstance().readValue(content, valueType);
如梦技术's avatar
如梦技术 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json反序列化成对象
	 *
	 * @param jsonString jsonString
	 * @param valueType  class
	 * @param <T>        T 泛型标记
	 * @return Bean
	 */
如梦技术's avatar
如梦技术 已提交
168 169 170 171 172
	@Nullable
	public static <T> T readValue(@Nullable String jsonString, Class<T> valueType) {
		if (StringUtil.isBlank(jsonString)) {
			return null;
		}
如梦技术's avatar
如梦技术 已提交
173 174 175 176 177 178 179 180 181 182
		try {
			return getInstance().readValue(jsonString, valueType);
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json反序列化成对象
	 *
如梦技术's avatar
如梦技术 已提交
183 184 185
	 * @param in        InputStream
	 * @param valueType class
	 * @param <T>       T 泛型标记
如梦技术's avatar
如梦技术 已提交
186 187
	 * @return Bean
	 */
如梦技术's avatar
如梦技术 已提交
188 189 190 191 192
	@Nullable
	public static <T> T readValue(@Nullable InputStream in, Class<T> valueType) {
		if (in == null) {
			return null;
		}
如梦技术's avatar
如梦技术 已提交
193 194 195 196 197 198 199 200 201 202
		try {
			return getInstance().readValue(in, valueType);
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json反序列化成对象
	 *
如梦技术's avatar
如梦技术 已提交
203
	 * @param content       bytes
如梦技术's avatar
如梦技术 已提交
204
	 * @param typeReference 泛型类型
如梦技术's avatar
如梦技术 已提交
205
	 * @param <T>           T 泛型标记
如梦技术's avatar
如梦技术 已提交
206 207
	 * @return Bean
	 */
如梦技术's avatar
如梦技术 已提交
208
	@Nullable
如梦技术's avatar
如梦技术 已提交
209
	public static <T> T readValue(@Nullable byte[] content, TypeReference<T> typeReference) {
如梦技术's avatar
如梦技术 已提交
210 211 212
		if (ObjectUtil.isEmpty(content)) {
			return null;
		}
如梦技术's avatar
如梦技术 已提交
213
		try {
如梦技术's avatar
如梦技术 已提交
214
			return getInstance().readValue(content, typeReference);
如梦技术's avatar
如梦技术 已提交
215 216 217 218 219 220 221 222
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json反序列化成对象
	 *
如梦技术's avatar
如梦技术 已提交
223
	 * @param jsonString    jsonString
如梦技术's avatar
如梦技术 已提交
224
	 * @param typeReference 泛型类型
如梦技术's avatar
如梦技术 已提交
225
	 * @param <T>           T 泛型标记
如梦技术's avatar
如梦技术 已提交
226 227
	 * @return Bean
	 */
如梦技术's avatar
如梦技术 已提交
228
	@Nullable
如梦技术's avatar
如梦技术 已提交
229
	public static <T> T readValue(@Nullable String jsonString, TypeReference<T> typeReference) {
如梦技术's avatar
如梦技术 已提交
230 231 232
		if (StringUtil.isBlank(jsonString)) {
			return null;
		}
如梦技术's avatar
如梦技术 已提交
233 234 235 236 237 238 239 240 241 242
		try {
			return getInstance().readValue(jsonString, typeReference);
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 将json反序列化成对象
	 *
如梦技术's avatar
如梦技术 已提交
243
	 * @param in            InputStream
如梦技术's avatar
如梦技术 已提交
244
	 * @param typeReference 泛型类型
如梦技术's avatar
如梦技术 已提交
245
	 * @param <T>           T 泛型标记
如梦技术's avatar
如梦技术 已提交
246 247
	 * @return Bean
	 */
如梦技术's avatar
如梦技术 已提交
248
	@Nullable
如梦技术's avatar
如梦技术 已提交
249
	public static <T> T readValue(@Nullable InputStream in, TypeReference<T> typeReference) {
如梦技术's avatar
如梦技术 已提交
250 251 252
		if (in == null) {
			return null;
		}
如梦技术's avatar
如梦技术 已提交
253 254 255 256 257 258 259
		try {
			return getInstance().readValue(in, typeReference);
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

如梦技术's avatar
如梦技术 已提交
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
	/**
	 * 封装 map type
	 *
	 * @param keyClass   key 类型
	 * @param valueClass value 类型
	 * @return MapType
	 */
	public static MapType getMapType(Class<?> keyClass, Class<?> valueClass) {
		return getInstance().getTypeFactory().constructMapType(Map.class, keyClass, valueClass);
	}

	/**
	 * 封装 map type
	 *
	 * @param elementClass 集合值类型
	 * @return CollectionLikeType
	 */
	public static CollectionLikeType getListType(Class<?> elementClass) {
		return getInstance().getTypeFactory().constructCollectionLikeType(List.class, elementClass);
	}

	/**
	 * 读取集合
	 *
	 * @param content      bytes
	 * @param elementClass elementClass
	 * @param <T>          泛型
	 * @return 集合
	 */
	public static <T> List<T> readList(@Nullable byte[] content, Class<T> elementClass) {
		if (ObjectUtil.isEmpty(content)) {
			return Collections.emptyList();
		}
		try {
			return getInstance().readValue(content, getListType(elementClass));
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

如梦技术's avatar
如梦技术 已提交
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
	/**
	 * 读取集合
	 *
	 * @param content      InputStream
	 * @param elementClass elementClass
	 * @param <T>          泛型
	 * @return 集合
	 */
	public static <T> List<T> readList(@Nullable InputStream content, Class<T> elementClass) {
		if (content == null) {
			return Collections.emptyList();
		}
		try {
			return getInstance().readValue(content, getListType(elementClass));
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

如梦技术's avatar
如梦技术 已提交
319 320 321 322 323 324 325 326
	/**
	 * 读取集合
	 *
	 * @param content      bytes
	 * @param elementClass elementClass
	 * @param <T>          泛型
	 * @return 集合
	 */
327
	public static <T> List<T> readList(@Nullable String content, Class<T> elementClass) {
如梦技术's avatar
如梦技术 已提交
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
		if (ObjectUtil.isEmpty(content)) {
			return Collections.emptyList();
		}
		try {
			return getInstance().readValue(content, getListType(elementClass));
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 读取集合
	 *
	 * @param content    bytes
	 * @param keyClass   key类型
	 * @param valueClass 值类型
如梦技术's avatar
如梦技术 已提交
344 345
	 * @param <K>        泛型
	 * @param <V>        泛型
如梦技术's avatar
如梦技术 已提交
346 347
	 * @return 集合
	 */
如梦技术's avatar
如梦技术 已提交
348
	public static <K, V> Map<K, V> readMap(@Nullable byte[] content, Class<?> keyClass, Class<?> valueClass) {
如梦技术's avatar
如梦技术 已提交
349
		if (ObjectUtil.isEmpty(content)) {
如梦技术's avatar
如梦技术 已提交
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
			return Collections.emptyMap();
		}
		try {
			return getInstance().readValue(content, getMapType(keyClass, valueClass));
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 读取集合
	 *
	 * @param content    InputStream
	 * @param keyClass   key类型
	 * @param valueClass 值类型
	 * @param <K>        泛型
	 * @param <V>        泛型
	 * @return 集合
	 */
	public static <K, V> Map<K, V> readMap(@Nullable InputStream content, Class<?> keyClass, Class<?> valueClass) {
		if (ObjectUtil.isEmpty(content)) {
			return Collections.emptyMap();
如梦技术's avatar
如梦技术 已提交
372 373 374 375 376 377 378 379 380 381 382 383 384 385
		}
		try {
			return getInstance().readValue(content, getMapType(keyClass, valueClass));
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 读取集合
	 *
	 * @param content    bytes
	 * @param keyClass   key类型
	 * @param valueClass 值类型
如梦技术's avatar
如梦技术 已提交
386 387
	 * @param <K>        泛型
	 * @param <V>        泛型
如梦技术's avatar
如梦技术 已提交
388 389
	 * @return 集合
	 */
如梦技术's avatar
如梦技术 已提交
390
	public static <K, V> Map<K, V> readMap(@Nullable String content, Class<?> keyClass, Class<?> valueClass) {
如梦技术's avatar
如梦技术 已提交
391
		if (ObjectUtil.isEmpty(content)) {
如梦技术's avatar
如梦技术 已提交
392
			return Collections.emptyMap();
如梦技术's avatar
如梦技术 已提交
393 394 395 396 397 398 399 400
		}
		try {
			return getInstance().readValue(content, getMapType(keyClass, valueClass));
		} catch (IOException e) {
			throw Exceptions.unchecked(e);
		}
	}

如梦技术's avatar
如梦技术 已提交
401 402 403 404 405 406 407 408 409 410 411 412
	/**
	 * jackson 的类型转换
	 *
	 * @param fromValue   来源对象
	 * @param toValueType 转换的类型
	 * @param <T>         泛型标记
	 * @return 转换结果
	 */
	public static <T> T convertValue(Object fromValue, Class<T> toValueType) {
		return getInstance().convertValue(fromValue, toValueType);
	}

413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
	/**
	 * jackson 的类型转换
	 *
	 * @param fromValue   来源对象
	 * @param toValueType 转换的类型
	 * @param <T>         泛型标记
	 * @return 转换结果
	 */
	public static <T> T convertValue(Object fromValue, JavaType toValueType) {
		return getInstance().convertValue(fromValue, toValueType);
	}

	/**
	 * jackson 的类型转换
	 *
	 * @param fromValue      来源对象
	 * @param toValueTypeRef 泛型类型
	 * @param <T>            泛型标记
	 * @return 转换结果
	 */
	public static <T> T convertValue(Object fromValue, TypeReference<T> toValueTypeRef) {
		return getInstance().convertValue(fromValue, toValueTypeRef);
	}

如梦技术's avatar
如梦技术 已提交
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
	/**
	 * tree 转对象
	 *
	 * @param treeNode  TreeNode
	 * @param valueType valueType
	 * @param <T>       泛型标记
	 * @return 转换结果
	 */
	public static <T> T treeToValue(TreeNode treeNode, Class<T> valueType) {
		try {
			return getInstance().treeToValue(treeNode, valueType);
		} catch (JsonProcessingException e) {
			throw Exceptions.unchecked(e);
		}
	}

	/**
	 * 对象转为 json node
	 *
	 * @param value 对象
	 * @return JsonNode
	 */
	public static JsonNode valueToTree(@Nullable Object value) {
		return getInstance().valueToTree(value);
	}

	/**
	 * 判断是否可以序列化
	 *
	 * @param value 对象
	 * @return 是否可以序列化
	 */
	public static boolean canSerialize(@Nullable Object value) {
		if (value == null) {
			return true;
		}
		return getInstance().canSerialize(value.getClass());
	}

476 477 478 479 480 481 482 483 484 485 486
	/**
	 * 对象转 tree
	 *
	 * @param fromValue fromValue
	 * @param <T>       泛型标记
	 * @return 转换结果
	 */
	public static <T extends JsonNode> T treeToValue(Object fromValue) {
		return getInstance().valueToTree(fromValue);
	}

如梦技术's avatar
如梦技术 已提交
487 488 489 490 491
	public static ObjectMapper getInstance() {
		return JacksonHolder.INSTANCE;
	}

	private static class JacksonHolder {
492
		private static final ObjectMapper INSTANCE = new JacksonObjectMapper();
如梦技术's avatar
如梦技术 已提交
493 494 495 496 497 498 499 500
	}

	private static class JacksonObjectMapper extends ObjectMapper {
		private static final long serialVersionUID = 4288193147502386170L;

		private static final Locale CHINA = Locale.CHINA;

		JacksonObjectMapper() {
501
			super(jsonFactory());
如梦技术's avatar
如梦技术 已提交
502 503 504 505 506 507 508 509 510 511 512 513
			super.setLocale(CHINA);
			super.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_DATETIME, CHINA));
			// 单引号
			super.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
			// 忽略json字符串中不识别的属性
			super.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
			// 忽略无法转换的对象
			super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
			super.setTimeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
			super.findAndRegisterModules();
		}

514 515 516 517 518 519 520 521
		private static JsonFactory jsonFactory() {
			return JsonFactory.builder()
				// 可解析反斜杠引用的所有字符
				.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true)
				// 允许JSON字符串包含非引号控制字符(值小于32的ASCII字符,包含制表符和换行符)
				.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS, true)
				.build();
		}
如梦技术's avatar
如梦技术 已提交
522 523
	}
}