Java for Beginner
677 subscribers
546 photos
155 videos
12 files
836 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Варианты ответа:
Anonymous Quiz
19%
15
10%
12
57%
9
14%
6
Это отец подложил?🧐😂

https://t.me/Java_for_beginner_dev

#Mems
Настройка сериализации данных в Spring

Сериализация данных — это процесс преобразования объектов в формат, пригодный для передачи (например, JSON или XML). В Spring сериализация используется для обмена данными между клиентом и сервером, в основном в рамках RESTful API.

Spring поддерживает сериализацию данных через такие библиотеки, как:
Jackson для JSON,
JAXB или другие парсеры для XML.


Настройка сериализации в Spring позволяет управлять тем, как данные преобразуются и передаются клиентам.

Основы сериализации данных в Spring

Использование аннотации @RestController
Аннотация @RestController позволяет автоматизировать процесс сериализации. Методы, возвращающие объекты, автоматически сериализуют их в указанный формат (например, JSON или XML).

Пример контроллера:
@RestController
@RequestMapping("/users")
public class UserController {

@GetMapping("/{id}")
public User getUser(@PathVariable int id) {
return new User(1, "John Doe", 30);
}
}


Выходной формат по умолчанию (JSON):
{
"id": 1,
"name": "John Doe",
"age": 30
}


Настройка формата ответа через заголовки

Клиент может указать, в каком формате он хочет получить данные, с помощью заголовка Accept:

Accept: application/json — вернуть JSON.
Accept: application/xml — вернуть XML.

Spring автоматически определит нужный формат, если конфигурация включает поддержку соответствующих библиотек.

Настройка сериализации в JSON

Spring использует библиотеку Jackson для работы с JSON. Она предоставляется по умолчанию, если в проект добавлен модуль spring-boot-starter-web.

Зависимость Jackson (если нужно вручную):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>


Настройка свойств через аннотации Jackson

Исключение ненужных полей: Используйте @JsonIgnore для исключения определённых полей из сериализации:
public class User {
private int id;
private String name;

@JsonIgnore
private String password;
}


Переименование полей: Используйте @JsonProperty для указания имени поля в JSON:
public class User {
@JsonProperty("user_id")
private int id;
private String name;
}


Настройка формата дат: Для работы с датами можно использовать @JsonFormat:
public class Event {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime eventDate;
}


Исключение пустых или null полей: Можно настроить глобально через файл application.properties:
spring.jackson.default-property-inclusion=non_null


Или с помощью аннотации @JsonInclude:
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
private String name;
private String email;
}


Настройка сериализации в XML

Для работы с XML используется библиотека JAXB или другие парсеры.


Зависимость JAXB:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>


Использование аннотаций JAXB


Аннотация @XmlRootElement: Указывает корневой элемент XML:
@XmlRootElement
public class User {
private int id;
private String name;

// Геттеры и сеттеры...
}


Указание имени поля в XML: Используйте @XmlElement:
public class User {
@XmlElement(name = "user_id")
private int id;
}


Исключение полей: Используйте
@XmlTransient:
public class User {
@XmlTransient
private String password;
}


#Java #Training #Spring #Serialization
Глобальная настройка сериализации

Настройка через ObjectMapper:
ObjectMapper — это основной класс Jackson для управления сериализацией и десериализацией JSON. Его можно настроить через бин в Spring:
@Configuration
public class JacksonConfig {

@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return mapper;
}
}


Настройка глобального форматирования дат: В application.properties:
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss


Обработка ошибок при сериализации

Если при сериализации возникают ошибки, например, несоответствие типов, Spring возвращает стандартное сообщение об ошибке.
{
"timestamp": "2024-12-11T12:00:00",
"status": 400,
"error": "Bad Request",
"message": "Cannot deserialize value of type 'int' from String \"abc\""
}


Чтобы настроить собственный обработчик ошибок, можно использовать @ControllerAdvice:
@ControllerAdvice
public class CustomExceptionHandler {

@ExceptionHandler(JsonMappingException.class)
public ResponseEntity<String> handleJsonMappingException(JsonMappingException ex) {
return ResponseEntity.badRequest().body("Ошибка в JSON данных: " + ex.getMessage());
}
}


Выбор формата ответа на уровне метода

