Библиотека Java разработчика
10.5K subscribers
1.17K photos
594 videos
58 files
1.49K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Download Telegram
🎮 Анатомия REST Controller: Входящие и Исходящие

Раньше, чтобы вернуть JSON, нужно было танцевать с бубном. В Spring Boot это делается "из коробки" благодаря библиотеке Jackson, которая тихо работает в фоне.

1️⃣ @RestController vs @Controller

Это первый вопрос на собеседовании.

🔴@Controller: Олдскул. Используется, когда мы возвращаем HTML-страницы (Thymeleaf, JSP). Чтобы вернуть JSON, нужно над каждым методом вешать @ResponseBody.
🔴@RestController: Современный стандарт для REST API.
🔴Это просто @Controller + @ResponseBody над всеми методами.
🔴Всё, что возвращает метод, автоматически превращается в JSON.



2️⃣ Принимаем данные (3 главных способа)

Как вытащить информацию из запроса?

А. Из пути URL (@PathVariable)
Используем, когда параметр - это часть адреса ресурса.

🔴URL: GET /users/42
🔴Код:

@GetMapping("/users/{id}")
public User getById(@PathVariable Long id) { ... }





Б. Из параметров запроса (@RequestParam)
Используем для фильтрации, сортировки или опциональных параметров.

URL: GET /users?role=ADMIN&age=25
Код:

@GetMapping("/users")
public List<User> search(
@RequestParam String role,
@RequestParam(required = false) Integer age // Опционально
) { ... }





В. Из тела запроса (@RequestBody)
Используем для отправки сложных объектов (обычно в POST/PUT запросах). Spring возьмет JSON и сам превратит его в Java-объект (DTO).

JSON: { "name": "Alex", "email": "a@b.com" }
Код:

@PostMapping("/users")
public User create(@RequestBody UserDto userDto) { ... }





3️⃣ Управляем ответом (ResponseEntity)

Просто вернуть объект User, это хорошо (статус будет 200 OK). Но что, если мы хотим вернуть 404 (Not Found) или 201 (Created)?

Для этого используем обертку ResponseEntity<T>.

💻 Пример: Идеальный контроллер


@RestController
@RequestMapping("/api/v1/users") // Общий префикс для всех методов
public class UserController {

private final UserService service; // Внедряем через конструктор

public UserController(UserService service) {
this.service = service;
}

// 1. Получить всех (GET 200 OK)
@GetMapping
public List<User> getAll() {
return service.findAll();
}

// 2. Найти одного (с управлением статусом)
@GetMapping("/{id}")
public ResponseEntity<User> getOne(@PathVariable Long id) {
return service.findById(id)
.map(user -> ResponseEntity.ok(user)) // 200 OK
.orElse(ResponseEntity.notFound().build()); // 404 Not Found
}

// 3. Создать (POST 201 Created)
@PostMapping
public ResponseEntity<User> create(@RequestBody UserDto dto) {
User created = service.save(dto);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
}
}



Jackson Magic (Pro-Tip)

Иногда вам не нужно отдавать все поля объекта (например, пароль).
Не пишите код для скрытия! Используйте аннотации Jackson прямо в DTO:

@JsonIgnore - поле не попадет в JSON.
@JsonProperty("full_name") - поле fullName в Java станет full_name в JSON.

🔥 Итог

• Используйте @RestController для API.
@PathVariable - для ID (/users/1).
@RequestParam - для фильтров (/users?sort=name).
@RequestBody - для больших данных (JSON).
• Возвращайте ResponseEntity, чтобы контролировать HTTP-статусы.

#SpringBoot #REST #Controller #API #Java


📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41
🔴 Завтра тестовое собеседование с Java-разработчиком

21 января(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_sh_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
💾 Spring Data JPA: SQL больше не нужен?

Spring Data JPA это абстракция над Hibernate (который, в свою очередь, является реализацией JPA).
Его главная киллер-фича: Генерация запросов из названий методов.

🏗 1. Сущность (@Entity)

Сначала мы объясняем Java, как выглядит наша таблица. Обычный класс превращается в таблицу с помощью пары аннотаций.


@Entity // Это таблица в БД
@Table(name = "users")
public class User {
@Id // Это Primary Key
@GeneratedValue(strategy = GenerationType.IDENTITY) // Авто-инкремент
private Long id;

private String email;
private int age;
private boolean active;

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



🪄 2. Репозиторий (Магия)

Вместо написания класса UserDao, мы просто создаем интерфейс.


public interface UserRepository extends JpaRepository<User, Long> {
// Здесь пусто! Но методы уже есть.
}



Наследуясь от JpaRepository, вы сразу получаете готовые методы:

🔴.save(user) - сохранить/обновить.
🔴.findById(id) - найти по ID (возвращает Optional).
🔴.findAll() - найти всех.
🔴.deleteById(id) - удалить.

Ни одной строчки SQL писать не пришлось! 😎

🔮 3. Derived Queries (Запросы из имени)

Что, если нужно найти пользователя по email? Или всех активных пользователей старше 18 лет?
Вы просто пишете метод в интерфейсе с правильным названием, и Spring сам составляет SQL-запрос.


public interface UserRepository extends JpaRepository<User, Long> {

// SQL: SELECT * FROM users WHERE email = ?
Optional<User> findByEmail(String email);

// SQL: SELECT * FROM users WHERE active = true AND age > ?
List<User> findByActiveTrueAndAgeGreaterThan(int age);

// SQL: EXISTS (SELECT 1 FROM users WHERE email = ?)
boolean existsByEmail(String email);
}



Синтаксис простой: find + By + ИмяПоля + Условие (если нужно).

🛠 4. Если магия не справилась (@Query)

Иногда названия методов становятся слишком длинными и уродливыми (findByNameAndAgeAndActiveAnd...). Или нужен сложный JOIN.
Тогда мы берем управление в свои руки и пишем запрос на JPQL (Java Persistence Query Language) - это SQL, но оперирующий классами, а не таблицами.


@Query("SELECT u FROM User u WHERE u.email LIKE %:domain%")
List<User> findUsersByEmailDomain(@Param("domain") String domain);



Транзакции (@Transactional)

База данных требует транзакций (всё или ничего).
В Spring Boot методы репозитория уже транзакционны (только на чтение).
Если же вы в сервисе делаете несколько операций подряд (снять деньги, перевести деньги), вешайте @Transactional над методом сервиса.


@Service
public class PaymentService {
@Transactional // Если упадет ошибка, все изменения откатятся
public void transferMoney() {
repo.withdraw(...);
repo.deposit(...);
}
}



🔥 Итог

Spring Data JPA убирает 90% рутинной работы с БД.

1. Создали @Entity.
2. Создали интерфейс extends JpaRepository.
3. Нужен поиск? Написали метод findByField.
4. Сложный запрос? Написали @Query.

#SpringBoot #JPA #Hibernate #Database #SQL

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4