- Введение в Jackson ObjectMapper
- 2. Зависимости
- 3. Чтение и запись с помощью ObjectMapper
- 3.1. Объект Java в JSON
- 3.2. JSON в объект Java
- 3.3. JSON в Джексон JsonNode
- 3.4. Создание списка Java из строки массива JSON
- 3.5. Создание карты Java из строки JSON
- 4. Расширенные функции
- 4.1. Настройка функции сериализации или десериализации
- 4.2. Создание пользовательского сериализатора или десериализатора
- 4.3. Обработка форматов даты
- 4.4. Обработка коллекций
- 5. Вывод
- Jackson – Custom Serializer
Введение в Jackson ObjectMapper
В этом руководстве основное внимание уделяется пониманию класса Jackson ObjectMapper и тому, как сериализовать объекты Java в JSON и десериализовать строку JSON в объекты Java.
Чтобы узнать больше о библиотеке Джексона в целом, можно начать с учебника по Джексону .
2. Зависимости
Давайте сначала добавим в pom.xml следующие зависимости :
dependency> groupId>com.fasterxml.jackson.coregroupId> artifactId>jackson-databindartifactId> version>2.13.0version> dependency>
Эта зависимость также транзитивно добавит в путь к классам следующие библиотеки:
Всегда используйте последние версии из центрального репозитория Maven для jackson-databind .
3. Чтение и запись с помощью ObjectMapper
Начнем с основных операций чтения и записи.
Простой API readValue ObjectMapper — хорошая отправная точка. Мы можем использовать его для анализа или десериализации содержимого JSON в объект Java.
Кроме того, на стороне записи мы можем использовать API writeValue для сериализации любого объекта Java в виде вывода JSON.
В этой статье мы будем использовать следующий класс Car с двумя полями в качестве объекта для сериализации или десериализации:
public class Car private String color; private String type; // standard getters setters >
3.1. Объект Java в JSON
Давайте посмотрим на первый пример сериализации объекта Java в JSON с использованием метода writeValue класса ObjectMapper :
ObjectMapper objectMapper = new ObjectMapper(); Car car = new Car("yellow", "renault"); objectMapper.writeValue(new File("target/car.json"), car);
Вывод вышеуказанного в файле будет:
Методы writeValueAsString и writeValueAsBytes класса ObjectMapper генерируют JSON из объекта Java и возвращают сгенерированный JSON в виде строки или массива байтов:
String carAsString = objectMapper.writeValueAsString(car);
3.2. JSON в объект Java
Ниже приведен простой пример преобразования строки JSON в объект Java с использованием класса ObjectMapper :
String json = "< \"color\" : \"Black\", \"type\" : \"BMW\" >"; Car car = objectMapper.readValue(json, Car.class);
Функция readValue() также принимает другие формы ввода, например файл, содержащий строку JSON:
Car car = objectMapper.readValue(new File("src/test/resources/json_car.json"), Car.class);
Car car = objectMapper.readValue(new URL("file:src/test/resources/json_car.json"), Car.class);
3.3. JSON в Джексон JsonNode
В качестве альтернативы JSON можно преобразовать в объект JsonNode и использовать для извлечения данных из определенного узла:
String json = "< \"color\" : \"Black\", \"type\" : \"FIAT\" >"; JsonNode jsonNode = objectMapper.readTree(json); String color = jsonNode.get("color").asText(); // Output: color -> Black
3.4. Создание списка Java из строки массива JSON
Мы можем разобрать JSON в виде массива в список объектов Java, используя TypeReference :
String jsonCarArray = "[< \"color\" : \"Black\", \"type\" : \"BMW\" >, < \"color\" : \"Red\", \"type\" : \"FIAT\" >]"; ListCar> listCar = objectMapper.readValue(jsonCarArray, new TypeReferenceListCar>>()>);
3.5. Создание карты Java из строки JSON
Точно так же мы можем разобрать JSON в карту Java :
String json = "< \"color\" : \"Black\", \"type\" : \"BMW\" >"; MapString, Object> map = objectMapper.readValue(json, new TypeReferenceMapString,Object>>()>);
4. Расширенные функции
Одной из самых сильных сторон библиотеки Джексона является настраиваемый процесс сериализации и десериализации.
В этом разделе мы рассмотрим некоторые дополнительные функции, в которых входной или выходной ответ JSON может отличаться от объекта, который создает или использует ответ.
4.1. Настройка функции сериализации или десериализации
При преобразовании объектов JSON в классы Java, если в строке JSON есть новые поля, процесс по умолчанию приведет к исключению:
Строка JSON в приведенном выше примере в процессе синтаксического анализа по умолчанию для объекта Java для класса Car приведет к исключению UnrecognizedPropertyException .
С помощью метода configure мы можем расширить процесс по умолчанию, чтобы игнорировать новые поля :
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); Car car = objectMapper.readValue(jsonString, Car.class); JsonNode jsonNodeRoot = objectMapper.readTree(jsonString); JsonNode jsonNodeYear = jsonNodeRoot.get("year"); String year = jsonNodeYear.asText();
Еще один вариант основан на FAIL_ON_NULL_FOR_PRIMITIVES , который определяет, разрешены ли нулевые значения для примитивных значений:
objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
Аналогично, FAIL_ON_NUMBERS_FOR_ENUM определяет, разрешено ли сериализовать/десериализовать значения перечисления как числа:
objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);
Вы можете найти полный список функций сериализации и десериализации на официальном сайте .
4.2. Создание пользовательского сериализатора или десериализатора
Еще одной важной функцией класса ObjectMapper является возможность регистрации собственного сериализатора и десериализатора .
Пользовательские сериализаторы и десериализаторы очень полезны в ситуациях, когда входной или выходной ответ JSON отличается по структуре от класса Java, в который он должен быть сериализован или десериализован.
Ниже приведен пример пользовательского сериализатора JSON :
public class CustomCarSerializer extends StdSerializerCar> public CustomCarSerializer() this(null); > public CustomCarSerializer(ClassCar> t) super(t); > @Override public void serialize( Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("car_brand", car.getType()); jsonGenerator.writeEndObject(); > >
Этот пользовательский сериализатор можно вызвать следующим образом:
ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule("CustomCarSerializer", new Version(1, 0, 0, null, null, null)); module.addSerializer(Car.class, new CustomCarSerializer()); mapper.registerModule(module); Car car = new Car("yellow", "renault"); String carJson = mapper.writeValueAsString(car);
Вот как выглядит Car (как вывод JSON) на стороне клиента:
var carJson = "car_brand":"renault">
А вот пример пользовательского десериализатора JSON :
public class CustomCarDeserializer extends StdDeserializerCar> public CustomCarDeserializer() this(null); > public CustomCarDeserializer(Class?> vc) super(vc); > @Override public Car deserialize(JsonParser parser, DeserializationContext deserializer) Car car = new Car(); ObjectCodec codec = parser.getCodec(); JsonNode node = codec.readTree(parser); // try catch block JsonNode colorNode = node.get("color"); String color = colorNode.asText(); car.setColor(color); return car; > >
Этот пользовательский десериализатор можно вызвать следующим образом:
String json = "< \"color\" : \"Black\", \"type\" : \"BMW\" >"; ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule("CustomCarDeserializer", new Version(1, 0, 0, null, null, null)); module.addDeserializer(Car.class, new CustomCarDeserializer()); mapper.registerModule(module); Car car = mapper.readValue(json, Car.class);
4.3. Обработка форматов даты
Сериализация java.util.Date по умолчанию создает число, т. е. отметку времени эпохи (количество миллисекунд с 1 января 1970 года, UTC). Но это не очень удобочитаемо для человека и требует дальнейшего преобразования для отображения в удобочитаемом формате.
Давайте обернем экземпляр Car , который мы использовали до сих пор, внутри класса Request со свойством datePurchased :
public class Request private Car car; private Date datePurchased; // standard getters setters >
Чтобы управлять строковым форматом даты и установить его, например, yyyy-MM-dd HH:mm az , рассмотрите следующий фрагмент:
ObjectMapper objectMapper = new ObjectMapper(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z"); objectMapper.setDateFormat(df); String carAsString = objectMapper.writeValueAsString(request); // output: ,"datePurchased":"2016-07-03 11:43 AM CEST">
Чтобы узнать больше о сериализации дат с Джексоном, прочитайте нашу более подробную статью .
4.4. Обработка коллекций
Еще одна небольшая, но полезная функция, доступная через класс DeserializationFeature , — это возможность генерировать нужный тип коллекции из ответа массива JSON.
Например, мы можем сгенерировать результат в виде массива:
String jsonCarArray = "[< \"color\" : \"Black\", \"type\" : \"BMW\" >, < \"color\" : \"Red\", \"type\" : \"FIAT\" >]"; ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true); Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class); // print cars
String jsonCarArray = "[< \"color\" : \"Black\", \"type\" : \"BMW\" >, < \"color\" : \"Red\", \"type\" : \"FIAT\" >]"; ObjectMapper objectMapper = new ObjectMapper(); ListCar> listCar = objectMapper.readValue(jsonCarArray, new TypeReferenceListCar>>()>); // print cars
Более подробная информация об обработке коллекций с помощью Jackson доступна здесь .
5. Вывод
Jackson — это надежная и зрелая библиотека сериализации/десериализации JSON для Java. API ObjectMapper предоставляет простой и гибкий способ анализа и создания объектов ответа JSON. В этой статье были рассмотрены основные особенности, которые делают библиотеку такой популярной.
Исходный код, прилагаемый к статье, можно найти на GitHub.
- 1. Обзор
- 2. Зависимости
- 3. Чтение и запись с помощью ObjectMapper
- 3.1. Объект Java в JSON
- 3.2. JSON в объект Java
- 3.3. JSON в Джексон JsonNode
- 3.4. Создание списка Java из строки массива JSON
- 3.5. Создание карты Java из строки JSON
- 4.1. Настройка функции сериализации или десериализации
- 4.2. Создание пользовательского сериализатора или десериализатора
- 4.3. Обработка форматов даты
- 4.4. Обработка коллекций
Jackson – Custom Serializer
Repeatedly, code that works in dev breaks down in production. Java performance issues are difficult to track down or predict.
Simply put, Digma provides immediate code feedback. As an IDE plugin, it identifies issues with your code as it is currently running in test and prod.
The feedback is available from the minute you are writing it.
Imagine being alerted to any regression or code smell as you’re running and debugging locally. Also, identifying weak spots that need attending to, based on integration testing results.
Of course, Digma is free for developers.
As always, the writeup is super practical and based on a simple application that can work with documents with a mix of encrypted and unencrypted fields.
We rely on other people’s code in our own work. Every day.
It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.
The problem is, of course, when things fall apart in production — debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky.
Lightrun is a new kind of debugger.
It’s one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics.
Learn more in this quick, 5-minute Lightrun tutorial:
Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.
The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.
Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.
Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:
DbSchema is a super-flexible database designer, which can take you from designing the DB with your team all the way to safely deploying the schema.
The way it does all of that is by using a design model, a database-independent image of the schema, which can be shared in a team using GIT and compared or deployed on to any database.
And, of course, it can be heavily visual, allowing you to interact with the database using diagrams, visually compose queries, explore the data, generate random data, import data or build HTML5 database reports.