1. 返回json
1. 依赖
-
Spring Boot
默认集成JackJson
,无需依赖 -
SSM
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.1</version> </dependency>
2. 简单使用
-
常用注解
-
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
-
修饰
属性
或者setter
方法 -
将
时间类型
成员变量的入参以及序列化格式
转化为字符串
-
入参
同样的作用:@DateTimeFormat(pattern = "yyyy-MM-dd") --> org.springframework.format.annotation.DateTimeFormat
-
栗子
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") private Date date;
-
-
@JsonProperty
-
修饰
属性
-
将成员变量
序列化
为另一个名称,反序列化时也只接受另一个名称的参数
-
栗子
@JsonProperty("sub_button") private List<WxMenuButtonBean> subButtons;
-
-
@JsonAlias
-
修饰
属性
-
反序列化时只接受另一个名称的参数
,优先级在@JsonProperty
之上 -
栗子
// 反序列化时,接受"subButtons"、"sub_button",序列化为 "sub_button" @JsonProperty("sub_button") @JsonAlias({"subButtons", "sub_button"}) private List<WxMenuButtonBean> subButtons;
-
-
@JsonIgnore
- 修饰
属性
、方法
序列化/反序列化时忽略掉修饰的属性
- 修饰
-
@JsonIgnoreProperties
-
在序列化/反序列化时忽略掉某些属性
-
可看作
@JsonIgnore
的批量操作 -
当类似于
代理类
无法使用@JsonIgnore
,则可用@JsonIgnoreProperties
-
栗子
// 忽略"属性1", "属性2",忽略未知属性 @JsonIgnoreProperties(value = {"属性1", "属性2"}, ignoreUnknown = true)
-
-
@JsonSerialize(using = StdSerializer.class)
-
自定义序列化时,修饰
需要自定义序列化的类
,StdSerializer.class
为自定义序列化类 -
简写了以下的
注册
代码ObjectMapper mapper = new ObjectMapper(); // Module SimpleModule module = new SimpleModule("name", new Version(1, 0, 0, null, null, null)); module.addDeserializer(WxIndustryBean.class, new JsonDeserializer()); // 注册 mapper.registerModule(module);
-
栗子:
toJson()
@Getter @Setter @JsonSerialize(using = WxIndustryBean.WxIndustryBeanSerializer.class) public class WxIndustryBean implements JsonService<WxIndustryBean> { private static final long serialVersionUID = -1277224438711154747L; @JsonAlias("primary_industry") private Industry primaryIndustry; @JsonAlias("secondary_industry") private Industry secondaryIndustry; private WxIndustryBean() { } @Override public String toJson() { ObjectMapper mapper = new ObjectMapper(); // // Module // SimpleModule module = new SimpleModule(); // module.addSerializer(WxIndustryBean.class, new WxIndustryBeanSerializer()); // // 注册 // mapper.registerModule(module); // 使用了 @JsonSerialize(using = WxIndustryBean.WxIndustryBeanSerializer.class),可简写,忽略以上代码 try { return mapper.writeValueAsString(this); } catch (Exception e) { throw new RuntimeException("WxIndustryBean 序列化失败"); } } /** * 初始化 * * @param primaryIndustryId 主行业 Id * @param secondaryIndustryId 副行业 Id * @return {@link WxIndustryBean} */ public static WxIndustryBean getInstance(String primaryIndustryId, String secondaryIndustryId) { WxIndustryBean bean = new WxIndustryBean(); bean.setPrimaryIndustry(Industry.getInstance(primaryIndustryId)); bean.setSecondaryIndustry(Industry.getInstance(secondaryIndustryId)); return bean; } /** * 微信公众号行业信息 */ @Data static class Industry implements Serializable { private static final long serialVersionUID = -3974402817176452594L; /** * 公众号模板消息所属行业编号 */ @JsonIgnore private String industryId; /** * 主行业 */ @JsonAlias("first_class") private String firstClass; /** * 副行业 */ @JsonAlias("second_class") private String secondClass; /** * 初始化 * * @param industryId 所属行业编号 * @return {@link Industry} */ static Industry getInstance(String industryId) { if (StrUtil.isBlank(industryId)) { throw new IllegalArgumentException("行业编号不能为空"); } Industry industry = new Industry(); industry.setIndustryId(industryId); return industry; } } /** * 序列化类 */ static class WxIndustryBeanSerializer extends StdSerializer<WxIndustryBean> { private static final long serialVersionUID = -2688346808314421783L; WxIndustryBeanSerializer() { this(null); } protected WxIndustryBeanSerializer(Class<WxIndustryBean> t) { super(t); } @Override public void serialize(WxIndustryBean value, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeStartObject(); Industry industry; gen.writeStringField("industry_id1", Objects.nonNull(value) && Objects.nonNull(industry = value.getPrimaryIndustry()) ? industry.getIndustryId() : null); gen.writeStringField("industry_id2", Objects.nonNull(value) && Objects.nonNull(industry = value.getSecondaryIndustry()) ? industry.getIndustryId() : null); gen.writeEndObject(); } } }
-
-
@JsonDeserialize(using = StdDeserializer.class)
-
自定义
反序列化
时,修饰需要自定义序列化的类
,StdDeserializer.class
为自定义序列化类 -
简写了以下
注册
代码ObjectMapper mapper = new ObjectMapper(); // Module SimpleModule module = new SimpleModule("JsonDeserializer", new Version(1, 0, 0, null, null, null)); module.addDeserializer(WxIndustryBean.class, new JsonDeserializer()); // 注册 mapper.registerModule(module);
-
与
@JsonSerialize(using = StdSerializer.class)
使用类似
-
-
-
最常用
Api
是基于对象绑定
的ObjectMapper
-
规则
- 如果字段的修饰符是
public
,则该字段可序列化和反序列化(不是标准写法)。 - 如果字段的修饰符
不是 public
,但是它的getter
方法和setter
方法是public
,则该字段可序列化和反序列化。getter 方法用于序列化
,setter 方法用于反序列化
。 - 如果字段只有
public
的setter
方法,而无public
的getter
方 法,则该字段只能用于反序列化 - 如果想更改默认的序列化和反序列化规则,需要调用
ObjectMapper
的setVisibility()
方法。否则将会抛出InvalidDefinitionException
异常。 getter、setter
方法要遵循小驼峰命名法
,否则可能出现属性的序列化、反序列化失败
- 如果字段的修饰符是
-
常用配置
ObjectMapper mapper = new ObjectMapper(); // 忽略无法识别的字段 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 在序列化时,忽略值为 null 的属性 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略值为默认值的属性 // mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT); // 时间格式 mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
-
序列化
// 将对象序列化为字符串 String writeValueAsString(Object value) // 将对象序列化为字节数组 byte[] writeValueAsBytes(Object value) // 将对象序列化存储到文件 writeValue(File resultFile, Object value)
-
反序列化
- 反序列化时要求对象必须有
默认构造方法
,否则抛出InvalidDefinitionException
异常
// Json 序列化为 T 对象 <T> T readValue(String content, Class<T> valueType) // byte[] 序列化为 T 对象 <T> T readValue(byte[] src, Class<T> valueType) // 生成 JSONNode 对象 // 利用 jsonNode.get() 方法读取 JsonNode readTree(String content) // 利用 TypeReference 可指定泛型,生成 Map、List 等对象 <T> T readValue(String content, TypeReference<T> valueTypeRef) // 也可指定泛型,生成 Map、List 等对象,少用 <T> T readValue(String content, JavaType valueType)
- 栗子
String json = "{\"name\": \"haha\", \"phone\": 123}"; ObjectMapper mapper = new ObjectMapper(); // JsonNode readTree(String content) JsonNode jsonNode = mapper.readTree(json); System.out.println(jsonNode.get("name").asText()); // <T> T readValue(String content, TypeReference<T> valueTypeRef) Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>() { }); map.forEach((k, v) -> System.out.println(k + " = " + v)); // <T> T readValue(String content, JavaType valueType) Map<String, Object> o = mapper.readValue(json, TypeFactory.defaultInstance().constructMapType(Map.class, String.class, Object.class)); o.forEach((k, v) -> System.out.println(k + " = " + v));
- 反序列化时要求对象必须有
-
工具类
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.TypeFactory; import lombok.extern.slf4j.Slf4j; import java.text.SimpleDateFormat; import java.util.List; import java.util.Map; import java.util.Set; /** * Json 相关工具类 * * @author sheng_zs@126.com * @date 2021-08-05 15:57 */ @Slf4j public class JsonUtils { private static final ObjectMapper MAPPER; static { ObjectMapper mapper = new ObjectMapper(); // 忽略无法识别的字段 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 在序列化时,忽略值为 null 的属性 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略值为默认值的属性 // mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT); // 时间格式 mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); MAPPER = mapper; } /** * 将 json 字符串转化为 Java Bean * * @param target json 字符串 * @param cls Java Bean 的字节码对象 * @param <T> 泛型 * @return Java Bean */ public static <T> T readValue(String target, Class<T> cls) { try { return MAPPER.readValue(target, cls); } catch (Exception e) { log.error("json [{}] to bean [{}] 错误", target, cls); throw new RuntimeException(e.getMessage()); } } /** * <p>将 json 字符串转化为 T 对象</p><br> * 栗子: * <ol> * <li>Set<String> set = readValue("[\"1\"]", new TypeReference<Set<String>>() {});</li> * <li>List<String> list = readValue("[\"1\"]", new TypeReference<List<String>>() {});</li> * <li>Map<String, Object> map = readValue("{\"1\": \"a\"}", new TypeReference<Map<String, Object>>() {});</li> * </ol> * * @param target json * @param type {@link TypeReference} new TypeReference<T>{} * @param <T> 泛型,转化的对象类型 * @return T */ public static <T> T readValue(String target, TypeReference<T> type) { try { return MAPPER.readValue(target, type); } catch (Exception e) { log.error("json [{}] to List [e:{}] 错误", target, type); throw new RuntimeException(e.getMessage()); } } /** * <p>将 json 字符串转化为 Map<K, V> 对象</p> * * @param target json 字符串 * @param kCls key 类型 * @param vCls value 类型 * @param <K> key 泛型 * @param <V> value 泛型 * @return Map<K, V> */ public static <K, V> Map<K, V> readValueAsMap(String target, Class<K> kCls, Class<V> vCls) { try { JsonNode jsonNode = MAPPER.readTree(target); return MAPPER.readValue(target, TypeFactory.defaultInstance().constructMapType(Map.class, kCls, vCls)); } catch (Exception e) { log.error("json [{}] to Map [k:{}, v:{}] 错误", target, kCls, vCls); throw new RuntimeException(e.getMessage()); } } /** * <p>将 json 字符串转化为 Map<String, Object> 对象</p> * * @param target json 字符串 * @return Map<String, Object> */ public static Map<String, Object> readValueAsMap(String target) { return readValue(target, new TypeReference<Map<String, Object>>() { }); } /** * <p>将 json 字符串转化为 List<E> 对象</p> * * @param target json 字符串 * @param eCls 成员字节码对象 * @param <E> 成员 泛型 * @return List<E> */ public static <E> List<E> readValueAsList(String target, Class<E> eCls) { try { return MAPPER.readValue(target, TypeFactory.defaultInstance().constructCollectionType(List.class, eCls)); } catch (Exception e) { log.error("json [{}] to List [e:{}] 错误", target, eCls); throw new RuntimeException(e.getMessage()); } } /** * <p>将 json 字符串转化为 Set<E> 对象</p> * * @param target json 字符串 * @param eCls 成员字节码对象 * @param <E> 成员 泛型 * @return Set<E> */ public static <E> Set<E> readValueAsSet(String target, Class<E> eCls) { try { return MAPPER.readValue(target, TypeFactory.defaultInstance().constructCollectionType(Set.class, eCls)); } catch (Exception e) { log.error("json [{}] to Set [e:{}] 错误", target, eCls); throw new RuntimeException(e.getMessage()); } } /** * 将 json 字符串转化为 JsonNode 对象 * * @param target json 字符串 * @return {@link JsonNode} */ public static JsonNode readTree(String target) { try { return MAPPER.readTree(target); } catch (Exception e) { log.error("json [{}] to JsonNode 错误", target); throw new RuntimeException(e.getMessage()); } } /** * 将 Java Bean o 转化为 字符串 * * @param o Java Bean * @return Json 字符串 */ public static String writeValueAsString(Object o) { try { return MAPPER.writeValueAsString(o); } catch (Exception e) { log.error("bean [{}] to json 错误", o); throw new RuntimeException(e.getMessage()); } } /** * 将 Java Bean o 转化为 byte[] * * @param o Java Bean * @return 字节数组 */ public static byte[] writeValueAsBytes(Object o) { try { return MAPPER.writeValueAsBytes(o); } catch (Exception e) { log.error("bean [{}] to byte[] 错误", o); throw new RuntimeException(e.getMessage()); } } }
-
-
自定义序列化和反序列化
-
序列化
- 继承
StdSerializer
- 重写
serialize()
方法 - 利用
JsonGenerator
生成JSON
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import lombok.AllArgsConstructor; import lombok.Data; import java.io.IOException; /** * @author sheng_zs@126.com * @date 2021-08-06 14:46 */ public class Test { public static void main(String[] args) throws JsonProcessingException { /* 要想调用 自定义序列化 类,需注册到 ObjectMapper 的 Module */ ObjectMapper mapper = new ObjectMapper(); // Module SimpleModule module = new SimpleModule("JsonSerializerTest", new Version(1, 0, 0, null, null, null)); module.addSerializer(TestBean.class, new JsonSerializerTest()); // 注册 mapper.registerModule(module); TestBean haha = new TestBean("haha", "11"); String s = mapper.writeValueAsString(haha); System.out.println(s); } } class JsonSerializerTest extends StdSerializer<TestBean> { public JsonSerializerTest() { this(null); } protected JsonSerializerTest(Class<TestBean> t) { super(t); } @Override public void serialize(TestBean value, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeStartObject(); gen.writeStringField("name", "姓名:" + value.getName() + ",测试自定义序列化"); gen.writeStringField("phone", "手机:" + value.getPhone() + ",哈哈的手机号,不填也可"); gen.writeEndObject(); } } @Data @NoArgsConstructor @AllArgsConstructor @ToString class TestBean { private String name; private String phone; }
- 继承
-
反序列化
- 继承
StdDeserializer
- 重写
deserialize()
方法 - 利用
JsonGenerator
读取JSON
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import java.io.IOException; /** * @author sheng_zs@126.com * @date 2021-08-06 14:46 */ public class Test { public static void main(String[] args) throws JsonProcessingException { /* 要想调用 自定义反序列化 类,需注册到 ObjectMapper 的 Module */ ObjectMapper mapper = new ObjectMapper(); // Module SimpleModule module = new SimpleModule("JsonDeserializerTest", new Version(1, 0, 0, null, null, null)); module.addDeserializer(TestBean.class, new JsonDeserializerTest()); // 注册 mapper.registerModule(module); String json = "{\"name\":\"姓名:haha,测试自定义序列化\",\"phone\":\"手机:11,哈哈的手机号,不填也可\"}"; TestBean bean = mapper.readValue(json, TestBean.class); System.out.println(bean); } } class JsonDeserializerTest extends StdDeserializer<TestBean> { public JsonDeserializerTest() { this(null); } protected JsonDeserializerTest(Class<?> vc) { super(vc); } @Override public TestBean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { /* 1. 通过 JsonNode 把 JSON 读取到一个树形结构中 2. 然后通过 JsonNode 的 get 方法将对应字段读取出来 3. 然后生成新的 Java 对象,并返回 */ TestBean testBean = new TestBean(); JsonNode node = p.getCodec().readTree(p); String name = node.get("name").asText(); testBean.setName((name = name.replaceFirst("姓名:", "")).substring(0, name.lastIndexOf(",测试自定义序列化"))); String phone = node.get("phone").asText(); testBean.setPhone((phone = phone.replaceFirst("手机:", "")).substring(0, phone.lastIndexOf(",哈哈的手机号,不填也可"))); return testBean; } } @Data @NoArgsConstructor @AllArgsConstructor @ToString class TestBean { private String name; private String phone; }
- 继承
-
2. 返回xml
1. 依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.10.1</version>
</dependency>
2. 简单使用
- 实体类
@Data @JacksonXmlRootElement(localName = "哈哈") public class TestDTO { @JacksonXmlProperty(localName = "Nihao") private String name; @JacksonXmlProperty(localName = "地址") private String addr; @JacksonXmlProperty(localName = "年龄") private Integer age; }
- controller
@PostMapping(produces = MediaType.APPLICATION_XML_VALUE) public Object h(@RequestBody TestDTO dto) { System.out.println(dto); return dto; }
- 结果
@JacksonXmlRootElement
修饰根标签,传入的时候可以按照原有的类名,也可以按照属性localName
的值@JacksonXmlProperty
修饰属性,传入的时候必须按照属性localName
的值