Что выведет код?
#Tasks
import java.util.*;
public class Task050525 {
public static void main(String[] args) {
TreeMap<String, Integer> tree = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
tree.put("Apple", 1);
tree.put("banana", 2);
tree.put("APPLE", 3);
System.out.println(tree.size() + " " + tree.get("aPpLe"));
}
}
#Tasks
Не, ну а че, на кулачках решать какой фреймворк лучше - вариант? 🥴 💪 😄
https://t.me/Java_for_beginner_dev
#Mems
https://t.me/Java_for_beginner_dev
#Mems
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопросы с собеседования 👩💻
Что такое аннотация в Java?
Что такое аннотация в Java?
Anonymous Quiz
7%
Комментарий в коде
89%
Метаданные для классов, методов или полей
0%
Оператор для циклов
4%
Тип данных
Jackson
Аннотации Jackson для десериализации и изменения структуры JSON
Иногда структура входящего JSON не совпадает напрямую с полями Java-объекта. Для корректной десериализации в таких случаях Jackson предлагает ряд аннотаций, среди которых особенно важны @JsonCreator, @JsonSetter и @JsonAlias.
@JsonCreator
Аннотация @JsonCreator позволяет указать, какой именно конструктор или фабричный метод должен использоваться для создания объекта из JSON.
Особенно полезна в случаях, когда объект должен быть создан через специфический конструктор, а не через пустой и геттеры/сеттеры.
Пример:
При десериализации Jackson использует указанный конструктор, а не требует пустой конструктор и сеттеры:
@JsonSetter
Аннотация @JsonSetter указывается на методе и сообщает Jackson, что данный метод должен использоваться для установки значения при десериализации.
Это полезно, когда метод сеттера отличается по названию от поля или нужно выполнить какую-то дополнительную обработку значения.
Пример:
JSON:
@JsonAlias
Аннотация @JsonAlias позволяет указывать альтернативные имена полей, которые могут приходить в JSON. Это особенно полезно для работы с нестабильными или изменяющимися API.
Пример:
Теперь следующий JSON будет корректно обработан:
или
Пример нестандартного маппинга
Иногда API может менять структуру данных или использовать разные названия для одного и того же поля. Комбинируя @JsonCreator, @JsonProperty и @JsonAlias, можно добиться правильной обработки даже самых нестандартных случаев.
Например:
#Java #Training #Medium #Jackson #JsonCreator #JsonSetter #JsonAlias
Аннотации Jackson для десериализации и изменения структуры JSON
Иногда структура входящего JSON не совпадает напрямую с полями Java-объекта. Для корректной десериализации в таких случаях Jackson предлагает ряд аннотаций, среди которых особенно важны @JsonCreator, @JsonSetter и @JsonAlias.
@JsonCreator
Аннотация @JsonCreator позволяет указать, какой именно конструктор или фабричный метод должен использоваться для создания объекта из JSON.
Особенно полезна в случаях, когда объект должен быть создан через специфический конструктор, а не через пустой и геттеры/сеттеры.
Пример:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class User {
private final String name;
private final int age;
@JsonCreator
public User(@JsonProperty("name") String name,
@JsonProperty("age") int age) {
this.name = name;
this.age = age;
}
// Только геттеры
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
При десериализации Jackson использует указанный конструктор, а не требует пустой конструктор и сеттеры:
String json = "{\"name\":\"Alice\",\"age\":30}";
User user = objectMapper.readValue(json, User.class);
@JsonSetter
Аннотация @JsonSetter указывается на методе и сообщает Jackson, что данный метод должен использоваться для установки значения при десериализации.
Это полезно, когда метод сеттера отличается по названию от поля или нужно выполнить какую-то дополнительную обработку значения.
Пример:
import com.fasterxml.jackson.annotation.JsonSetter;
public class Product {
private String name;
public Product() {}
public String getName() {
return name;
}
@JsonSetter("product_name")
public void setName(String name) {
this.name = name.toUpperCase();
}
}
JSON:
{
"product_name": "laptop"
}
При десериализации будет вызван метод setName, а имя продукта будет автоматически приведено к верхнему регистру: "LAPTOP".
@JsonAlias
Аннотация @JsonAlias позволяет указывать альтернативные имена полей, которые могут приходить в JSON. Это особенно полезно для работы с нестабильными или изменяющимися API.
Пример:
import com.fasterxml.jackson.annotation.JsonAlias;
public class Customer {
@JsonAlias({"user_name", "login"})
private String username;
public Customer() {}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
Теперь следующий JSON будет корректно обработан:
{ "user_name": "admin" }
или
{ "login": "admin" }
И в обоих случаях значение попадет в поле username.
Пример нестандартного маппинга
Иногда API может менять структуру данных или использовать разные названия для одного и того же поля. Комбинируя @JsonCreator, @JsonProperty и @JsonAlias, можно добиться правильной обработки даже самых нестандартных случаев.
Например:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonAlias;
public class Employee {
private final String id;
private final String fullName;
@JsonCreator
public Employee(@JsonProperty("id") String id,
@JsonProperty("full_name") @JsonAlias({"name", "fullname"}) String fullName) {
this.id = id;
this.fullName = fullName;
}
public String getId() {
return id;
}
public String getFullName() {
return fullName;
}
}
Теперь Jackson корректно обработает JSON, где имя сотрудника приходит под разными ключами: full_name, name или fullname.
#Java #Training #Medium #Jackson #JsonCreator #JsonSetter #JsonAlias
Jackson
Работа со списками, картами и вложенными объектами
JSON — это не только простые объекты, но и сложные структуры: списки, словари, вложенные объекты. В этом посте разберем, как Jackson справляется с такими случаями, и как правильно сериализовать и десериализовать коллекции и составные структуры.
Списки объектов
Представим, что у нас есть список пользователей:
Сериализация списка в JSON:
Результат:
Десериализация списка обратно в Java:
Карты (мапы)
JSON-объект с произвольными ключами часто удобно мапить в Map<String, Object>.
Например:
Можно прочитать в Map:
Сериализация карты обратно:
Вложенные объекты
Вложенные структуры — это JSON, где одно поле содержит объект:
Соответствующий Java-класс:
Jackson автоматически корректно сериализует и десериализует такие вложенные объекты:
Результат:
И обратно:
Комбинирование структур
Jackson легко справляется с комбинацией вложенных объектов, списков и мап:
Нужно лишь правильно описать классы:
#Java #Training #Medium #Jackson
Работа со списками, картами и вложенными объектами
JSON — это не только простые объекты, но и сложные структуры: списки, словари, вложенные объекты. В этом посте разберем, как Jackson справляется с такими случаями, и как правильно сериализовать и десериализовать коллекции и составные структуры.
Списки объектов
Представим, что у нас есть список пользователей:
public class User {
private String name;
private int age;
public User() {}
public User(String name, int age) {
this.name = name;
this.age = age;
}
// Геттеры и сеттеры
}
Сериализация списка в JSON:
List<User> users = List.of(
new User("Alice", 30),
new User("Bob", 25)
);
String json = objectMapper.writeValueAsString(users);
System.out.println(json);
Результат:
[
{"name":"Alice","age":30},
{"name":"Bob","age":25}
]
Десериализация списка обратно в Java:
String jsonInput = "[{\"name\":\"Alice\",\"age\":30},{\"name\":\"Bob\",\"age\":25}]";
List<User> users = objectMapper.readValue(
jsonInput,
new TypeReference<List<User>>() {}
);
Здесь важно использовать TypeReference, чтобы сохранить информацию о типе во время десериализации.
Карты (мапы)
JSON-объект с произвольными ключами часто удобно мапить в Map<String, Object>.
Например:
{
"name": "Alice",
"age": 30,
"active": true
}
Можно прочитать в Map:
String json = "{\"name\":\"Alice\",\"age\":30,\"active\":true}";
Map<String, Object> map = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});
Сериализация карты обратно:
Map<String, Object> data = new HashMap<>();
data.put("name", "Alice");
data.put("age", 30);
data.put("active", true);
String jsonOutput = objectMapper.writeValueAsString(data);
Вложенные объекты
Вложенные структуры — это JSON, где одно поле содержит объект:
{
"id": 1,
"user": {
"name": "Alice",
"age": 30
}
}
Соответствующий Java-класс:
public class Wrapper {
private int id;
private User user;
public Wrapper() {}
public Wrapper(int id, User user) {
this.id = id;
this.user = user;
}
// Геттеры и сеттеры
}
Jackson автоматически корректно сериализует и десериализует такие вложенные объекты:
Wrapper wrapper = new Wrapper(1, new User("Alice", 30));
String json = objectMapper.writeValueAsString(wrapper);
Результат:
{
"id": 1,
"user": {
"name": "Alice",
"age": 30
}
}
И обратно:
String input = "{\"id\":1,\"user\":{\"name\":\"Alice\",\"age\":30}}";
Wrapper wrapper = objectMapper.readValue(input, Wrapper.class);
Комбинирование структур
Jackson легко справляется с комбинацией вложенных объектов, списков и мап:
{
"group": "admins",
"members": [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25}
],
"meta": {
"created": "2023-10-01",
"active": true
}
}
Нужно лишь правильно описать классы:
public class Group {
private String group;
private List<User> members;
private Map<String, Object> meta;
// Конструктор, геттеры, сеттеры
}
#Java #Training #Medium #Jackson
Что выведет код?
#Tasks
import java.util.*;
public class Task060525 {
public static void main(String[] args) {
TreeSet<String> tree = new TreeSet<>(Comparator.reverseOrder());
tree.add("B");
tree.add("A");
tree.add("C");
tree.add("A");
System.out.println(tree.pollFirst() + " " + tree.pollLast());
}
}
#Tasks
Please open Telegram to view this post
VIEW IN TELEGRAM
Вопросы с собеседования 👩💻
Что такое module в Java?
Что такое module в Java?
Anonymous Quiz
8%
Класс для работы с файлами
88%
Единица модульной организации кода
0%
Тип данных для чисел
5%
Метод для обработки исключений
Jackson
Кастомные десериализаторы
Иногда структура входящего JSON или требования к обработке данных слишком специфичны, и стандартной десериализации Jackson оказывается недостаточно. В таких случаях можно реализовать собственный десериализатор, унаследовавшись от JsonDeserializer.
Когда нужен кастомный десериализатор
— Нужно преобразовать нестандартный формат данных
— Нужно добавить проверку, валидацию, нормализацию
— Нужно маппить одно поле в несколько
— Нужно логировать, фильтровать, трансформировать содержимое JSON
Шаг 1: Создание собственного десериализатора
Для этого создаем класс, расширяющий JsonDeserializer<T>:
Шаг 2: Привязка десериализатора к полю
Теперь мы можем использовать наш кастомный десериализатор на нужном поле через аннотацию @JsonDeserialize.
Шаг 3: Пример использования
Что ещё можно делать в кастомных десериализаторах
— Преобразовывать дату из нестандартного формата
— Разбирать строки с разделителями (например, CSV в List)
— Валидировать числовые диапазоны
— Преобразовывать строки в enum с логикой по умолчанию
— Обрабатывать null как спецзначения
— Инъектировать зависимости (через context.findInjectableValue())
#Java #Training #Medium #Jackson
Кастомные десериализаторы
Иногда структура входящего JSON или требования к обработке данных слишком специфичны, и стандартной десериализации Jackson оказывается недостаточно. В таких случаях можно реализовать собственный десериализатор, унаследовавшись от JsonDeserializer.
Когда нужен кастомный десериализатор
— Нужно преобразовать нестандартный формат данных
— Нужно добавить проверку, валидацию, нормализацию
— Нужно маппить одно поле в несколько
— Нужно логировать, фильтровать, трансформировать содержимое JSON
Шаг 1: Создание собственного десериализатора
Для этого создаем класс, расширяющий JsonDeserializer<T>:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
public class NameDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String rawValue = p.getText();
if (rawValue == null || rawValue.trim().isEmpty()) {
throw new IOException("Имя не может быть пустым");
}
// Пример нормализации: первая буква заглавная
return rawValue.substring(0, 1).toUpperCase() + rawValue.substring(1).toLowerCase();
}
}
Шаг 2: Привязка десериализатора к полю
Теперь мы можем использовать наш кастомный десериализатор на нужном поле через аннотацию @JsonDeserialize.
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
public class User {
@JsonDeserialize(using = NameDeserializer.class)
private String name;
private int age;
public User() {}
// Геттеры и сеттеры
}
Шаг 3: Пример использования
String json = "{\"name\":\" aLiCe \", \"age\":30}";
User user = objectMapper.readValue(json, User.class);
System.out.println(user.getName()); // Выведет: Alice
Если в поле name будет пустая строка или только пробелы — Jackson выбросит исключение, как мы это настроили в десериализаторе.
Что ещё можно делать в кастомных десериализаторах
— Преобразовывать дату из нестандартного формата
— Разбирать строки с разделителями (например, CSV в List)
— Валидировать числовые диапазоны
— Преобразовывать строки в enum с логикой по умолчанию
— Обрабатывать null как спецзначения
— Инъектировать зависимости (через context.findInjectableValue())
#Java #Training #Medium #Jackson
Jackson
Глобальная настройка ObjectMapper: как управлять сериализацией и десериализацией
Jackson предоставляет удобный способ централизованно настраивать поведение через ObjectMapper. Эта конфигурация позволяет управлять форматированием JSON, обработкой неизвестных полей, null-значений и множеством других аспектов.
Инициализация ObjectMapper
1. Игнорирование неизвестных полей
По умолчанию Jackson выбросит исключение, если в JSON попадётся поле, которого нет в Java-классе.
Это можно отключить так:
Теперь лишние поля будут просто игнорироваться:
2. Красивая печать JSON (Pretty Print)
По умолчанию JSON сериализуется в одну строку. Чтобы включить форматирование с отступами:
Пример вывода:
3. Исключение null-полей
Если нужно убрать из JSON все поля с null, можно настроить так:
Пример:
Результат без email, если он null:
4. Ошибка при отсутствии обязательных полей
По умолчанию Jackson пропускает отсутствующие поля. Но можно требовать их наличия:
5. Написание чисел как строки
Результат:
6. Установка глобального формата дат
Когда это полезно
— В проектах с нестабильными API
— При интеграции с фронтендом, где важно форматирование
— При логировании JSON в читаемом виде
— Для обеспечения устойчивости к изменяющимся данным
#Java #Training #Medium #Jackson #ObjectMapper
Глобальная настройка ObjectMapper: как управлять сериализацией и десериализацией
Jackson предоставляет удобный способ централизованно настраивать поведение через ObjectMapper. Эта конфигурация позволяет управлять форматированием JSON, обработкой неизвестных полей, null-значений и множеством других аспектов.
Инициализация ObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
Можно использовать его напрямую или создать бин (например, в Spring).
1. Игнорирование неизвестных полей
По умолчанию Jackson выбросит исключение, если в JSON попадётся поле, которого нет в Java-классе.
Это можно отключить так:
import com.fasterxml.jackson.databind.DeserializationFeature;
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Теперь лишние поля будут просто игнорироваться:
{
"name": "Alice",
"age": 30,
"extra_field": "ignored"
}
2. Красивая печать JSON (Pretty Print)
По умолчанию JSON сериализуется в одну строку. Чтобы включить форматирование с отступами:
import com.fasterxml.jackson.databind.SerializationFeature;
mapper.enable(SerializationFeature.INDENT_OUTPUT);
Пример вывода:
{
"name" : "Alice",
"age" : 30
}
Это особенно полезно для логирования и отладки.
3. Исключение null-полей
Если нужно убрать из JSON все поля с null, можно настроить так:
import com.fasterxml.jackson.annotation.JsonInclude;
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
Пример:
public class User {
public String name;
public String email; // может быть null
}
Результат без email, если он null:
{
"name": "Alice"
}
4. Ошибка при отсутствии обязательных полей
По умолчанию Jackson пропускает отсутствующие поля. Но можно требовать их наличия:
mapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true);
mapper.configure(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES, true);
5. Написание чисел как строки
mapper.configure(SerializationFeature.WRITE_NUMBERS_AS_STRINGS, true);
Результат:
{
"age": "30"
}
6. Установка глобального формата дат
import java.text.SimpleDateFormat;
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
Когда это полезно
— В проектах с нестабильными API
— При интеграции с фронтендом, где важно форматирование
— При логировании JSON в читаемом виде
— Для обеспечения устойчивости к изменяющимся данным
#Java #Training #Medium #Jackson #ObjectMapper
Что выведет код?
#Tasks
import java.util.*;
public class Task070525 {
public static void main(String[] args) {
TreeMap<Integer, String> tree = new TreeMap<>();
tree.put(1, "Java");
tree.put(1, "Python");
tree.put(2, "C++");
tree.put(3, "Go");
tree.remove(2);
System.out.println(tree.subMap(1, true, 3, true).values());
}
}
#Tasks
Варианты ответа:
Anonymous Quiz
14%
[Python]
51%
[Python, Go]
23%
[Java, Python, Go]
11%
[Python, C++, Go]
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM