当前位置: 首页 > news >正文

绵竹网站制作中国建筑设计网站

绵竹网站制作,中国建筑设计网站,网站建设起到计划和指导作用,php购物网站开发背景写在前面 虽然现在市面上有很多优秀的json解析库#xff0c;但 Spring默认采用Jackson解析Json。 本文将通过一系列通俗易懂的代码示例#xff0c;带你逐步掌握 Jackson 的基础用法、进阶技巧以及在实际项目中的应用场景。 一、Jackjson简介 Jackson 是当前用的比较广泛的但 Spring默认采用Jackson解析Json。 本文将通过一系列通俗易懂的代码示例带你逐步掌握 Jackson 的基础用法、进阶技巧以及在实际项目中的应用场景。 一、Jackjson简介 Jackson 是当前用的比较广泛的用来序列化和反序列化 json 的 Java 的开源框架。 什么是序列化和反序列化呢 序列化将 Java Bean 转换为JSON 字符串 反序列化将JSON字符串转换为JavaBeen对象 GitHub地址GitHub - FasterXML/jackson: Main Portal page for the Jackson project 从GitHub 看到目前有8.8k stars最近更新时间是2个月前。可见其更新速度还是比较活跃的 也是json最流行的解析器之一 二、Jackjson优点 Jackson 所依赖的 jar 包较少简单易用 其他 Java 的 json 的框架 Gson 等相比 Jackson 解析大的 json 文件速度比较快 Jackson 运行时占用内存比较低性能比较好 Jackson 有灵活的 API可以很容易进行扩展和定制 三、Jackjson模块及依赖 ① Jackson库包括三个主要的模块 jackson-databind用于数据绑定 jackson-core用于JSON解析和生成 jackson-annotations用于注解支持 ② 所需依赖 jackson-databind 依赖 jackson-core 和 jackson-annotations所以可以只显示地添加jackson-databind依赖jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中 maven dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-core/artifactIdversion2.15.3/version /dependency dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-annotations/artifactIdversion2.15.2/version /dependency dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.15.2/version /dependency Gradle dependencies {implementation com.fasterxml.jackson.core:jackson-databind:2.13.4 } 四、快速上手 假设我们有一个简单的 User 类 Data ToString AllArgsConstructor NoArgsConstructor public class User {private String name;private int age; } 4.1 Java对象转JSON字符串 Test public void testSerializationExample() throws JsonProcessingException {User user new User(小凡, 18);ObjectMapper objectMapper new ObjectMapper();String userstr objectMapper.writeValueAsString(user);System.out.println(userstr); } //输出 {name:小凡,age:18} 4.2 JSON字符串转Java对象 Test public void testDeserializationExample() throws JsonProcessingException {String json {\name\:\小凡\,\age\:18};ObjectMapper objectMapper new ObjectMapper();User user objectMapper.readValue(json, User.class);System.out.println(user);} //输出 User(name小凡, age18) 上面例子中我们我们使用了ObjectMapper 它是 Jackson 库的核心类负责实现 Java 对象与 JSON 文本之间的相互转换 五、Jackjson序列化API 5.1 普通Java对象序列化 Test public void testObjectToJson() throws JsonProcessingException {User user new User();user.setName(小凡);user.setAge(18);ObjectMapper mapper new ObjectMapper();String userstr mapper.writeValueAsString(user);System.out.println(userstr); } //输出 {name:小凡,age:18} 5.2 复杂对象序列化 ① 构造作者出版信息对象 //书籍对象 Data public class Book {private String bookName;private String publishDate;private String publishHouse;private Double price;} //地址对象 Data public class Address {private String city;private String street; } //作者出版信息对象 Data public class PublishInfo {private String name;private String sex;private Integer age;private Address addr;private ListBook books; } ② 复杂对象转JSON字符串 Test public void testComplexObjectToJson() throws JsonProcessingException {//构造所有出版的书籍listArrayListBook books new ArrayListBook();Book book1 new Book();book1.setBookName(Java从入门到放弃);book1.setPublishDate(2004-01-01);book1.setPublishHouse(小凡出版社);book1.setPrice(66.66);Book book2 new Book();book2.setBookName(Spring从入门到入土);book2.setPublishDate(2024-01-01);book2.setPublishHouse(小凡出版社);book2.setPrice(88.88);books.add(book1);books.add(book2);//构造作者地址信息Address addr new Address();addr.setCity(昆明);addr.setStreet(xxx区xxx路xxx号);//构造作者出版的所有书籍信息PublishInfo publishInfo new PublishInfo();publishInfo.setName(小凡);publishInfo.setSex(男);publishInfo.setAge(18);publishInfo.setAddr(addr);publishInfo.setBooks(books);ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(publishInfo);System.out.println(json); } //返回 {name:小凡,sex:男,age:18,addr:{city:昆明,street:xxx区xxx路xxx号},books:[{bookName:Java从入门到放弃,publishDate:2004-01-01,publishHouse:小凡出版社,price:66.66},{bookName:Spring从入门到入土,publishDate:2024-01-01,publishHouse:小凡出版社,price:88.88}]} 5.3 List集合序列化 Test public void testListToJson() throws JsonProcessingException {User user1 new User();user1.setName(小凡001);user1.setAge(18);User user2 new User();user2.setName(小凡002);user2.setAge(30);ArrayListUser users new ArrayList();users.add(user1);users.add(user2);ObjectMapper mapper new ObjectMapper();String userstr mapper.writeValueAsString(users);System.out.println(userstr);} //输出 [{name:小凡001,age:18},{name:小凡002,age:30}] 5.4 Map集合序列化 ① Test public void testMapToJson() throws JsonProcessingException {User user new User();user.setName(小凡);user.setAge(18);ListString asList Arrays.asList(抽烟, 喝酒, 烫头发);HashMapString, Object map new HashMap();map.put(user, user);map.put(hobby,asList);ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(map);System.out.println(json); } //输出 {user:{name:小凡,age:18},hobby:[抽烟,喝酒,烫头发]} ② Test public void testMapToJsonSup() throws JsonProcessingException {User user1 new User();user1.setName(小凡001);user1.setAge(18);User user2 new User();user2.setName(小凡002);user2.setAge(30);ArrayListUser users new ArrayList();users.add(user1);users.add(user2);ListString asList Arrays.asList(抽烟, 喝酒, 烫头发);HashMapString, Object map new HashMap();map.put(users, users);map.put(hobby,asList);map.put(name,张三);ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(map);System.out.println(json); } //输出 {name:张三,users:[{name:小凡001,age:18},{name:小凡002,age:30}],hobby:[抽烟,喝酒,烫头发]} 5.5 日期处理 默认情况下jackjson会将日期类型属性序列化成long型值自1970年1月1日以来的毫秒数。显然这样格式的数据不符合人类直观查看 假设我们有个Person对象 Data public class Person {private String name;private Date birthday; } ① 我们先来看看默认转换的结果 Test public void testDateToJsonDefault() throws JsonProcessingException {Person person new Person();person.setName(小凡);person.setBirthday(new Date());ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(person);System.out.println(json);} //输出 {name:小凡,birthday:1712220896407} ② 通过SimpleDateFormat 将日期格式化成人类可看格式显示 Test public void testDateToJson() throws JsonProcessingException {Person person new Person();person.setName(小凡);person.setBirthday(new Date());ObjectMapper mapper new ObjectMapper();//进行一下日期转换SimpleDateFormat dateFormat new SimpleDateFormat(yyyy-MM-dd);mapper.setDateFormat(dateFormat);String json mapper.writeValueAsString(person);System.out.println(json);} //输出 这个格式就人性化多了 {name:小凡,birthday:2024-04-04} 六、Jackjson反序列化API Jackson通过将JSON字段的名称与Java对象中的getter和setter方法进行匹配将JSON对象的字段映射到Java对象中的属性。 Jackson删除了getter和setter方法名称的“ get”和“ set”部分并将其余名称的第一个字符转换为小写。 6.1 普通JSON字符串反序列化 6.1.1 JSON字符串-Java对象 注 这里我们还是使用前面小节中创建的User 实体类 Test public void testStrToObject() throws JsonProcessingException {String json {\name\:\小凡\,\age\:18};ObjectMapper mapper new ObjectMapper();User user mapper.readValue(json, User.class);System.out.println(user); } //输出 User(name小凡, age18) 6.1.2 字符输入流--Java对象 Test public void testReaderToObject() throws JsonProcessingException {String json {\name\:\小医仙\,\age\:18};Reader reader new StringReader(json);ObjectMapper mapper new ObjectMapper();User user mapper.readValue(json, User.class);System.out.println(user); } //输出 User(name小医仙, age18) 6.1.3 字节输入流-Java对象 ① 创建user001.json文件文件内容如下 ②将字节输入流转换为User对象 Test public void testInputStreamToObject() throws IOException {FileInputStream inputStream new FileInputStream(F:\\vueworkspace\\jackjson-demo\\jackjson-demo\\src\\json\\user001.json);ObjectMapper mapper new ObjectMapper();User user mapper.readValue(inputStream, User.class);System.out.println(user);} } //输出 User(name萧炎, age18) 6.1.4 JSON 文件反-Java对象 ①我们准备一个user.json文件内容如下 ② 读取user.json文件中内容并转换成User 对象 Test public void testJsonfileToObject() throws IOException {File file new File(F:\\vueworkspace\\jackjson-demo\\jackjson-demo\\src\\json\\user.json);ObjectMapper mapper new ObjectMapper();User user mapper.readValue(file, User.class);System.out.println(user);} //输出 User(name萧炎, age18) 6.1.5 URL文件-Java对象 ① 我们在网络上放一个user.json资源文件内容如下 {name:紫妍,age:18} ② 通过URL(java.net.URL) 将JSON转换成User对象 Test public void testUrlToObject() throws IOException {String url https://files.cnblogs.com/files/blogs/685650/user.json;URL url1 new URL(url);ObjectMapper mapper new ObjectMapper();User user mapper.readValue(url1, User.class);System.out.println(user); } //输出 User(name紫妍, age18) 6.1.6 字节数组- java对象 Test public void testByteToObject() throws IOException {String json {\name\:\韩雪\,\age\:18};byte[] bytes json.getBytes();ObjectMapper mapper new ObjectMapper();User user mapper.readValue(bytes, User.class);System.out.println(user);} //输出 User(name韩雪, age18) 6.2 JSON数组字符串 反序列化 6.2.1 JSON字符串-Map集合 Test public void testJsonStrToMap() throws JsonProcessingException {//{name:小凡,sex:男,age:18}String json {\name\:\小凡\,\sex\:\男\,\age\:18};ObjectMapper mapper new ObjectMapper();MapString, Object map mapper.readValue(json, new TypeReferenceMapString, Object() {});System.out.println(map); } //输出 {name小凡, sex男, age18} 6.2.2 JSON数组字符串-List集合 Test public void testJsonArrToList() throws JsonProcessingException {//[{name:小凡001,age:18},{name:小凡002,age:30}]String json [{\name\:\小凡001\,\age\:18},{\name\:\小凡002\,\age\:30}];ObjectMapper mapper new ObjectMapper();ListUser users mapper.readValue(json, new TypeReferenceListUser() {});System.out.println(users); } //输出 [User(name小凡001, age18), User(name小凡002, age30)] 6.2.3 JSON数组字符串-Java对象数据 Test public void testJsonArrToObjArr() throws JsonProcessingException {//[{name:小凡001,age:18},{name:小凡002,age:30}]String json [{\name\:\小凡001\,\age\:18},{\name\:\小凡002\,\age\:30}];ObjectMapper mapper new ObjectMapper();User[] users mapper.readValue(json, User[].class);for (User user : users) {System.out.println(user);} } //输出 User(name小凡001, age18) User(name小凡002, age30) 七、自定义序列化反序列化 通过自定义序列化和反序列化可以使其更加灵活多变 7.1 自定义序列化 有时候我们不需要jackjson默认的序列化方式。例如JSON中使用与Java对象中不同的属性名称 或者不需要Java对象中的某个字段这时我们就需要自定义序列化器 我们先来看看User实体对象的定义如下 Data public class User {private String name;private Integer age; } 按照下面默认序列化代码我们最后得到的JSON字符串如下 Test public void testSerializationExample() throws JsonProcessingException {User user new User(小凡, 18);ObjectMapper objectMapper new ObjectMapper();String userstr objectMapper.writeValueAsString(user);System.out.println(userstr); } //输出 {name:小凡,age:18} 而现在的需求升级了再不创建或修改Users实体对象的情况下我们想要得到{username:小凡,userage:18} 这样的字符串 应该怎么办呢 这时我们就需要自定义序列化器就可以轻松实现具体代码如下 Test public void testDefineSerialize() throws JsonProcessingException {SimpleModule version1Module new SimpleModule();version1Module.addSerializer(User.class, new JsonSerializerUser() {Overridepublic void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {jsonGenerator.writeStartObject();jsonGenerator.writeStringField(username, user.getName());jsonGenerator.writeNumberField(userage, user.getAge());jsonGenerator.writeEndObject();}});ObjectMapper objectMapper new ObjectMapper();objectMapper.registerModule(version1Module);User user new User(小凡, 18);String json objectMapper.writeValueAsString(user); // 使用版本1的序列化器System.out.println( json);} //输出 {username:小凡,userage:18} 7.2 自定义反序列化器 同理反序列化也可以自定义具体代码如下 ① 自定义一个反序列化器 public class UserDeserializer extends StdDeserializerUser {public UserDeserializer() {this(null);}public UserDeserializer(Class? vc) {super(vc);}Overridepublic User deserialize(JsonParser jp, DeserializationContext ctxt)throws IOException {JsonNode node jp.getCodec().readTree(jp);String name node.get(name).asText();int age (Integer) ((IntNode) node.get(age)).numberValue();return new User(name, age);} } ②将JSON字符串反序列化为 User 对象 Test public void testUserDeserializer() throws JsonProcessingException {ObjectMapper objectMapper new ObjectMapper();SimpleModule module new SimpleModule();module.addDeserializer(User.class, new UserDeserializer());objectMapper.registerModule(module);String json {\name\:\小凡\,\age\:30};User user objectMapper.readValue(json, User.class);System.out.println(user);} //输出 User(name小凡, age30) 八、树模型 Jackson具有内置的树模型可用于表示JSON对象。Jackson树模型由JsonNode类表示。 在处理JSON时我们有时并不直接关心或无法直接映射到特定的Java对象而是需要对JSON内容进行动态、灵活的操作。 这时树模型就派上了用场。我们可以遍历、查询、更新或合并JSON数据而无需预先定义对应的Java类 8.1 JsonNode类型概览 JsonNode家族包括以下主要子类型 ObjectNode对应JSON对象包含一组键值对可以通过.put(key, value)添加或更新属性。 ArrayNode对应JSON数组包含一系列元素可通过.add(value)插入新元素。 TextNode、IntNode、LongNode、DoubleNode等分别对应JSON中的字符串、整数、长整数、浮点数等基本类型值。 BooleanNode、NullNode分别对应JSON中的布尔值和null值。 8.2 创建与操作JsonNode实例 下面通过一些具体的代码示例展示如何使用JackJson的树模型API来创建、操作JsonNode对象。 示例1创建简单JsonNode Test public void testJackJsonTreeModelExample(){// 创建 ObjectMapper 实例ObjectMapper mapper new ObjectMapper();// 创建并初始化各类型 JsonNode 实例ObjectNode personNode mapper.createObjectNode();personNode.put(name, 小凡);personNode.put(age, 18);ArrayNode hobbiesNode mapper.createArrayNode();hobbiesNode.add(写代码).add(看书).add(打豆豆);personNode.set(hobbies, hobbiesNode);// 输出构建的 JSON 字符串System.out.println(personNode.toString()); } //输出 {name:小凡,age:18,hobbies:[写代码,看书,打豆豆]} 上述代码首先创建了一个ObjectMapper实例它是JackJson的核心工具类负责序列化和反序列化工作。接着我们创建了一个ObjectNode代表JSON对象设置了name和age两个属性。然后创建了一个ArrayNode存储爱好列表并将其添加到personNode中。最后打印输出构建的JSON字符串。 示例2从JSON字符串反序列化为JsonNode Test public void testJackJsonTreeModelExample2() throws JsonProcessingException {String jsonInput {\name\:\小凡\,\age\:18,\hobbies\:[\写代码\,\看书\,\打豆豆\]};ObjectMapper mapper new ObjectMapper();JsonNode rootNode mapper.readTree(jsonInput);System.out.println(rootNode.get(name).asText());System.out.println(rootNode.get(age).asInt());System.out.println(rootNode.get(hobbies).get(0).asText());System.out.println(rootNode.get(hobbies).get(1).asText());System.out.println(rootNode.get(hobbies).get(2).asText()); } //输出 小凡 18 写代码 看书 打豆豆 在此示例中我们首先定义了一个JSON字符串。然后使用ObjectMapper的readTree()方法将其反序列化为JsonNode。接下来通过调用.get(key)方法访问对象属性或数组元素并使用.asText()、.asInt()等方法获取其值。 8.3 利用JackJson树模型进行深度查询、修改、合并等操作 上面给出的两个案例属于入门级操作我们学会后可以接着进行一些高级操作 Test public void testJsonManipulationExample() throws JsonProcessingException {String JSON_STRING {\name\:\小凡\,\age\:18,\hobbies\:[\写代码\,\看书\,\打豆豆\]};ObjectMapper mapper new ObjectMapper();// 将JSON字符串转换为JsonNode对象JsonNode rootNode mapper.readTree(JSON_STRING);// **深度查询**// 查询年龄int age rootNode.get(age).asInt();System.out.println(Age: age);// 查询第一个兴趣爱好String firstHobby rootNode.get(hobbies).get(0).asText();System.out.println(First hobby: firstHobby);// **修改**// 修改年龄为20((ObjectNode) rootNode).put(age, 20);// 添加新的兴趣爱好旅行((ArrayNode) rootNode.get(hobbies)).add(旅行);// **合并**// 假设有一个新的JSON片段要与原数据合并String additionalJson {\address\:\北京市\,\job\:\程序员\};JsonNode additionalNode mapper.readTree(additionalJson);// 使用ObjectNode#setAll方法将新节点中的键值对合并到原始节点中((ObjectNode) rootNode).setAll((ObjectNode) additionalNode);// 打印更新后的JSON字符串System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode)); } //输出 Age: 18 First hobby: 写代码 {name : 小凡,age : 20,hobbies : [ 写代码, 看书, 打豆豆, 旅行 ],address : 北京市,job : 程序员 } 九、Jackson注解使用 9.1 序列化反序列化通用注解 9.1.1 JsonIgnore JsonIgnore 用于在序列化或反序列化过程中忽略某个属性 ① 定义实体类Person public class Person {private String name;JsonIgnore // 添加此注解以忽略 password 字段private String password;// 构造器、getter/setter 方法等... } ②使用示例 Test public void testJsonIgnore() throws Exception{Person person new Person(小凡, 123456);ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(person); } //输出 {name: 小凡 } ③ 详细解释 JsonIgnore 注解直接放在属性声明前如 private String password; 行上方。 当 Person 类的对象被序列化为 JSON 时password 属性将不会出现在生成的 JSON 字符串中 同样地在反序列化过程中如果 JSON 数据中包含 password 字段Jackson 在解析时会自动忽略它不会尝试将其值设置到对应的 Person 对象属性上。 9.1.2 JsonIgnoreProperties 与JsonIgnore 注解相比JsonIgnoreProperties 用于批量指定在序列化或反序列化过程中应忽略的属性列表特别适用于应对不明确或动态变化的输入 JSON 中可能存在但不应处理的额外字段 ① 定义实体类Person 希望同时忽略 password 和 socialSecurityNumber 两个敏感属性 JsonIgnoreProperties({password, socialSecurityNumber}) public class Person {private String name;private String password;private String socialSecurityNumber;// 构造器、getter/setter 方法等... } ② 使用示例 Test public void testJsonIgnoreProperties() throws Exception{Person person new Person(小凡, 123456,233535);ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(person); } //输出 {name: 小凡 } ③ 详细解释 JsonIgnoreProperties 注解放置在类定义的开始处作为类级别的注解。 注解内通过一个字符串数组参数列举出要忽略的属性名。在这个例子中{password, socialSecurityNumber} 指定了 password 和 socialSecurityNumber 两个属性在序列化和反序列化时应被忽略。 序列化 Person 对象时生成的 JSON 字符串将不包含 password 和 socialSecurityNumber 属性。与前面 JsonIgnore 示例类似JSON 输出仅包含未被忽略的 name 属性 {name: 小凡 } 反序列化时即使输入的 JSON 数据中包含了 password 或 socialSecurityNumber 字段Jackson 也会忽略它们不会尝试将这些字段的值填充到相应的 Person 对象属性中。 ④ JsonIgnoreProperties 还有一个额外功能 JsonIgnoreProperties有个可选的属性 ignoreUnknown用于控制是否忽略 JSON 中存在但 Java 类中没有对应的未知属性。若设置为 true则在反序列化时遇到未知属性时会自动忽略避免抛出异常 JsonIgnoreProperties(ignoreUnknown true) public class Person {// ... } 9.1.3 JsonIgnoreType JsonIgnoreType 注解在 Jackson 库中用于指示整个类在序列化或反序列化过程中应当被忽略。这适用于那些由于某种原因如敏感信息、内部细节等不需要或不应该被 JSON 化处理的类 ①定义CreditCardDetails 实体类 // 标记该类在序列化和反序列化时应被忽略 JsonIgnoreType public class CreditCardDetails {private String cardNumber;private String cvv;private String expirationDate;// 构造器、getter/setter 方法等... } ②定义Customer 类 Customer 类它有一个 creditCardDetails 属性引用上述 CreditCardDetails 类型的对象 public class Customer {private String customerId;private String name;private CreditCardDetails creditCardDetails;// 构造器、getter/setter 方法等... } ③ 使用示例 public void testJsonIgnoreType() throws JsonProcessingException {Customer customer new Customer(CUST001, John Doe, new CreditCardDetails(1234567890123456, 123, 2024-12));ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(customer); } //输出 {customerId: CUST001,name: John Doe } ④ 详细解释 JsonIgnoreType 注解放置在需要忽略的类定义前作为类级别的注解。 当 Customer 类对象被序列化为 JSON 时所有 CreditCardDetails 类型的属性如 customer.creditCardDetails都会被完全忽略不会出现在生成的 JSON 字符串中。例如 在此例中生成的 json 字符串将不含 creditCardDetails 部分仅包含 customerId 和 name {customerId: CUST001,name: John Doe } 同理在反序列化过程中如果 JSON 数据中包含 CreditCardDetails 类型的嵌套结构Jackson 解析时会自动忽略这部分内容不会尝试创建或填充对应的 CreditCardDetails 对象 9.1.4 JsonAutoDetect JsonAutoDetect 用于自定义类的属性包括字段和 getter/setter 方法在序列化和反序列化过程中的可见性规则。默认情况下Jackson 只使用 public 的字段和 public 的 getter/setter 方法。通过使用 JsonAutoDetect你可以根据需要调整这些规则以适应不同类的设计和数据模型。 ① 定义实体类Employee JsonAutoDetect(fieldVisibility JsonAutoDetect.Visibility.NONE, // 不使用字段getterVisibility JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC, // 允许 protected 和 public 的 gettersetterVisibility JsonAutoDetect.Visibility.ANY, // 允许任意访问权限的 setterisGetterVisibility JsonAutoDetect.Visibility.DEFAULT, // 默认行为publiccreatorVisibility JsonAutoDetect.Visibility.DEFAULT) // 默认行为public public class Employee {protected String id;String department; // package-private 字段// 非标准命名的 getterpublic String getIdentification() {return id;}// 非标准命名的 setterpublic void setIdentification(String id) {this.id id;}//...标准getter setter} ②使用示例 Test public void testJsonAutoDetect() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper();Employee employee new Employee();employee.setId(E001);employee.setDepartment(Sales);String json mapper.writeValueAsString(employee);System.out.println(json); } //输出 {identification: E001,department: Sales } ③ 详细解释 在上述 Employee 类的例子中fieldVisibility JsonAutoDetect.Visibility.NONE 指定不使用任何字段意味着即使有 public 字段也不会被 Jackson 处理。getterVisibility JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC 允许 Jackson 使用 protected 和 public 的 getter 方法。setterVisibility JsonAutoDetect.Visibility.ANY 指定可以使用任意访问权限的 setter 方法。isGetterVisibility 和 creatorVisibility 使用默认行为即只处理 public 的 is-getter 方法和构造函数。 因为我们将 id 字段的 getter 和 setter 设为了非标准命名getIdentification() 和 setIdentification()且指定了 getterVisibility JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC所以 Jackson 能正确识别并处理这两个方法尽管它们不是标准的 get 前缀命名。 9.1.5 JsonProperty 用于指定类的属性在序列化和反序列化成 JSON 时所对应的键名 ①Book 实体类 假设有一个 Book 类其中包含 title 和 yearPublished 字段。我们希望在序列化和反序列化时将 yearPublished 字段以 publishedYear 作为 JSON 键名。可以使用 JsonProperty 注解进行重命名 public class Book {private String title;JsonProperty(publishedYear) // 重命名 yearPublished 字段为 publishedYearprivate int yearPublished;// 构造器、getter/setter 方法等... } ②使用示例: 现在创建一个 Book 对象并序列化为 JSON public void testJsonProperty() throws Exception {Book book new Book();book.setTitle(小凡编程语录);book.setYearPublished(1951);ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(book);System.out.println(json); } //输出 {title: 小凡编程语录,publishedYear: 1951 } ③详细解释 在本例中JsonProperty(publishedYear) 表明 yearPublished 字段在 JSON 中应称为 publishedYear 反序列化时当遇到 JSON 中的 publishedYear 键时Jackson 会知道应该将其值赋给 Book 类的 yearPublished 字段。 9.1.6 JsonFormat 用于指定日期、时间、日期时间以及其他数值类型在序列化和反序列化为 JSON 时的格式 ① 创建 Student 类 public class Student {// 其他属性...// 使用 JsonFormat 注解的 LocalDate 属性JsonFormat(shape JsonFormat.Shape.STRING, pattern yyyy-MM-dd)private LocalDate birthday;// 构造器、getter、setter 等... } ②使用示例 注Jackson默认不支持Java 8的日期时间类型java.time.LocalDate如果使用jdk8需要引入如下依赖. dependencygroupIdcom.fasterxml.jackson.datatype/groupIdartifactIdjackson-datatype-jsr310/artifactIdversion最新版本号/version !-- 替换为当前最新的稳定版本 -- /dependency 除了引入以来外还需要确保在使用Jackson进行序列化和反序列化时注册JavaTimeModule mapper.registerModule(new JavaTimeModule()); Test public void testJsonFormat() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例mapper.registerModule(new JavaTimeModule());// 序列化示例Student student new Student();student.setName(小凡);student.setAge(18);student.setBirthday(LocalDate.of(1990,1,1)); // 设置用户的出生日期String json mapper.writeValueAsString(student); // 将用户对象转换为 JSON 字符串System.out.println(json); // 输出序列化后的 JSON 数据// 反序列化示例String inputJson {\birthday\:\1990-01-01\};Student deserializedUser mapper.readValue(inputJson, Student.class); // 从 JSON 字符串反序列化为 User 对象System.out.println(deserializedUser.getBirthday()); // 输出反序列化后获得的出生日期 } //输出 {name:小凡,age:18,birthday:1990-01-01} 1990-01-01 ③详细解释 JsonFormat 注解在 Jackson 中被用来精确控制日期/时间类型的属性在 JSON 序列化和反序列化过程中的格式。通过给定合适的 shape 和 pattern 参数可以确保日期数据在 Java 类型与 JSON 文本之间准确无误地转换。 9.2 序列化注解 9.2.1 JsonInclude 用于控制对象在序列化过程中包含哪些属性。它可以防止空或特定值的字段被序列化到JSON输出中从而帮助您精简JSON数据结构减少不必要的传输量或避免向客户端暴露不必要的信息 ①定义PersonInclude实体类 JsonInclude(JsonInclude.Include.NON_NULL) public class PersonInclude {/*** 姓名字段由于未指定JsonInclude注解因此继承类级别的NON_NULL策略*/private String name;/*** 职业字段显式指定为仅在非空时才包含在序列化结果中*/JsonInclude(JsonInclude.Include.NON_EMPTY)private String occupation;/*** 兴趣爱好列表遵循类级别的NON_NULL策略*/private ListString hobbies;// 构造函数、getter/setter等省略...} ②使用示例 Test public void testJsonInclude() throws JsonProcessingException {PersonInclude personFull new PersonInclude();personFull.setName(小凡);personFull.setOccupation(程序员);personFull.setHobbies(Arrays.asList(编程,看书,打豆豆));PersonInclude personPartial new PersonInclude();personPartial.setName(null);personPartial.setOccupation(保洁员);ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(personFull);System.out.println(json);String json1 mapper.writeValueAsString(personPartial);System.out.println(json1);} //输出 {name:小凡,occupation:程序员,hobbies:[编程,看书,打豆豆]} {occupation:保洁员} ③ 详细解释 测试用例1序列化后JSON只包含name、occupation和hobbies字段都不为空所以都显示出来 测试用例2创建了一个部分字段为null或空的PersonInclude实例。为空的不显示 9.2.2 JsonGetter 用于告诉Jackson应该通过调用getter方法而不是通过直接字段访问来获取某个字段值 ①创建PersonGetter实体类 public class PersonGetter {private String firstName;private String lastName;// 使用 JsonGetter 定义一个方法该方法将在序列化时作为 fullName 属性的值返回JsonGetter(fullName)public String getFullName() {return this.firstName this.lastName;}// 构造函数和其他常规setter/getter方法 } ②使用示例 Test public void testJsonGetter() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例PersonGetter person new PersonGetter(张, 小凡);// 创建一个 Person 对象String json mapper.writeValueAsString(person); // 将 Person 对象序列化为 JSON 字符串System.out.println(json); // 输出序列化后的 JSON } //输出 {firstName:张,lastName:小凡,fullName:张 小凡} JsonGetter 注解成功地将 getFullName() 方法的结果映射到 JSON 对象中的 fullName 属性。 9.2.3 JsonAnyGetter 用于标记一个方法获取除已知属性外的所有其他键值对。这些键值对通常存储在一个 Map 结构中 以便将它们作为一个附加的对象进行序列化。 ① 创建CustomData实体类 Data public class CustomData {private final MapString, Object additionalProperties new HashMap();// 使用 JsonAnyGetter 定义一个方法该方法将在序列化时返回所有额外属性JsonAnyGetterpublic MapString, Object getAdditionalProperties() {return additionalProperties;}// 提供方法来添加或修改额外属性public void addProperty(String key, Object value) {additionalProperties.put(key, value);} } ②使用示例 Test public void testJsonAnyGetter() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例CustomData data new CustomData();data.addProperty(key1, value1);data.addProperty(key2, 42);data.addProperty(key3, value3);String json mapper.writeValueAsString(data); // 将 CustomData 对象序列化为 JSON 字符串System.out.println(json); // 输出序列化后的 JSON } //输出 {key1:value1,key2:42,key3:value3} JsonAnyGetter 注解的主要作用如下 动态属性支持通过在返回 Map 的方法上使用 JsonAnyGetter您可以将一个对象的动态属性集合序列化为 JSON 对象的多个键值对。这些属性可能是在运行时添加的或者基于某些条件动态生成的。 简化结构避免为每个可能的动态属性单独声明字段和 getter/setter。只需维护一个 Map即可处理任意数量和类型的额外属性。 兼容性与灵活性当需要与未知或未来可能变化的数据结构交互时JsonAnyGetter 可确保 JSON 表示能够容纳未预定义的属性从而提高系统的兼容性和适应性。 9.2.4 JsonPropertyOrder 用于指定类中属性在序列化为 JSON 时的排序规则 ①创建OrderPerson 实体类 public class OrderPerson {JsonProperty(firstName)private String givenName;JsonProperty(lastName)private String familyName;// 构造函数和其他常规setter/getter方法 } ②使用示例 Test public void testJsonPropertyOrder() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例OrderPerson person new OrderPerson(John, Doe); // 创建一个 OrderedPerson 对象String json mapper.writeValueAsString(person); // 将 OrderedPerson 对象序列化为 JSON 字符串System.out.println(json); // 输出序列化后的 JSON } //输出 {firstName:John,lastName:Doe} JsonPropertyOrder 注解按照指定顺序lastNamefirstName对 JSON 对象的属性进行了排序。 9.2.5 JsonRawValue 用于标记一个字段或方法返回值指示Jackson在序列化时应将其原始值视为未经转义的 JSON 字符串并直接嵌入到输出的 JSON 文档中。即使所标记的值包含 JSON 特殊字符如双引号、反斜杠等也不会对其进行转义 ① 创建一个包含 JsonRawValue 注解的类 public class RawJsonValueExample {private String normalProperty 这是一个正常字符串;// 使用 JsonRawValue 标记 rawJsonProperty使其内容被视为未经转义的 JSON 值JsonRawValueprivate String rawJsonProperty {\key\: \value\, \array\: [1, 2, 3]};// 构造函数和其他常规setter/getter方法 } ②使用示例 Test public void testJsonRawValue() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper(); // 创建 Jackson 的 ObjectMapper 实例RawJsonValueExample example new RawJsonValueExample(); // 创建一个 RawJsonValueExample 对象String json mapper.writeValueAsString(example); // 将 RawJsonValueExample 对象序列化为 JSON 字符串System.out.println(json); // 输出序列化后的 JSON } //输出 {normalProperty:这是一个正常字符串,rawJsonProperty:{key: value, array: [1, 2, 3]}} rawJsonProperty 的值并未被转义而是作为一个完整的 JSON 对象直接嵌入到父 JSON 文档中。 当您需要在 JSON 对象中嵌入另一段 JSON 文本时使用 JsonRawValue 可以确保这段文本以未经转义的形式出现在输出的 JSON 中保持其原有的 JSON 结构。 9.2.6 JsonValue 用于标记一个方法或字段Jackson在序列化该类实例时直接使用该方法的返回值或字段的值作为整个对象的 JSON 表示而非按照类的常规属性进行序列化 ① 创建JsonValueExample类 public class JsonValueExample {private LocalDate date;private String formattedDate;JsonValuepublic String asJsonString() {return {\date\:\ date.toString() \,\formatted\:\ formattedDate \};}// 构造函数和其他常规setter/getter方法 } ② 使用示例 Test public void testJsonValue() throws JsonProcessingException {ObjectMapper mapper new ObjectMapper();JsonValueExample example new JsonValueExample();example.setDate(LocalDate.of(2024,4,6));example.setFormattedDate(yyyy-MM-dd);String json mapper.writeValueAsString(example);System.out.println(json); } //输出 {\date\:\2024-04-06\,\formatted\:\yyyy-MM-dd\} 在 asJsonString() 方法上应用注解指示序列化时应将该方法的返回值作为整个对象的 JSON 表达忽略类中其他的属性 9.2.7 JsonSerialize 于指定类、字段或方法在序列化过程中使用的自定义序列化逻辑 ① 创建一个包含 JsonSerialize 注解的类及其自定义序列化器 public class BooleanSerializer extends JsonSerializerBoolean {Overridepublic void serialize(Boolean aBoolean, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {if(aBoolean){jsonGenerator.writeNumber(1);} else {jsonGenerator.writeNumber(0);}} }public class PersonSerializer {public long personId 0;public String name John;JsonSerialize(using BooleanSerializer.class)public boolean enabled false;// 构造函数和其他常规setter/getter方法 } ②使用示例 Test public void testJsonSerialize() throws JsonProcessingException {PersonSerializer person new PersonSerializer();person.setName(小凡);person.setPersonId(1001);person.setEnabled(true);ObjectMapper mapper new ObjectMapper();String json mapper.writeValueAsString(person);System.out.println(json); } //输出 {personId:1001,name:小凡,enabled:1} 通过上面代码测试我们可以看到enabled被序列化为1 9.3 反序列化注解 9.3.1 JsonSetter 用于标记一个方法或字段指示 Jackson 在反序列化过程中应如何设置该属性的值 ①创建PersonSetter 类 public class PersonSetter {JsonSetter(first_name)private String firstName;JsonSetter(last_name)private String lastName;// 其他getter setter toString方法省略... } ②使用示例 Test public void testJsonSetter() throws JsonProcessingException {String jsonNormal {\first_name\:\张\, \last_name\:\小凡\};ObjectMapper mapper new ObjectMapper();PersonSetter person mapper.readValue(jsonNormal, PersonSetter.class);System.out.println(person); } //输出 PersonSetter(firstName张, lastName小凡) JsonSetter 注解提供了灵活的方式来定制Jackson在反序列化期间如何将JSON数据映射到Java对象的属性 9.3.2 JsonAnySetter 用于处理反序列化过程中遇到的未知或额外的 JSON 键值对。当一个对象的JSON表示中包含无法直接映射到已声明属性的键时这个注解可以帮助捕获并存储这些额外的数据 ① 定义带有 JsonAnySetter 注解的类 ToString public class CustomObject {private String knownProperty;private MapString, Object additionalProperties new HashMap();// 已知属性的setter方法public void setKnownProperty(String knownProperty) {this.knownProperty knownProperty;}// 获取已知属性的getter方法省略.../*** JsonAnySetter注解方法用于处理反序列化过程中遇到的所有未知属性。** param key 未知属性的键* param value 未知属性的值*/JsonAnySetterpublic void addAdditionalProperty(String key, Object value) {additionalProperties.put(key, value);}// 提供访问额外属性的方法public MapString, Object getAdditionalProperties() {return additionalProperties;} } ②使用示例 Test public void testJsonAnySetter() throws JsonProcessingException {String json {\knownProperty\:\expectedValue\,\extraField1\:\someValue\,\extraField2\:42,\nestedObject\:{\key\:\value\}};ObjectMapper mapper new ObjectMapper();CustomObject customObject mapper.readValue(json, CustomObject.class);System.out.println(customObject); } //输出 CustomObject(knownPropertyexpectedValue, additionalProperties{extraField1someValue, nestedObject{keyvalue}, extraField242}) JsonAnySetter注解来应对JSON反序列化过程中可能出现的未知属性确保所有数据都能被妥善处理和保留。这种机制特别适用于需要兼容动态或扩展性较强的JSON输入场景。 9.3.3 JsonCreator 用于标记一个构造器、静态工厂方法或实例方法使其成为反序列化过程中创建对象实例的入口点。这个注解帮助 Jackson 确定如何根据 JSON 数据构建相应的 Java 对象。 ① 定义带有 JsonCreator 注解的类 public class AddressCreator {private String street;private int number;private String city;// 构造器上使用JsonCreator注解指示Jackson使用此构造器反序列化JSONJsonCreatorpublic AddressCreator(JsonProperty(street) String street,JsonProperty(number) int number,JsonProperty(city) String city) {this.street street;this.number number;this.city city;}// getter setter toString方法省略... } ② 使用示例 Test public void testCreateor() throws JsonProcessingException {String json {\street\:\呈贡区\,\number\:123,\city\:\昆明\};ObjectMapper mapper new ObjectMapper();AddressCreator addressCreator mapper.readValue(json, AddressCreator.class);System.out.println(addressCreator); } //输出 AddressCreator(street呈贡区, number123, city昆明) 9.3.4 JacksonInject 用于在反序列化过程中自动注入依赖项或附加信息到目标对象。通常用于处理那些不能直接从 JSON 数据中获取、但又希望在反序列化完成后立即可用的信息 ① 定义带有 JacksonInject 注解的类 public class UserInject {private String name;private String email;// JacksonInject注解在字段上指示Jackson在反序列化过程中注入特定值JacksonInject(defaultEmail)private String defaultEmail;// 构造器和getter setter toString方法省略... } ②使用示例 Test public void testJacksonInject() throws JsonProcessingException {// 设置可注入的值InjectableValues injectables new InjectableValues.Std().addValue(defaultEmail, xiaofanexample.com);// 创建ObjectMapper并配置注入值ObjectMapper mapper new ObjectMapper().setInjectableValues(injectables);String json {\name\:\小凡\};// 反序列化时defaultEmail字段会被自动注入指定值UserInject userInject mapper.readValue(json, UserInject.class);System.out.println(Name: userInject.getName());System.out.println(Email: userInject.getEmail());System.out.println(Default Email: userInject.getDefaultEmail()); } //输出 Name: 小凡 Email: null Default Email: xiaofanexample.com JacksonInject 注解在Jackson反序列化过程中用于引入外部依赖或默认值使得这些信息能够在反序列化完成后立即可用 9.3.5 JsonDeserialize 用于在反序列化过程中指定自定义的反序列化器来处理某个字段或类的特殊逻辑 ①自定义反序列化器 public class BooleanDeserializer extends JsonDeserializerBoolean {Overridepublic Boolean deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {String text jsonParser.getText();if(0.equals(text)) {return false;}return true;} } ② JsonDeserialize注解添加到要为其使用自定义反序列化器的字段 public class PersonDeserialize {public long id;public String name;JsonDeserialize(using BooleanDeserializer.class)public boolean enabled false;//构造器和getter setter toString方法省略... } ③使用示例 {id:1001,name:小凡,enabled:1} Test public void testJsonDeserialize() throws JsonProcessingException {String json {\id\:1001,\name\:\小凡\,\enabled\:1};ObjectMapper mapper new ObjectMapper();PersonDeserialize personDeserialize mapper.readValue(json, PersonDeserialize.class);System.out.println(personDeserialize); } //输出 PersonDeserialize(id1001, name小凡, enabledtrue) 我们json字符串中enabled的值是1最终反序列化成PersonDeserialize 对象后值变成了ture 本期内容到此就结束了希望对你有所帮助。我们下期再见 (●◡●) 文章转载自xiezhr 原文链接https://www.cnblogs.com/xiezhr/p/18119893 体验地址引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构
文章转载自:
http://www.morning.wsjnr.cn.gov.cn.wsjnr.cn
http://www.morning.fflnw.cn.gov.cn.fflnw.cn
http://www.morning.pnjsl.cn.gov.cn.pnjsl.cn
http://www.morning.ygztf.cn.gov.cn.ygztf.cn
http://www.morning.ymhzd.cn.gov.cn.ymhzd.cn
http://www.morning.bkqw.cn.gov.cn.bkqw.cn
http://www.morning.bqpgq.cn.gov.cn.bqpgq.cn
http://www.morning.bgpb.cn.gov.cn.bgpb.cn
http://www.morning.rqqn.cn.gov.cn.rqqn.cn
http://www.morning.csnch.cn.gov.cn.csnch.cn
http://www.morning.kpzbf.cn.gov.cn.kpzbf.cn
http://www.morning.plcyq.cn.gov.cn.plcyq.cn
http://www.morning.bnpn.cn.gov.cn.bnpn.cn
http://www.morning.sgbsr.cn.gov.cn.sgbsr.cn
http://www.morning.hnrls.cn.gov.cn.hnrls.cn
http://www.morning.sxjmz.cn.gov.cn.sxjmz.cn
http://www.morning.yongkangyiyuan-pfk.com.gov.cn.yongkangyiyuan-pfk.com
http://www.morning.trqhd.cn.gov.cn.trqhd.cn
http://www.morning.ldqzz.cn.gov.cn.ldqzz.cn
http://www.morning.rbyz.cn.gov.cn.rbyz.cn
http://www.morning.zkzjm.cn.gov.cn.zkzjm.cn
http://www.morning.nzkc.cn.gov.cn.nzkc.cn
http://www.morning.sxjmz.cn.gov.cn.sxjmz.cn
http://www.morning.zmzdx.cn.gov.cn.zmzdx.cn
http://www.morning.knzdt.cn.gov.cn.knzdt.cn
http://www.morning.kkwgg.cn.gov.cn.kkwgg.cn
http://www.morning.jfjpn.cn.gov.cn.jfjpn.cn
http://www.morning.tsdqr.cn.gov.cn.tsdqr.cn
http://www.morning.jfjbl.cn.gov.cn.jfjbl.cn
http://www.morning.ggxbyhk.cn.gov.cn.ggxbyhk.cn
http://www.morning.gqddl.cn.gov.cn.gqddl.cn
http://www.morning.tqsmg.cn.gov.cn.tqsmg.cn
http://www.morning.ishoufeipin.cn.gov.cn.ishoufeipin.cn
http://www.morning.wmrgp.cn.gov.cn.wmrgp.cn
http://www.morning.krxzl.cn.gov.cn.krxzl.cn
http://www.morning.sryyt.cn.gov.cn.sryyt.cn
http://www.morning.tgmwy.cn.gov.cn.tgmwy.cn
http://www.morning.mfbcs.cn.gov.cn.mfbcs.cn
http://www.morning.ngjpt.cn.gov.cn.ngjpt.cn
http://www.morning.kpyyf.cn.gov.cn.kpyyf.cn
http://www.morning.qbgdy.cn.gov.cn.qbgdy.cn
http://www.morning.qbfqb.cn.gov.cn.qbfqb.cn
http://www.morning.nhdw.cn.gov.cn.nhdw.cn
http://www.morning.bpwz.cn.gov.cn.bpwz.cn
http://www.morning.dsprl.cn.gov.cn.dsprl.cn
http://www.morning.jynzb.cn.gov.cn.jynzb.cn
http://www.morning.gzxnj.cn.gov.cn.gzxnj.cn
http://www.morning.gqfjb.cn.gov.cn.gqfjb.cn
http://www.morning.bsrcr.cn.gov.cn.bsrcr.cn
http://www.morning.hylbz.cn.gov.cn.hylbz.cn
http://www.morning.mrfjr.cn.gov.cn.mrfjr.cn
http://www.morning.xrnh.cn.gov.cn.xrnh.cn
http://www.morning.sjwzl.cn.gov.cn.sjwzl.cn
http://www.morning.bnbtp.cn.gov.cn.bnbtp.cn
http://www.morning.mcpdn.cn.gov.cn.mcpdn.cn
http://www.morning.qztsq.cn.gov.cn.qztsq.cn
http://www.morning.wqsjx.cn.gov.cn.wqsjx.cn
http://www.morning.xuejitest.com.gov.cn.xuejitest.com
http://www.morning.bbrf.cn.gov.cn.bbrf.cn
http://www.morning.khlxd.cn.gov.cn.khlxd.cn
http://www.morning.qmqgx.cn.gov.cn.qmqgx.cn
http://www.morning.qtkfp.cn.gov.cn.qtkfp.cn
http://www.morning.pqwhk.cn.gov.cn.pqwhk.cn
http://www.morning.lpyjq.cn.gov.cn.lpyjq.cn
http://www.morning.mfbzr.cn.gov.cn.mfbzr.cn
http://www.morning.pjjkz.cn.gov.cn.pjjkz.cn
http://www.morning.qbxdt.cn.gov.cn.qbxdt.cn
http://www.morning.mpngp.cn.gov.cn.mpngp.cn
http://www.morning.rlbg.cn.gov.cn.rlbg.cn
http://www.morning.dncgb.cn.gov.cn.dncgb.cn
http://www.morning.gydsg.cn.gov.cn.gydsg.cn
http://www.morning.hdscx.cn.gov.cn.hdscx.cn
http://www.morning.kwrzg.cn.gov.cn.kwrzg.cn
http://www.morning.ltfnl.cn.gov.cn.ltfnl.cn
http://www.morning.twfdm.cn.gov.cn.twfdm.cn
http://www.morning.yrjxr.cn.gov.cn.yrjxr.cn
http://www.morning.myxps.cn.gov.cn.myxps.cn
http://www.morning.nbnpb.cn.gov.cn.nbnpb.cn
http://www.morning.hlzpb.cn.gov.cn.hlzpb.cn
http://www.morning.cfcpb.cn.gov.cn.cfcpb.cn
http://www.tj-hxxt.cn/news/235925.html

