>  기사  >  Java  >  SpringBoot는 Jackson을 어떻게 통합합니까?

SpringBoot는 Jackson을 어떻게 통합합니까?

WBOY
WBOY앞으로
2023-05-12 21:01:041532검색

1. Jackson 소개

지침: Jackson 도구 클래스는 기사 마지막 부분에 있으므로 복사하여 붙여넣기만 하면 됩니다. 잭슨은 회사에서 반드시 사용해야 하는 구성요소 중 하나이다. 알리바바의 Fastjson도 많이 사용된다. 그러나 어떤 이유로 인해 보안에 신경쓰는 회사들은 바로 통과하는 경우도 있다. Gson (이건 쓸모가 없습니다. 하지만 저는 그것에 대해 잘 모릅니다). Spring MVC의 기본 json 파서는 Jackson입니다. 잭슨은 많은 장점을 가지고 있습니다. Jackson은 더 적은 수의 jar 패키지에 의존하며 간단하고 사용하기 쉽습니다. Gson과 같은 다른 Java json 프레임워크와 비교하여 Jackson은 대용량 json 파일을 더 빠르게 구문 분석합니다. Jackson은 런타임 중에 메모리를 덜 차지하고 성능이 더 좋습니다. Jackson은 쉽게 확장하고 사용자 정의할 수 있는 유연한 API를 제공합니다.

추가 지식:
Jackson 1.x 버전의 패키지 이름은 org.codehaus.jackson입니다. org.codehaus.jackson
当升级到 2.x 版本时,包名变为com.fasterxml.jackson

Jackson 有三个核心包,分别是 StreamingDatabidAnnotations,通过这些包可以方便的对 JSON 进行操作.

  • jackson-core:核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。

  • jackson-annotations:注解包,提供标准注解功能.

  • jackson-databind :数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。包含上面两个包,只导入这个坐标即可。

运行环境:

  • idea2020.2

  • jdk1.8

  • springboot 2.7.92.x 버전으로 업그레이드하면 패키지 이름은 가 됩니다. >com.fasterxml.jackson.

  • Jackson에는 Streaming, Databid, Annotations라는 세 가지 핵심 패키지가 있습니다. 이 패키지를 통해 JSON을 쉽게 운영할 수 있습니다. class=" list-paddingleft-2">