Если нужно вручную управлять форматом данных для отдельных методов, можно использовать параметр produces в аннотациях:
@GetMapping(value = "/user/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public User getUserAsJson(@PathVariable int id) {
return new User(1, "John Doe", 30);
}

@GetMapping(value = "/user/{id}", produces = MediaType.APPLICATION_XML_VALUE)
public User getUserAsXml(@PathVariable int id) {
return new User(1, "John Doe", 30);
}


Тестирование сериализации


Для проверки работы сериализации можно использовать инструменты, такие как:

Postman: отправлять запросы и проверять ответ.
Spring MockMvc: тестирование сериализации на уровне кода:

@Test
public void testJsonSerialization() throws Exception {
mockMvc.perform(get("/users/1")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("John Doe"));
}


#Java #Training #Spring #Serialization
Работа с HTTP-методами в Spring: GET, POST, PUT, DELETE

HTTP-методы (или «глаголы») — это действия, которые клиент может выполнять на ресурсе в веб-приложении. В контексте RESTful архитектуры, они представляют собой стандартные операции для взаимодействия с ресурсами.

Spring предоставляет удобный механизм работы с HTTP-методами через аннотации контроллеров, такие как @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, которые упрощают реализацию RESTful API.

Настройка HTTP-методов в Spring


Общий пример контроллера
@RestController
@RequestMapping("/api/users")
public class UserController {

@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return new User(id, "John Doe", "john@example.com");
}

@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
user.setId(1L); // Пример генерации ID
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}

@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
return ResponseEntity.ok(user);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
return ResponseEntity.noContent().build();
}
}


HTTP-методы


1. GET — Чтение данных

Назначение: Возвращает данные с сервера (например, список пользователей, детали одного пользователя).
Идемпотентный метод: Повторный вызов GET не изменяет состояние ресурса.


Пример запроса:
GET /api/users/1 HTTP/1.1
Host: example.com


Реализация в Spring:
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return new User(id, "John Doe", "john@example.com");
}


Особенности:
Используется аннотация @GetMapping.
Данные возвращаются в формате JSON или XML в зависимости от заголовка Accept.


2. POST — Создание нового ресурса
Назначение: Создает новый ресурс на сервере.
Не идемпотентный метод: Повторный вызов создаёт новые записи.


Пример запроса:
POST /api/users HTTP/1.1
Content-Type: application/json
Host: example.com

{
"name": "Jane Doe",
"email": "jane@example.com"
}


Реализация в Spring:

@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
user.setId(1L); // Симуляция сохранения с генерацией ID
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}


Особенности:
Используется аннотация @PostMapping.
Данные передаются через тело запроса (
@RequestBody).
В ответе часто возвращается код 201 Created и URL нового ресурса.


3. PUT — Обновление ресурса
Назначение: Обновляет существующий ресурс или создаёт его, если он не существует.
Идемпотентный метод: Повторный вызов приводит к тому же результату.


Пример запроса:
PUT /api/users/1 HTTP/1.1
Content-Type: application/json
Host: example.com

{
"name": "John Smith",
"email": "john.smith@example.com"
}


Реализация в Spring:
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id); // Симуляция обновления ресурса
return ResponseEntity.ok(user);
}


Особенности:
Используется аннотация @PutMapping.
Данные для обновления передаются через тело запроса.
В ответе обычно возвращается 200 OK с обновлённым ресурсом.


4. DELETE — Удаление ресурса
Назначение: Удаляет ресурс на сервере.
Идемпотентный метод: Повторный вызов приводит к тому же результату (ресурс уже удалён).


Пример запроса:
DELETE /api/users/1 HTTP/1.1
Host: example.com


Реализация в Spring:
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
return ResponseEntity.noContent().build();
}


Особенности:
Используется аннотация @DeleteMapping.
В ответе часто возвращается 204 No Content.


#Java #Training #Spring #GET #PUT #POST #DELETE
Примеры сложных сценариев

1. Обработка ошибок
Если ресурс не найден, можно вернуть соответствующий HTTP-ответ:
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.status(HttpStatus.NOT_FOUND).build());
}


2. Валидация данных

Использование @Valid для проверки корректности входящих данных:
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
user.setId(1L);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}