相关文章:

  • 嘉兴公司做网站做直播网站软件有哪些
  • 四川省住房和城乡建设厅网站域名家具网站建设便宜
  • 寿县网站建设线上美工招聘
  • eclipse可以做网站嘛网站 文件夹 上传
  • 四川建设厅网站施工员证查询wordpress更改主题首页
  • 培训网站图片比较好的设计公司
  • 电子商务网站建设的流程图万网域名解析平台
  • 网站搜索排名高怎么做网站网页设计尺寸
  • 挂别人公司做网站可以吗wordpress怎么改登陆不了
  • 长兴网站建设列举企业网站建设有哪些好处360网站空间
  • 腾讯云备案网站建设方案书广州公布一批重点场所
  • 云浮网站建设安徽省建设法制协会网站
  • 沈阳做网站的公司排行对电子商务网站与建设的心得
  • 电子商务网站开发背景与原因站长工具源码
  • 17一起广州做网站石家庄信息门户网站制作费用
  • 松江专业做网站建设企业银行
  • .net和php那个做网站好抚州市住房和城乡建设局网站
  • 网站建设如何上传文件网站设计制作费用多少
  • 学校网站建设管理制度卡盟网站顶图怎么做
  • 网站建设需要知道什么wordpress站点添加skype
  • 中国空间站天宫课堂网站收款即时到账怎么做的
  • 个人域名网站可以做企业站吗舆情网站直接打开的软件
  • php网站开发接口开发做公司网站的南宁公司
  • 自己建设企业网站如何做wordpress主题
  • 东营网站建设策划内容兰州快速seo整站优化招商
  • 北京网站建设佳v询 lotlek 能上词建一个快讯网站要多少钱
  • 网站建设求职要求用手机怎么做免费网站
  • 自做衣服网站蓝色管理系统网站模版
  • 海报模板网站有哪些成都网站建设 川icp备
  • 白云鄂博矿区网站建设邢台有几个县