Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ target/

### IntelliJ IDEA ###
.idea
*.iml


### Eclipse ###
Expand Down
28 changes: 28 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Quest LedZeppelin

### Ребята и девчата, всем привет!

На этот раз у нас более сложный проект, который будет трудно объединить в один общий проект со всем зависимостями.
Поэтому поступим просто. Тут первоначально лежит наш учебный проект.
Заготовка, такая же как может быть сгенерирована в IDEA.
Договоримся, что Java у нас будет 21-я. У всех. Привыкайте использовать только LTS.
Из зависимостей есть jakarta.servlet-api + jstl, JUnit5 и Lombok,
так что POM.xml возможно надо будет заменить на свой.

### Что нужно сделать.

1. Сделайте форк и затем клон этого репозитория.
2. **СРАЗУ** создайте в нем ветку со своей фамилией, например, ivanov.
3. Размещайте в своей ветке свое решение (если мои примеры мешают их можно просто удалить - ветвление же).
4. В конце вам нужно будет сделать **Pull Request** из своей ветки (в своем форке) в такую же точно ветку (в этом удаленном
репозитории), если вы не найдете - тогда в **main** ну и затем ОБЯЗАТЕЛЬНО заполнить форму проектов.
5. Я положу в ветку **khmelov** тот пример, который буду параллельно с вами разрабатывать на факультативах. Полезнее будет
не копипастить, смотрите видео, разбирайтесь, что, почему, где и как сделано. Не копируйте, нужно ВАШЕ решение. Но мы уже и
не совсем зеленые, правда ведь ;).
6. Проверять проекты по итогам третьего модуля я буду с **code review**, и скорее всего быстро не получится, так что за
сроки сдачи можно не волноваться.
7. Планируйте время так, первые три консультации - основной функционал. Последняя консультация - плюшки, рефакторинг,
тесты, красоты.
8. Если будут какие-то моменты - я обновлю это README. Поглядывайте периодически.

#### _2024 JRU LedZeppelin, Александр Хмелев._
33 changes: 33 additions & 0 deletions src/main/java/com/javarush/GameRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.javarush;

import java.time.LocalDateTime;

public class GameRecord {
private LocalDateTime timestamp;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поля класса рекомендуется делать финальными, если объект не предполагает изменения после создания. Это обеспечивает потокобезопасность и упрощает логику.

private int score;
private boolean isWin;

public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}

public void setScore(int score) {
this.score = score;
}

public void setWin(boolean win) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Имя сеттера 'setWin' не совсем соответствует имени поля 'isWin'. Рекомендуется использовать 'setWon' или переименовать поле в 'win' для единообразия с 'isWin()'.

isWin = win;
}

public LocalDateTime getTimestamp() {
return timestamp;
}

public int getScore() {
return score;
}