Пример ошибок валидации:
{
"timestamp": "2024-12-11T12:00:00",
"status": 400,
"errors": [
{
"field": "name",
"message": "Name is required"
}
]
}


3. Поддержка разных форматов данных
Spring поддерживает автоматическое преобразование данных в зависимости от заголовков запроса:
JSON (application/json)
XML (application/xml)


Пример настройки:
@GetMapping(value = "/{id}", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
public User getUser(@PathVariable Long id) {
return new User(id, "John Doe", "john@example.com");
}


#Java #Training #Spring #GET #PUT #POST #DELETE
Что выведет код?

import java.util.HashSet;
import java.util.Set;

public class Task201224_1 {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
set.add(2);
set.add(1);

System.out.println(set.size());
}
}


#Tasks
Варинаты ответа:
Anonymous Quiz
30%
5
0%
4
70%
3
0%
2
И куча банков🙈😂

https://t.me/Java_for_beginner_dev

#Mems
Создание CRUD API в Spring

Разработка CRUD API (Create, Read, Update, Delete) — стандартная задача для построения RESTful приложений. Использование Spring Boot и PostgreSQL позволяет быстро и эффективно создать такое API.

Шаг 1: Создание проекта Spring Boot

Перейдите на Spring Initializr.

Выберите:
Project: Maven.
Language: Java.
Dependencies: Spring Web, Spring Data JPA, PostgreSQL Driver, Validation (для валидации данных).
Скачайте проект и откройте его в IDE.


Шаг 2: Настройка подключения к PostgreSQL

Добавьте настройки базы данных в файл application.properties.

Пример application.properties:
spring.datasource.url=jdbc:postgresql://localhost:5432/my_database
spring.datasource.username=postgres
spring.datasource.password=password

spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect


Расшифровка настроек:
spring.datasource.url: URL подключения к PostgreSQL (с указанием базы данных).
spring.jpa.hibernate.ddl-auto: Автоматическое управление схемой базы данных (update, create, none).
spring.jpa.show-sql: Показывать SQL-запросы в консоли.
spring.jpa.properties.hibernate.dialect: Dialect Hibernate для PostgreSQL.


Шаг 3: Создание сущности (Entity)

Сущность представляет таблицу в базе данных.
import jakarta.persistence.*;
import jakarta.validation.constraints.*;

@Entity
@Table(name = "users")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotBlank(message = "Name is mandatory")
private String name;

@Email(message = "Email should be valid")
@NotBlank(message = "Email is mandatory")
private String email;

@NotNull(message = "Age is mandatory")
private Integer age;
// Геттеры и сеттеры...
}


Примечания:
Аннотация @Entity связывает класс с таблицей в базе данных.
Аннотация @Id указывает первичный ключ.
Аннотация
@GeneratedValue используется для автоинкремента.
@Table(name = "users") указывает имя таблицы.
Аннотации валидации (@NotBlank, @Email, @NotNull) проверяют корректность данных.

Шаг 4: Создание слоя доступа к данным (Repository)

Интерфейс репозитория предоставляет методы для взаимодействия с базой данных.
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
}


Особенности:
JpaRepository предоставляет стандартные CRUD-методы (save, findById, findAll, deleteById).
Не нужно реализовывать методы вручную.


Шаг 5: Реализация бизнес-логики (Service)

Слой Service инкапсулирует логику работы с данными.
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Service
public class UserService {

private final UserRepository userRepository;

@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}

public List<User> getAllUsers() {
return userRepository.findAll();
}

public User getUserById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("User not found with id: " + id));
}

public User createUser(User user) {
return userRepository.save(user);
}

public User updateUser(Long id, User updatedUser) {
User existingUser = getUserById(id);
existingUser.setName(updatedUser.getName());
existingUser.setEmail(updatedUser.getEmail());
existingUser.setAge(updatedUser.getAge());
return userRepository.save(existingUser);
}

public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}


Примечания:
Методы инкапсулируют работу с UserRepository.
Если пользователь не найден, выбрасывается исключение.


#Java #Training #Spring #CRUD_API
Шаг 6: Создание REST-контроллера

Контроллер обрабатывает HTTP-запросы и возвращает данные клиенту.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

private final UserService userService;

@Autowired
public UserController(UserService userService) {
this.userService = userService;
}

