Loading... # Jackson ```java public final class JsonUtils { private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class); private static final ObjectMapper MAPPER; static { MAPPER = new ObjectMapper(); MAPPER.registerModule(new Jdk8Module()); MAPPER.registerModule(new JavaTimeModule()); MAPPER.registerModule(new GuavaModule()); MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true); } private JsonUtils() { } @Setter @Getter @ToString public static class Model { private String key1; private String key2; private String key3; private String key4; } /** * 将空字符串""或空数组"[]"转换成空对象"{}"格式 */ public static String toEmptyJsonObject(String json) { if (StringUtils.isBlank(json) || "[]".equals(json.trim())) { return "{}"; } return json; } /** * 将json解析为指定类型,会屏蔽异常 */ public static <T> T stringToObject(String jsonString, Class<T> cla) { if (StringUtils.isBlank(jsonString)) { return null; } try { return MAPPER.readValue(jsonString, cla); } catch (IOException e) { logger.error(String.format("convert json string to obj error, json:%s", jsonString), e); return null; } } /** * 将json解析为指定类型,会屏蔽异常 */ public static <T> T stringToObject(String jsonString, TypeReference<T> typeReference) { if (StringUtils.isBlank(jsonString)) { return null; } try { return MAPPER.readValue(jsonString, typeReference); } catch (IOException e) { logger.error(String.format("convert json string to obj error, json:%s", jsonString), e); return null; } } /** * 将对象序列化为字符串,会屏蔽异常 */ public static String objectToString(Object object) { if (object == null) { return null; } try { return MAPPER.writer().writeValueAsString(object); } catch (IOException e) { logger.error(String.format("convert obj to json string error, obj:%s", object), e); return null; } } /** * 将json转换为指定的对象,该方法将异常抛出交由上层处理 */ public static <T> T stringToObject2(String jsonString, Class<T> cla) { if (StringUtils.isBlank(jsonString)) { return null; } try { return MAPPER.readValue(jsonString, cla); } catch (IOException e) { throw new ServiceException(e); } } /** * 将json转换为指定的类型,该方法将异常抛出交由上层处理 */ public static <T> T stringToObject2(String jsonString, TypeReference<T> typeReference) { if (StringUtils.isBlank(jsonString)) { return null; } try { return MAPPER.readValue(jsonString, typeReference); } catch (IOException e) { throw new ServiceException(e); } } /** * 将对象转换为json,该方法将异常抛出交由上层处理 */ public static String objectToString2(Object object) { if (object == null) { return null; } try { return MAPPER.writer().writeValueAsString(object); } catch (IOException e) { throw new ServiceException(e); } } /** * 判断是否为json字符串 */ public static boolean isValidJson(String json) { if(!json.startsWith("{")){ return false; } try { MAPPER.readTree(json); return true; } catch (JsonProcessingException e) { return false; } catch (IOException e) { return false; } } public static ObjectMapper mapper() { return MAPPER; } public static ObjectReader reader() { return MAPPER.reader(); } } ``` ```java @Configuration public class BeanConfiguration { @Bean @Primary @ConditionalOnMissingBean(ObjectMapper.class) public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { ObjectMapper objectMapper = builder.createXmlMapper(false).build(); // 通过该方法对mapper对象进行设置,所有序列化对象都按此规则执行 // ALWAYS 默认全部序列化 // NON_NULL 为NULL不序列化 // NON_ABSENT 为NULL、Optional、AtomicReference不序列化 // NON_EMPTY 为 NON_ABSENT 以及为 ""不序列化 // NON_DEFAULT 为默认值不序列化 // CUSTOM 符合过滤条件的不序列化 // USE_DEFAULTS指定合理的默认值,配合NON_DEFAULT objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // Doc:http://fasterxml.github.io/jackson-core/javadoc/2.9/ // ALLOW_UNQUOTED_CONTROL_CHARS 允许出现特殊字符和转义字符 // ALLOW_SINGLE_QUOTES 允许出现单引号 // ... objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true); // 自定义处理:NULL 转为 "" objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(""); } }); return objectMapper; } } ``` **自定义写法2:**秒时间戳和其Date的转换 ```java public class Long2DateSerializer extends JsonSerializer<Long> { @Override // 写法一:返回void就用JsonGenerator写入 public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (value == null || value == 0) { gen.writeNull(); return; } // 防止误传毫秒 if (value.toString().length() == 13) { value = value / 1000; } Date date = new Date(value * 1000); jgen.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)); } } ``` ```java public class Long2DateDeserializer extends JsonDeserializer<Long> { @Override // 写法二:返回Long则直接return public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { String value = jp.getValueAsString(); if (StringUtils.isBlank(value)) { return null; } //兼容就是Long 类型的值 try { return Long.valueOf(value); } catch (Exception e) { try { return DateUtil.Str20ToDate(value).getTime() / 1000; } catch (ParseException pe) { throw new RuntimeException("data string is not format 'yyyy-MM-dd HH:mm:ss'"); } } } } ``` --- `@JsonFormat` 主要是后台到前台的时间格式的转换 `@DataFormAT` 主要是前后到后台的时间格式的转换 ```java @Data public class TestEntity extends BaseEntity { private static final long serialVersionUID = 1L; private String one; @JsonSerialize(using = Date20Serializer.class) @JsonDeserialize(using = Date20Deserializer.class) private Long createTime; @JsonFormat(pattern="yyyy-MM-dd HH:mm") private Date createDate; } ``` ```java public class Date20Serializer extends JsonSerializer<Long> { @Override public void serialize(Long value, JsonGenerator jgen, SerializerProvider provider) throws IOException { if (value == null || value == 0) { jgen.writeNull(); return; } if (value.toString().length() == 13) {//防止误传毫秒 value = value / 1000; } Date date = DateUtil.fromSecond(value); jgen.writeString(DateUtil.dateToString20(date)); } } ``` ```java public class Date20Deserializer extends JsonDeserializer<Long> { @Override public Long deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { String value = jp.getValueAsString(); if (StringUtils.isBlank(value)) { return null; } //兼容就是Long 类型的值 try { return Long.valueOf(value); } catch (Exception e) { try { return DateUtil.Str20ToDate(value).getTime() / 1000; } catch (ParseException pe) { throw new RuntimeException("data string is not format 'yyyy-MM-dd HH:mm:ss'"); } } } } ``` ```java @Controller public class ExceptionHandlingController { @Autowired private TestDao testDao; @ResponseBody @RequestMapping(value = "/test", method = RequestMethod.GET) public JsonResult test(TestEntity test) { System.out.println(test.toString()); System.out.println("---"); TestEntity entity = testDao.getById(1); entity.setCreateDate(new Date(System.currentTimeMillis())); System.out.println(entity.toString()); return JsonResult.success(entity); } } ``` **暗坑1:**`@JsonFormat`返回前端生效必须返回整个实体类,只返回其中的 `createDate`字段是不会生效的。 **暗坑2:**在服务器上部署的时候,可能会出现时间差,需要配置为 `@JsonFormat(pattern="yyyy-MM-dd", timezone = "GMT+8")` **暗坑3:**反序列化不会像序列化一样自动执行,必须调用 `ObjectMapper.readValue(String content, Class<T> valueType)`,所以一般是后端接收前端form传来的值后调用JsonUtil的 `objectToString()`,这时候才进行反序列化操作。转换过程为: `Base64`->`ArrayNode`->`JsonNode`->`String/Integer/Long/...`->`ObjectMapper.readValue()` ![](https://blog-picture01.oss-cn-shenzhen.aliyuncs.com/img/20210425094800.png) Last modification:August 22, 2022 © Allow specification reprint Like 0 喵ฅฅ