public boolean isWin() {
return isWin;
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
package com.javarush.khmelov.lesson14.controller;
package com.javarush.babkin;

import com.javarush.khmelov.lesson14.config.Winter;
import com.javarush.khmelov.lesson14.entity.Role;
import com.javarush.khmelov.lesson14.entity.User;
import com.javarush.khmelov.lesson14.service.UserService;
import com.javarush.babkin.entity.Role;
import com.javarush.babkin.entity.User;
import com.javarush.babkin.service.UserService;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отсутствует валидация данных, поступающих из 'HttpServletRequest'. Это может привести к уязвимостям или ошибкам при обработке некорректного ввода.

import java.io.IOException;
import java.util.Optional;

@WebServlet(value = "/edit-user", loadOnStartup = 1)
public class EditUserServlet extends HttpServlet {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Установка атрибута 'roles' в 'ServletContext' при каждом создании сервлета избыточна. Это лучше сделать один раз в 'ServletContextListener'.

private final UserService userService = Winter.find(UserService.class);
private final UserService userService = UserService.USER_SERVICE;

@Override
public void init(ServletConfig config) throws ServletException {
Expand All @@ -26,30 +26,42 @@ public void init(ServletConfig config) throws ServletException {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Метод 'Long.parseLong(id)' может выбросить 'NumberFormatException', если параметр отсутствует или не является числом. Необходимо добавить проверку или блок try-catch.

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если пользователь с указанным ID не найден, сервлет продолжит выполнение без уведомления об ошибке. Следует предусмотреть обработку отсутствующего значения (например, редирект на 404).

String stringId = req.getParameter("id");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Закомментированный код ('// if (user.isPresent()) ...') следует удалять перед публикацией в репозиторий для поддержания чистоты проекта.

if (stringId != null) {
long id = Long.parseLong(stringId);
Optional<User> user = userService.get(id);
String id = req.getParameter("id");
if (id != null) {
long userId = Long.parseLong(id);
Optional<User> user = userService.getById(userId);
user.ifPresent(value -> req.setAttribute("user", value));
// if (user.isPresent()) {
// req.setAttribute("user", user);
// }
}
req.getRequestDispatcher("/WEB-INF/edit-user.jsp").forward(req, resp);

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String parameter = req.getParameter("id");
User user = User.builder()
.id(parameter!=null?Long.parseLong(parameter):null)
.id(parameter != null ? Long.parseLong(parameter) : null)
.login(req.getParameter("login"))
.password(req.getParameter("password"))
.role(Role.valueOf(req.getParameter("role")))
.build();
if (req.getParameter("create") != null) {
userService.create(user);
} else if (req.getParameter("update") != null) {
user.setId(Long.parseLong(req.getParameter("id")));


// if (req.getParameter("create")!= null) {
// userService.create(user);
// } else
if (req.getParameter("update") != null) {
user.setId(Long.valueOf(req.getParameter("id")));
userService.update(user);
} else if (req.getParameter("delete") != null) {
user.setId(Long.valueOf(req.getParameter("id")));
userService.delete(user);
}

// resp.sendRedirect(req.getContextPath() + "/edit-user?id=" + req.getParameter("id"));
resp.sendRedirect(req.getContextPath() + "/edit-user?id=" + user.getId());
}
}
42 changes: 42 additions & 0 deletions src/main/java/com/javarush/babkin/PlayerStats.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.javarush.babkin;

public class PlayerStats {

private long playerId;
private int totalGames;
private int wins;
private int losses;

public PlayerStats(long playerId) {
this.playerId = playerId;
this.totalGames = 0;
this.wins = 0;
this.losses = 0;
}


public long getPlayerId() { return playerId; }
public int getTotalGames() { return totalGames; }
public int getWins() { return wins; }
public int getLosses() { return losses; }


public void setTotalGames(int totalGames) { this.totalGames = totalGames; }
public void setWins(int wins) { this.wins = wins; }
public void setLosses(int losses) { this.losses = losses; }

public double getWinRate() {
if (totalGames == 0) return 0.0;
return (double) wins / totalGames * 100;
}

public void incrementWin() {
totalGames++;
wins++;
}

public void incrementLoss() {
totalGames++;
losses++;
}
}
16 changes: 16 additions & 0 deletions src/main/java/com/javarush/babkin/QuestProgress.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.javarush.babkin;

public class QuestProgress {
private String step = "start";
private boolean finished = false;

public QuestProgress() {
this.step = "start";
this.finished = false;
}

public String getStep() { return step; }
public void setStep(String step) { this.step = step; }
public boolean isFinished() { return finished; }
public void setFinished(boolean finished) { this.finished = finished; }
}
43 changes: 43 additions & 0 deletions src/main/java/com/javarush/babkin/UserDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.javarush.babkin;

public class UserDto {
private long id;
private String login;
private int totalGames;
private int wins;
private int losses;
private double winRate;

public UserDto(long id, String login, int totalGames, int wins, int losses, double winRate) {
this.id = id;
this.login = login;
this.totalGames = totalGames;
this.wins = wins;
this.losses = losses;
this.winRate = winRate;
}

public long getId() {
return id;
}

public String getLogin() {
return login;
}

public int getTotalGames() {
return totalGames;
}

public int getWins() {
return wins;
}

public int getLosses() {
return losses;
}

public double getWinRate() {
return winRate;
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
package com.javarush.khmelov.lesson14.controller;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В проекте полностью отсутствует логирование (например, через SLF4J). Использование 'System.out.println' или отсутствие логов затрудняет отладку в продакшене.

package com.javarush.babkin;

import com.javarush.khmelov.lesson14.config.Winter;
import com.javarush.khmelov.lesson14.entity.User;
import com.javarush.khmelov.lesson14.service.UserService;
import com.javarush.babkin.entity.User;
import com.javarush.babkin.service.UserService;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;


Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Использование пустой строки '""' в URL-паттерне может привести к конфликтам при обработке корневых запросов. Лучше использовать конкретный путь.

import java.io.IOException;
import java.util.Collection;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Прямая зависимость от синглтона 'UserService.USER_SERVICE' затрудняет тестирование. Рекомендуется использовать внедрение зависимостей (Dependency Injection).

@WebServlet("/list-user")
public class ListUserServlet extends HttpServlet {
@WebServlet(value = {"","/user-list"})
public class UserListServlet extends HttpServlet {

private final UserService userService= Winter.find(UserService.class);
private final UserService userService = UserService.USER_SERVICE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Путь к JSP-файлу жестко закодирован в методе. Подобные константы следует выносить в отдельные статические переменные или конфигурацию.


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Collection<User> users = userService.getAll();

req.setAttribute("users", users);
req.getRequestDispatcher("/WEB-INF/list-user.jsp")
.forward(req, resp);
req.getRequestDispatcher("/WEB-INF/user-list.jsp").forward(req, resp);

}
}
34 changes: 34 additions & 0 deletions src/main/java/com/javarush/babkin/UserStatsAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.javarush.babkin;

import com.javarush.babkin.entity.User;
import com.javarush.babkin.service.StatsService;
import com.javarush.babkin.service.UserService;

public class UserStatsAdapter {

private final UserService userService;
private final StatsService statsService;

public UserStatsAdapter(UserService userService, StatsService statsService) {
this.userService = userService;
this.statsService = statsService;
}

public UserDto getUserWithStats(long userId) {
User user = userService.getUserById(userId);
if (user == null) {
return null;
}

PlayerStats stats = statsService.getStatsForUser(user);

return new UserDto(
user.getId(),
user.getLogin(),
stats.getTotalGames(),
stats.getWins(),
stats.getLosses(),
stats.getWinRate()
);
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/javarush/babkin/entity/Quest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.javarush.babkin.entity;


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Quest {
private Long id;
private String title;
private String description;


}
5 changes: 5 additions & 0 deletions src/main/java/com/javarush/babkin/entity/Role.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.javarush.babkin.entity;

public enum Role {
ADMIN, USER, GUEST
}
Loading