@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}

@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return ResponseEntity.ok(userService.getUserById(id));
}

@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
return ResponseEntity.status(201).body(userService.createUser(user));
}

@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @Valid @RequestBody User user) {
return ResponseEntity.ok(userService.updateUser(id, user));
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return ResponseEntity.noContent().build();
}
}


Примечания:
Методы контроллера возвращают данные с помощью ResponseEntity.
Данные валидируются аннотацией
@Valid.
Используются стандартные HTTP-коды:
200 OK для успешных операций.
201 Created для создания ресурса.
204 No Content для удаления.


Шаг 7: Тестирование API

Пример запросов (с использованием Postman или curl):

Получение всех пользователей:
GET http://localhost:8080/api/users


Получение пользователя по ID:
GET http://localhost:8080/api/users/1


Создание пользователя:
POST http://localhost:8080/api/users
Content-Type: application/json

{
"name": "Jane Doe",
"email": "jane.doe@example.com",
"age": 28
}


Обновление пользователя:
PUT http://localhost:8080/api/users/1
Content-Type: application/json

{
"name": "John Smith",
"email": "john.smith@example.com",
"age": 35
}


Удаление пользователя:
DELETE http://localhost:8080/api/users/1


Дополнительные возможности

Обработка ошибок: Добавьте обработчик ошибок с помощью @ControllerAdvice:
@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleRuntimeException(RuntimeException ex) {
return ResponseEntity.status(404).body(ex.getMessage());
}
}


Тестирование с помощью MockMvc:
@SpringBootTest
@AutoConfigureMockMvc
public class UserControllerTest {

@Autowired
private MockMvc mockMvc;

@Test
public void testGetAllUsers() throws Exception {
mockMvc.perform(get("/api/users"))
.andExpect(status().isOk());
}
}


#Java #Training #Spring #CRUD_API
Доброго субботнего утра! ☀️

Как Ваши дела? Елку поставили?🎄

Готовлю на завтра выполнение тестового задания от одного из работодателей с hh.ru.🤌

Посмотрим, разберем, да что-нибудь напишем🤪😂

Всем хороших выходных🎉
Всем привет!

В 16:00 по МСК, я вновь жду Вас на встрече в Яндекс.Телемост!

Попробуем сделать тестовое задание от работодателя на hh.ru, обсудим детали)

Жду всех!✌️
Встреча создана!

https://telemost.yandex.ru/j/89268837201575

Залетаем!
Пишем тестовое задание от реального работодателя. Встреча от 22.12.2024

Запись нашей сегодняшней встречи -
YOUTUBE
RUTUBE

Крайне благодарен всем кто пришел, за участие!💪

На сегодняшней встрече мы начали писать тестовый сервис по документации реального работодателя с hh.ru:
— разобрали логику приложения
— создали сущность и Dto
— начали писать сервисы и контроллер


Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!

Всем хорошего настроения! 🫡✌️
Всем доброго утра!

Есть вопрос - вчера мы начали писать тестовый сервис хранения носков на складе. Стоит ли продолжить? И второй момент, что можно это сделать в середине недели. Вас это устроит, или привычнее вечер воскресения?
Anonymous Poll
88%
Да, продолжай в любой день!
8%
Да, но мне удобнее быть в воскресение
0%
Какой сервис, о чем ты?
0%
Не, не стоит продолжать, не интересно
4%
Хватит выкладывать всякую чушь!
Пагинация и фильтрация данных в REST API с использованием Spring

При работе с большими наборами данных в REST API критически важна поддержка пагинации и фильтрации. Они позволяют улучшить производительность приложения, сократить нагрузку на сервер и предоставить клиентам удобные способы получать нужные данные.

1. Пагинация (Pagination) в Spring

Пагинация позволяет разделить большие объемы данных на страницы и возвращать их по частям. В Spring Boot пагинация реализуется с помощью Spring Data JPA.

Подключение пагинации в проекте

Spring Data JPA предоставляет интерфейсы и аннотации для легкой реализации пагинации.

Добавьте параметр Pageable в методы репозитория:
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

Page<User> findAll(Pageable pageable);

}


Page — это контейнер, который содержит данные текущей страницы и мета-информацию (например, общее количество страниц).
Pageable — это интерфейс для параметров пагинации: номер страницы, размер страницы и сортировка.


