Ответ
Проект: RESTful API для управления задачами (To-Do List) на Spring Boot.
Цель: Создать backend-сервис с полным циклом аутентификации, авторизации и CRUD-операций.
Стек технологий:
- Backend: Java 17, Spring Boot 3
- Безопасность: Spring Security, JWT (JSON Web Token)
- База данных: PostgreSQL, Spring Data JPA (Hibernate)
- Документация: OpenAPI 3 (Springdoc)
- Тестирование: JUnit 5, Mockito, Testcontainers
Ключевые компоненты и реализация:
-
JWT Аутентификация и Авторизация:
- Реализован фильтр для проверки JWT-токена в каждом запросе.
@Component public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String authHeader = request.getHeader("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { String jwt = authHeader.substring(7); String username = jwtUtil.extractUsername(jwt); // Утилита для работы с JWT if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { if (jwtUtil.validateToken(jwt, username)) { // Создание объекта Authentication и установка в SecurityContext UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, null, authorities); SecurityContextHolder.getContext().setAuthentication(authToken); } } } chain.doFilter(request, response); } }
- Реализован фильтр для проверки JWT-токена в каждом запросе.
-
Слой данных (Repository):
- Использовал Spring Data JPA для декларативного доступа к данным.
@Repository public interface TaskRepository extends JpaRepository<Task, Long> { List<Task> findByUserIdAndCompleted(Long userId, boolean completed); @Query("SELECT t FROM Task t WHERE t.dueDate < :date AND t.completed = false") List<Task> findOverdueTasks(@Param("date") LocalDate date); }
- Использовал Spring Data JPA для декларативного доступа к данным.
-
Обработка больших данных (отдельный модуль):
- Парсер CSV-файлов с использованием Java Stream API и многопоточности (
ForkJoinPool) для импорта задач.public List<Task> parseCsvFile(Path filePath) throws IOException { return Files.lines(filePath) .skip(1) // Пропуск заголовка .parallel() // Параллельная обработка строк .map(line -> line.split(",")) .filter(parts -> parts.length == 3) .map(parts -> new Task(parts[0], parts[1], LocalDate.parse(parts[2]))) .collect(Collectors.toList()); }
- Парсер CSV-файлов с использованием Java Stream API и многопоточности (
Что было реализовано:
- Регистрация и вход пользователя с выдачей JWT.
- CRUD для задач с привязкой к пользователю.
- Фильтрация и пагинация задач.
- Интеграционные и unit-тесты.
- Docker-контейнеризация приложения и БД.
Итог: Проект продемонстрировал навыки работы с ключевыми Spring-технологиями, проектированием API, безопасностью и эффективной обработкой данных.
Ответ 18+ 🔞
Слушай, смотри, я тут наспрингбутил один проект — типа умный список дел, REST API. Ну, чтобы таски создавать, удалять, всё такое. В общем, обычная история, но я её, блядь, так закрутил, что сам от себя офигеваю.
Чё за хрень получилась: Ну, бэкенд, ясен пень, на Java 17 и Spring Boot 3. База — PostgreSQL, потому что нахуй эти игрушечные H2 для прода. Безопасность — Spring Security с JWT, чтобы эти, блядь, токены по заголовкам летали. Документацию на OpenAPI накрутил, чтобы не тыкаться вслепую. И тесты, мать их, JUnit с Testcontainers, чтобы всё как у больших.
А теперь про самое сокровенное, как я это всё ебал:
-
JWT — ебать его в сраку, этот токен. Сделал фильтр, который каждый запрос ловит и смотрит: а есть ли там в заголовках этот самый
Bearer? Если есть — выковыривает оттуда токен и начинает его проверять. Если всё чисто — пускает дальше, а если нет — нахуй. Код вот, смотри, не трогай его:@Component public class JwtAuthenticationFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String authHeader = request.getHeader("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { String jwt = authHeader.substring(7); String username = jwtUtil.extractUsername(jwt); // Утилита для работы с JWT if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { if (jwtUtil.validateToken(jwt, username)) { // Создание объекта Authentication и установка в SecurityContext UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, null, authorities); SecurityContextHolder.getContext().setAuthentication(authToken); } } } chain.doFilter(request, response); } }Всё, больше в этот код не лезь, он работает, ёпта.
-
База данных — тут вообще магия. Взял Spring Data JPA и просто объявил интерфейс. А он, сука, сам все методы из названия понимает! Хочешь найти все задачи пользователя по айди и статусу? Пожалуйста, пиши
findByUserIdAndCompleted. Хочешь просроченные задачи? На, держи кастомный запрос с@Query. Вообще охуенно.@Repository public interface TaskRepository extends JpaRepository<Task, Long> { List<Task> findByUserIdAndCompleted(Long userId, boolean completed); @Query("SELECT t FROM Task t WHERE t.dueDate < :date AND t.completed = false") List<Task> findOverdueTasks(@Param("date") LocalDate date); }Красота, блядь, а не код. Ни одной лишней строчки.
-
А вот это вообще пиздец — обработка CSV-файлов. Представь, тебе заливают файл на овердохуища задач. Надо всё распарсить и в базу запихнуть. Я сделал это с помощью Java Stream API и параллельной обработки. Читаем файл построчно, первую строку (заголовок) — нахуй, а дальше в параллель всё обрабатываем. Скорость — просто улёт.
public List<Task> parseCsvFile(Path filePath) throws IOException { return Files.lines(filePath) .skip(1) // Пропуск заголовка .parallel() // Параллельная обработка строк .map(line -> line.split(",")) .filter(parts -> parts.length == 3) .map(parts -> new Task(parts[0], parts[1], LocalDate.parse(parts[2]))) .collect(Collectors.toList()); }Вот так вот, чих-пых, и миллион записей обработан.
В итоге что получилось: Человек регистрируется, логинится, получает свой JWT-токен. Потом с этим токеном может делать с задачами что хочет: создавать, читать, обновлять, удалять — всё только свои, чужие не увидит. Можно фильтровать, по страницам листать. Всё затестировано, ёбта, и даже в Docker завернуто, чтобы одним махом поднималось.
Вывод: Проект, конечно, учебный, но я в нём все ключевые плюшки Spring'а попробовал — от безопасности до работы с данными. Получилось, вроде, неплохо, даже самому не стыдно.