jackson-core: 핵심 패키지는 JsonPaser 및 JsonGenerator를 포함하는 "스트림 모드" 구문 분석을 기반으로 관련 API를 제공합니다. Jackson의 내부 구현에서는 고성능 스트리밍 API의 JsonGenerator 및 JsonParser를 사용하여 json을 생성하고 구문 분석합니다.

  • jackson-annotations: 표준 주석 기능을 제공하는 주석 패키지

  • jackson-databind: " "Object Binding"(ObjectMapper)으로 구문 분석되는 관련 API와 "Tree Model"(JsonNode)로 구문 분석되는 관련 API는 "Object Binding"을 기반으로 구문 분석되는 API와 "Tree Model"로 구문 분석되는 API는 기반으로 구문 분석되는 API에 따라 다릅니다. "스트리밍 모드"에 있습니다. 위의 두 패키지가 포함되어 있으므로 이 좌표를 가져오면 됩니다.

    실행 환경:

    idea2020.2

  • jdk1.8 code><h4></h4> <li> <p><code>springboot 2.7.9
    데모 다운로드:

    다운로드하려면 내 리소스로 직접 이동하세요(Jackson 예제 - 도구 클래스 포함)

    SpringBoot는 Jackson을 어떻게 통합합니까? 2. Json 소개

    참고:

    Java 개발자는 Json을 배워야 합니다. 프론트엔드와 백엔드가 분리된 현재 프로젝트에서는 Json이 가장 일반적인 데이터 교환 형식입니다. 예를 들어 SpringBoot의 @RequestBody 주석은 Json 형식을 수신하기 위한 주석으로 사용됩니다. 테스트를 위해 Postman을 사용할 때 전송되는 raw-json도 Json 형식 데이터입니다. JSON 표현 구조:

    객체 배열SpringBoot는 Jackson을 어떻게 통합합니까?: 객체 구조는 "{" 중괄호로 시작하고 "}" 중괄호로 끝납니다. 중간 부분은 ","/ 값(값)으로 구분된 0개 이상의 키(키워드)로 구성됩니다. )" 쌍, 키워드 및 값은 ":"으로 구분되며 구문 구조는 코드와 같습니다. 여기에 예가 있습니다.

    {
      "array": [1,2,3],
      "boolean": true,
      "name": "cllb",
      "null": null,
      "age": 12345,
      "object": {
        "height": 100,
        "color": "红色"
      },
      "string": "陈老老老板"
    }

    3. Springboot는 Jackson을 통합합니다

    1. 프로젝트 생성

    지침:

    빈 springboot 프로젝트(버전 2.7.9)를 생성합니다. 여기서는 너무 많이 반복하지 않겠습니다. Get/Set 메서드를 작성할 필요 없이 Lombok 구성 요소를 생성할 때 선택하는 것이 매우 편리합니다.

    참고:

    databind 패키지를 가져오면 나머지 두 패키지도 자동으로 가져오는 것을 볼 수 있습니다.

    2. 좌표 가져오기

    지침: databind 패키지를 가져오면 나머지 두 패키지도 자동으로 가져오는 것을 볼 수 있습니다.

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.13.3</version>
    </dependency>

    SpringBoot는 Jackson을 어떻게 통합합니까?3. 구성 파일

    a. 구성 파일 구성

    속성 형식:

    #指定日期格式,比如yyyy-MM-dd HH:mm:ss,或者具体的格式化类的全限定名
    spring.jackson.date-format
    #指定日期格式化时区,比如America/Los_Angeles或者GMT+10.
    spring.jackson.time-zone
    #是否开启Jackson的反序列化
    spring.jackson.deserialization
    #是否开启json的generators.
    spring.jackson.generator
    #指定Joda date/time的格式,比如yyyy-MM-ddHH:mm:ss). 如果没有配置的话,dateformat会作为backup
    spring.jackson.joda-date-time-format
    #指定json使用的Locale.
    spring.jackson.locale
    #是否开启Jackson通用的特性.
    spring.jackson.mapper
    #是否开启jackson的parser特性.
    spring.jackson.parser
    #指定PropertyNamingStrategy(CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES)或者指定PropertyNamingStrategy子类的全限定类名.
    spring.jackson.property-naming-strategy
    #是否开启jackson的序列化.
    spring.jackson.serialization
    #指定序列化时属性的inclusion方式,具体查看JsonInclude.Include枚举.
    spring.jackson.serialization-inclusion
    b. 사용자 정의 구성

    여기서 Jackson 도구 클래스를 직접 제공합니다. , 사용자 정의 구성은 도구 클래스의 object_mapper에 대한 설정 할당을 나타냅니다. 모든 메소드가 있으며, 툴 클래스를 이용하여 직접 데모를 진행합니다.

    spring:
      jackson:
        #日期格式化
        date-format: yyyy-MM-dd HH:mm:ss
        time-zone: GMT+8
        #设置空如何序列化
        default-property-inclusion: non_null    
        serialization:
           #格式化输出 
          indent_output: true
          #忽略无法转换的对象
          fail_on_empty_beans: false
        deserialization:
          #允许对象忽略json中不存在的属性
          fail_on_unknown_properties: false
        parser:
          #允许出现特殊字符和转义符
          allow_unquoted_control_chars: true
          #允许出现单引号
          allow_single_quotes: true
    4. 엔터티 클래스

    지침:

    여기에서 사용자 엔터티 클래스를 생성하세요.
    package com.clllb.jackson.utils;
    
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.*;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.util.StringUtils;
    
    import java.io.File;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.List;
    
    @Slf4j
    public class JacksonUtil {
    
        private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
        private static final ObjectMapper OBJECT_MAPPER_SNAKE_CASE = new ObjectMapper();
        // 日期格式化
        private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
        static {
            //对象的所有字段全部列入
            OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.ALWAYS);
            //取消默认转换timestamps形式
            OBJECT_MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
            //忽略空Bean转json的错误
            OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            //所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ss
            OBJECT_MAPPER.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
            //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
            OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }
    
        static {
            //对象的所有字段全部列入
            OBJECT_MAPPER_SNAKE_CASE.setSerializationInclusion(JsonInclude.Include.ALWAYS);
            //取消默认转换timestamps形式
            OBJECT_MAPPER_SNAKE_CASE.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
            //忽略空Bean转json的错误
            OBJECT_MAPPER_SNAKE_CASE.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            //所有的日期格式都统一为以下的样式,即yyyy-MM-dd HH:mm:ss
            OBJECT_MAPPER_SNAKE_CASE.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
            //忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
            OBJECT_MAPPER_SNAKE_CASE.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            //转换为下划线
            OBJECT_MAPPER_SNAKE_CASE.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
        }
    
        private JacksonUtil() {
        }
    
        /**
         * 对象转Json格式字符串
         *
         * @param obj 对象
         * @return Json格式字符串
         */
        public static <T> String obj2String(T obj) {
            if (obj == null) {
                return null;
            }
            try {
                return obj instanceof String ? (String) obj : OBJECT_MAPPER.writeValueAsString(obj);
            } catch (JsonProcessingException e) {
                log.warn("Parse Object to String error : {}", e.getMessage());
                return null;
            }
        }
    
        /**
         * 对象转file
         * @param fileName
         * @param obj
         */
         public static void obj2File(String fileName,Object obj){
            if (obj == null){
                return;
            }
             try {
                 OBJECT_MAPPER.writeValue(new File(fileName),obj);
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
    
        /**
         * 对象转Json格式字符串; 属性名从驼峰改为下划线形式
         *
         * @param obj 对象
         * @return Json格式字符串
         */
        public static <T> String obj2StringFieldSnakeCase(T obj) {
            if (obj == null) {
                return null;
            }
            try {
                ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;
                return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
            } catch (JsonProcessingException e) {
                log.warn("Parse Object to String error : {}", e.getMessage());
                return null;
            }
        }
    
        /**
         * 字符串转换为自定义对象; 属性名从下划线形式改为驼峰
         *
         * @param str   要转换的字符串
         * @param clazz 自定义对象的class对象
         * @return 自定义对象
         */
        public static <T> T string2ObjFieldLowerCamelCase(String str, Class<T> clazz) {
            if (StringUtils.isEmpty(str) || clazz == null) {
                return null;
            }
            try {
                ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;
                return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
            } catch (Exception e) {
                log.warn("Parse String to Object error : {}", e.getMessage());
                return null;
            }
        }
    
        /**
         * 字符串转换为自定义对象(List); 属性名从下划线形式改为驼峰
         *
         * @param str           要转换的字符串
         * @param typeReference 自定义对象的typeReference List 对象
         * @return 自定义对象
         */
        public static <T> List<T> string2ListFieldLowerCamelCase(String str, TypeReference<List<T>> typeReference) {
            if (StringUtils.isEmpty(str) || typeReference == null) {
                return null;
            }
            try {
                ObjectMapper objectMapper = OBJECT_MAPPER_SNAKE_CASE;
                return objectMapper.readValue(str, typeReference);
            } catch (Exception e) {
                log.warn("Parse String to Object error : {}", e.getMessage());
                return null;
            }
        }
    
        /**
         * 对象转Json格式字符串(格式化的Json字符串)
         *
         * @param obj 对象
         * @return 美化的Json格式字符串
         */
        public static <T> String obj2StringPretty(T obj) {
            if (obj == null) {
                return null;
            }
            try {
                return obj instanceof String ? (String) obj : OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
            } catch (JsonProcessingException e) {
                log.warn("Parse Object to String error : {}", e.getMessage());
                return null;
            }
        }
    
        /**
         * 字符串转换为自定义对象
         *
         * @param str   要转换的字符串
         * @param clazz 自定义对象的class对象
         * @return 自定义对象
         */
        public static <T> T string2Obj(String str, Class<T> clazz) {
            if (StringUtils.isEmpty(str) || clazz == null) {
                return null;
            }
            try {
                return clazz.equals(String.class) ? (T) str : OBJECT_MAPPER.readValue(str, clazz);
            } catch (Exception e) {
                log.warn("Parse String to Object error : {}", e.getMessage());
                return null;
            }
        }
    
        /**
         * 字符串转换为自定义字段转为list
         * @param str
         * @param typeReference
         * @param <T>
         * @return
         */
        public static <T> T string2Obj(String str, TypeReference<T> typeReference) {
            if (StringUtils.isEmpty(str) || typeReference == null) {
                return null;
            }
            try {
                return (T) (typeReference.getType().equals(String.class) ? str : OBJECT_MAPPER.readValue(str, typeReference));
            } catch (IOException e) {
                log.warn("Parse String to Object error", e);
                return null;
            }
        }
    
        public static <T> T string2Obj(String str, Class<?> collectionClazz, Class<?>... elementClazzes) {
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(collectionClazz, elementClazzes);
            try {
                return OBJECT_MAPPER.readValue(str, javaType);
            } catch (IOException e) {
                log.warn("Parse String to Object error : {}" + e.getMessage());
                return null;
            }
        }
    }

    프로젝트 샘플:

    5.테스트 클래스

    지침:

    테스트 클래스에서 도구 클래스를 직접 조정하세요. 방법은 매우 간단하며 출력 결과가 첨부됩니다.

    a.object 유형을 JsonSpringBoot는 Jackson을 어떻게 통합합니까?

    으로 변환 지침:

    writeValueAsString 메소드 사용

    package com.clllb.jackson.PO;
    
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    public class User {
    
        private String username;
    
        private Integer age;
    
        private List<String> info;
    
    	private Long userId;
    }
    출력 결과:

    🎜{"username":"clllb","age":24,"info":["There are 백 Wan","make a luck"],"userId":1}🎜🎜🎜b.object 유형을 파일로 변환🎜🎜🎜지침: 🎜 writeValue 메소드 사용🎜
      @Test
        void obj2string(){
            User user = new User();
            user.setUsername("clllb");
            user.setAge(24);
            user.setUserId(1L);
            List<String> infoList = new ArrayList<>();
            infoList.add("有一百万");
            infoList.add("发大财");
            user.setInfo(infoList);
    
            String json = JacksonUtil.obj2String(user);
            System.out.println(json);
        }
    🎜출력 결과: 🎜🎜🎜🎜🎜c. 문자열 유형 변환 객체 사용자 정의 유형🎜🎜🎜지침:🎜 readValue 메소드를 사용하세요🎜
     @Test
        void string2obj(){
            String json = "{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"userId\":11}";
            User user = JacksonUtil.string2Obj(json, User.class);
            System.out.println(user);
        }

    输出结果:

    User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)

    d.string类型转Object自定义类型list

    说明: 使用readValue方法,传参变为TypeReference typeReference,这里工具类用的重载方法名是相同的。

    @Test
        void string2objList(){
            String json = "[{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"userId\":11},\n" +
                    "{\"username\":\"陈老老老板\",\"age\":25,\"info\":[\"有一千万\",\"发大大财\"],\"userId\":12}]";
            List<User> user = JacksonUtil.string2Obj(json, new TypeReference<List<User>>(){});
            user.forEach(System.out::println);
        }

    输出结果:

    User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)
    User(username=陈老老老板, age=25, info=[有一千万, 发大大财], userId=12)

    e.object类型转String(驼峰转下划线)

    说明: 使用writeValueAsString方法,这里区别看工具类就会发现,就是多了一个设置OBJECT_MAPPER_SNAKE_CASE.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);

     @Test
        void obj2sringSnakeCase(){
            User user = new User();
            user.setUsername("clllb");
            user.setAge(24);
            user.setUserId(11L);
            List<String> infoList = new ArrayList<>();
            infoList.add("有一百万");
            infoList.add("发大财");
            user.setInfo(infoList);
            String json = JacksonUtil.obj2StringFieldSnakeCase(user);
            System.out.println(json);
        }

    输出结果:

    {"username":"clllb","age":24,"info":["有一百万","发大财"],"user_id":11}

    f.string类型(下划线)转Object类型

    <font color = &#39;red&#39;><b>说明:</font> 使用readValue方法
    ```java
     @Test
        void string2obj(){
            String json = "{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"user_id\":11}";
            User user = JacksonUtil.string2Obj(json, User.class);
            System.out.println(user);
        }

    输出结果:

    User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)

    g.string类型(下划线)转Object自定义类型list

    说明: 使用readValue方法,传参变为TypeReference typeReference,这里工具类用的重载方法名是相同的。

     @Test
        void string2objSnakeCase(){
            String json = "[{\"username\":\"clllb\",\"age\":24,\"info\":[\"有一百万\",\"发大财\"],\"user_id\":11},\n" +
                    "{\"username\":\"陈老老老板\",\"age\":25,\"info\":[\"有一千万\",\"发大大财\"],\"user_id\":12}]";
            List<User> user = JacksonUtil.string2ListFieldLowerCamelCase(json, new TypeReference<List<User>>(){});
            user.forEach(System.out::println);
        }

    输出结果:

    User(username=clllb, age=24, info=[有一百万, 发大财], userId=11)
    User(username=陈老老老板, age=25, info=[有一千万, 发大大财], userId=12)

  • 위 내용은 SpringBoot는 Jackson을 어떻게 통합합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제