Использование Pageable в контроллере:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

private final UserRepository userRepository;

@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}

@GetMapping
public ResponseEntity<Page<User>> getAllUsers(Pageable pageable) {
Page<User> users = userRepository.findAll(pageable);
return ResponseEntity.ok(users);
}
}


Пример запроса с пагинацией:
GET /api/users?page=0&size=5&sort=name,asc
page — номер страницы (начинается с 0).
size — количество элементов на странице.
sort — параметры сортировки (поле,направление).


Пример ответа:
{
"content": [
{"id": 1, "name": "John", "email": "john@example.com"},
{"id": 2, "name": "Jane", "email": "jane@example.com"}
],
"pageable": {
"pageNumber": 0,
"pageSize": 5
},
"totalPages": 2,
"totalElements": 10,
"last": false
}


2. Фильтрация данных в REST API

Фильтрация позволяет клиентам задавать условия, по которым нужно отбирать данные.


Подходы к фильтрации

Фильтрация по параметрам запроса (Request Parameters): Используется для простой фильтрации данных.

Динамическая фильтрация с помощью Specification или Criteria:
Применяется для сложных и многоуровневых условий.

Фильтрация по параметрам запроса
Реализация простого поиска с фильтрацией:

Добавьте методы в репозиторий:
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

List<User> findByNameContaining(String name);

List<User> findByAgeGreaterThanEqual(Integer age);

}


#Java #Training #Spring #Pagination #Filter
Добавьте фильтры в контроллер:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

private final UserRepository userRepository;

@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}

@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age) {

if (name != null) {
return ResponseEntity.ok(userRepository.findByNameContaining(name));
} else if (age != null) {
return ResponseEntity.ok(userRepository.findByAgeGreaterThanEqual(age));
} else {
return ResponseEntity.ok(userRepository.findAll());
}
}
}


Примеры запросов:

Фильтрация по имени:
GET /api/users/search?name=John


Фильтрация по возрасту:
GET /api/users/search?age=30


Динамическая фильтрация с использованием Specification
Для сложных фильтров можно использовать Spring Data JPA Specification.

Добавьте зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>


Создайте Specification для фильтрации:
import org.springframework.data.jpa.domain.Specification;

public class UserSpecification {

public static Specification<User> hasName(String name) {
return (root, query, cb) -> cb.like(root.get("name"), "%" + name + "%");
}

public static Specification<User> hasAgeGreaterThan(Integer age) {
return (root, query, cb) -> cb.greaterThanOrEqualTo(root.get("age"), age);
}
}


Расширьте репозиторий:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}


Добавьте динамическую фильтрацию в контроллер:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

private final UserRepository userRepository;

@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}

@GetMapping("/filter")
public ResponseEntity<List<User>> filterUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age) {

Specification<User> spec = Specification.where(null);

if (name != null) {
spec = spec.and(UserSpecification.hasName(name));
}

if (age != null) {
spec = spec.and(UserSpecification.hasAgeGreaterThan(age));
}

return ResponseEntity.ok(userRepository.findAll(spec));
}
}


Пример запроса с фильтрацией:

GET /api/users/filter?name=Jane&age=25


3. Пагинация и фильтрация вместе

Совмещение пагинации и фильтрации:
@GetMapping("/filter")
public ResponseEntity<Page<User>> filterUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age,
Pageable pageable) {

Specification<User> spec = Specification.where(null);

if (name != null) {
spec = spec.and(UserSpecification.hasName(name));
}

if (age != null) {
spec = spec.and(UserSpecification.hasAgeGreaterThan(age));
}

Page<User> result = userRepository.findAll(spec, pageable);
return ResponseEntity.ok(result);
}


Пример запроса:
GET /api/users/filter?name=Jane&page=0&size=5&sort=age,desc


#Java #Training #Spring #Pagination #Filter
Что выведет код?

import java.util.HashMap;
import java.util.Map;

public class Task231224_1 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("a", 3);
map.put("c", null);

System.out.println(map.get("a") + " " + map.get("c"));
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
43%
1 null
4%
3 0
52%
3 null
0%
2 null
И поднять его теперь не так просто🤪😂

https://t.me/Java_for_beginner_dev

#Mems