-
Notifications
You must be signed in to change notification settings - Fork 27
Tarasenko #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Tarasenko #13
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package com.javarush.khmelov.cmd; | ||
|
|
||
| import com.javarush.khmelov.quest.Answer; | ||
| import com.javarush.khmelov.quest.Question; | ||
| import lombok.Getter; | ||
| import lombok.Setter; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.concurrent.atomic.AtomicInteger; | ||
|
|
||
| public class Quest { | ||
| static AtomicInteger atomicInteger = new AtomicInteger(0); | ||
| @Setter | ||
| @Getter | ||
| String win; | ||
| @Getter | ||
| int id = atomicInteger.getAndIncrement(); | ||
| @Getter | ||
| String name; | ||
|
|
||
| public Quest(String name){ | ||
| this.name = name; | ||
| } | ||
|
|
||
| Map<Integer, Question> questions = new HashMap<>(); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Поля 'questions' и 'loseMap' имеют доступ по умолчанию (package-private). Согласно принципу инкапсуляции, их следует сделать private. |
||
| Map<Integer, String> loseMap = new HashMap<>(); | ||
| public Question getQuestionById(int i){ | ||
| return questions.get(i); | ||
| } | ||
| public void crete(int i,String first, String second, String third, String lose){ | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Опечатка в названии метода 'crete'. Следует исправить на 'create' для соблюдения чистоты кода и читаемости. |
||
| questions.put(i, | ||
| new Question( | ||
| i, | ||
| first, | ||
| List.of(new Answer(second,1), | ||
| new Answer(third,2)) | ||
|
|
||
| )); | ||
| loseMap.put(i,lose); | ||
| } | ||
|
|
||
| public String lose(int id){ | ||
| return loseMap.get(id); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package com.javarush.khmelov.quest; | ||
|
|
||
|
|
||
| public class Answer { | ||
| String text; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Поля 'text' и 'id' не имеют модификаторов доступа. Их следует сделать private final. |
||
| int id; | ||
| public Answer(String text,int id) { | ||
| this.text = text; | ||
| this.id = id; | ||
| } | ||
|
|
||
| public String getText() { | ||
| return text; | ||
| } | ||
|
|
||
| public int getId() { | ||
| return id; | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| package com.javarush.khmelov.quest; | ||
|
|
||
|
|
||
| import java.util.List; | ||
|
|
||
| public class Question { | ||
| private final int id; | ||
| private final String text; | ||
| private final List<Answer> answers; | ||
|
|
||
| public Question(int id, String text, List<Answer> answers) { | ||
| this.id = id; | ||
| this.text = text; | ||
| this.answers = answers; | ||
| } | ||
|
|
||
|
|
||
| // Тоже добавь геттеры | ||
|
|
||
|
|
||
|
|
||
| public int getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public String getText() { | ||
| return text; | ||
| } | ||
|
|
||
| public List<Answer> getAnswers() { | ||
| return answers; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package com.javarush.khmelov.repository; | ||
|
|
||
|
|
||
| import com.javarush.khmelov.cmd.Quest; | ||
|
|
||
| import java.util.*; | ||
| import java.util.concurrent.atomic.AtomicLong; | ||
|
|
||
| public class QuestRepository { | ||
|
|
||
|
|
||
|
|
||
| private final Map<Integer, Quest> questMap = new HashMap<>(); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Использование HashMap в многопоточной среде (сервлеты) небезопасно. Рекомендуется заменить на ConcurrentHashMap для предотвращения Race Condition. |
||
|
|
||
|
|
||
|
|
||
| public Quest getById(int id){ | ||
| return questMap.get(id); | ||
| } | ||
|
|
||
| public void crate(Quest quest){ | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Опечатка в названии метода 'crate'. Следует переименовать в 'create'. |
||
| questMap.put(quest.getId(), quest); | ||
| } | ||
|
|
||
| public Collection<Quest> getAll() { | ||
| return questMap.values(); | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.javarush.khmelov.something; | ||
|
|
||
| import jakarta.servlet.ServletException; | ||
| import jakarta.servlet.annotation.WebServlet; | ||
| import jakarta.servlet.http.HttpServlet; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
| import jakarta.servlet.http.HttpServletResponse; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| @WebServlet("/questRepository") | ||
| public class AllQuests extends HttpServlet { | ||
| @Override | ||
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | ||
| req.setAttribute("questRepository", Create.questRepository); | ||
| req.getRequestDispatcher("/WEB-INF/allQuests.jsp").forward(req, resp); | ||
|
|
||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package com.javarush.khmelov.something; | ||
|
|
||
| import com.javarush.khmelov.cmd.Quest; | ||
| import com.javarush.khmelov.repository.QuestRepository; | ||
| import jakarta.servlet.ServletException; | ||
| import jakarta.servlet.annotation.WebServlet; | ||
| import jakarta.servlet.http.HttpServlet; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
| import jakarta.servlet.http.HttpServletResponse; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| @WebServlet("/create") | ||
| public class Create extends HttpServlet { | ||
|
|
||
| public static QuestRepository questRepository = new QuestRepository(); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Публичное статическое поле 'questRepository' — это нарушение инкапсуляции и плохая практика управления зависимостями. Репозиторий должен внедряться через конструктор или Winter.find. |
||
| Quest quest; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Поле 'quest' в сервлете приведет к состоянию гонки (Race Condition). Перенесите его в локальную область видимости метода doPost. |
||
| @Override | ||
| protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | ||
| quest = new Quest(NewQuest.name); | ||
|
|
||
| quest.setWin(req.getParameter("e")); | ||
| for (int i = 0; i < NewQuest.num; i++) { | ||
| String first = req.getParameter("a" + i); | ||
| String second = req.getParameter("b" + i); | ||
| String third = req.getParameter("c" + i); | ||
| String fourth = req.getParameter("d" + i); | ||
| quest.crete(i, first, second, third,fourth); | ||
| } | ||
| questRepository.crate(quest); | ||
| req.getRequestDispatcher("/WEB-INF/start-page.jsp").forward(req, resp); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| package com.javarush.khmelov.something; | ||
|
|
||
| import jakarta.servlet.ServletException; | ||
| import jakarta.servlet.annotation.WebServlet; | ||
| import jakarta.servlet.http.HttpServlet; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
| import jakarta.servlet.http.HttpServletResponse; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| @WebServlet("/quest") | ||
| public class NewQuest extends HttpServlet { | ||
| static int num; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Объявление переменных 'num' и 'name' как static в сервлете — критическая ошибка. Сервлет создается в единственном экземпляре, и эти данные будут перезаписываться при одновременном обращении разных пользователей. |
||
| static String name; | ||
| @Override | ||
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | ||
| req.getRequestDispatcher("/WEB-INF/quest.jsp").forward(req,resp); | ||
| } | ||
|
|
||
| @Override | ||
| protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | ||
| name = req.getParameter("name"); | ||
| num =Integer.parseInt( req.getParameter("num")); | ||
| req.setAttribute("num",num); | ||
|
|
||
| req.getRequestDispatcher("/WEB-INF/create.jsp").forward(req,resp); | ||
|
|
||
|
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| package com.javarush.khmelov.something; | ||
|
|
||
| import jakarta.servlet.ServletException; | ||
| import jakarta.servlet.annotation.WebServlet; | ||
| import jakarta.servlet.http.HttpServlet; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
| import jakarta.servlet.http.HttpServletResponse; | ||
|
|
||
| import java.io.IOException; | ||
|
|
||
| @WebServlet("/play") | ||
| public class Play extends HttpServlet { | ||
| int qid; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Поле 'qid' на уровне класса сервлета не является потокобезопасным. Значение, установленное одним пользователем, может быть прочитано другим. Данные состояния должны храниться в HttpSession. |
||
| @Override | ||
| protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | ||
| System.out.println("=== PLAY POST ==="); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Использование System.out.println для логирования недопустимо в продакшн-коде. Рекомендуется использовать логгер (например, SLF4J + Logback). |
||
| System.out.println("answerId = " + req.getParameter("answerId")); | ||
| System.out.println("questionId = " + req.getParameter("questionId")); | ||
| try{ | ||
| qid = Integer.parseInt(req.getParameter("questId")); | ||
| } | ||
| catch (Exception e){ | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Пустой блок catch (Exception e) 'проглатывает' ошибки. Это затрудняет отладку. Необходимо как минимум логировать исключение. |
||
|
|
||
| } | ||
|
|
||
| int ans = Integer.parseInt(req.getParameter("answerId")); | ||
| int que = Integer.parseInt(req.getParameter("questionId")); | ||
| if(ans %2 == 0){ | ||
| req.setAttribute("lose", Create.questRepository.getById(qid).lose(que)); | ||
| req.getRequestDispatcher("/WEB-INF/lose.jsp").forward(req, resp); | ||
| return; | ||
| } | ||
|
|
||
| if ( Create.questRepository.getById(qid).getQuestionById(que+1 ) == null){ | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Сложная цепочка вызовов (Create.questRepository.getById...). Это нарушает закон Деметры. Следует извлечь объект Quest в локальную переменную. |
||
| req.setAttribute("win", Create.questRepository.getById(qid).getWin()); | ||
| req.getRequestDispatcher("/WEB-INF/win.jsp").forward(req, resp); | ||
| return; | ||
| } | ||
| req.setAttribute("question", Create.questRepository.getById(qid).getQuestionById(que+1 )); | ||
|
|
||
| req.getRequestDispatcher("/WEB-INF/game.jsp").forward(req, resp); | ||
|
|
||
| } | ||
|
|
||
| @Override | ||
| protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { | ||
| req.setAttribute("question", Create.questRepository.getById(Integer.parseInt(req.getParameter("id"))).getQuestionById(0)); | ||
| req.setAttribute("questId",Integer.parseInt(req.getParameter("id")) ); | ||
| req.getRequestDispatcher("/WEB-INF/game.jsp").forward(req, resp); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| <%-- | ||
| Created by IntelliJ IDEA. | ||
| User: ADMIN | ||
| Date: 2/9/2026 | ||
| Time: 1:34 PM | ||
| To change this template use File | Settings | File Templates. | ||
| --%> | ||
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> | ||
| <%@include file="head.jsp" %> | ||
| <html> | ||
| <body> | ||
| <c:forEach var="quest" items="${questRepository.all}"> | ||
| <a href="play?id=${quest.id}">${quest.name}</a> | ||
| </c:forEach> | ||
|
|
||
| <a href="/"> | ||
| <button>На главную</button> | ||
| </a> | ||
|
|
||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| <%-- | ||
| Created by IntelliJ IDEA. | ||
| User: ADMIN | ||
| Date: 2/9/2026 | ||
| Time: 9:47 AM | ||
| To change this template use File | Settings | File Templates. | ||
| --%> | ||
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> | ||
| <%@include file="head.jsp"%> | ||
| <html> | ||
| <head> | ||
|
|
||
| </head> | ||
| <body> | ||
|
|
||
| <h1>Привет тут ты можешь написать свой квест</h1> | ||
| <h2>в каждом блоке тебе надо:</h2> | ||
| <h2>в первом столбце написать вопрос</h2> | ||
| <h2>во втором правильный ответ</h2> | ||
| <h2>в третьем неправильный ответ</h2> | ||
| <h2>в четвертом что будет за не правильный ответ</h2> | ||
| <h2>в последнюю если он победил </h2> | ||
| <form method="post" action="create"> | ||
| <input type="hidden" name="answerId" value="${answer.id}"> | ||
| <input type="hidden" name="questionId" value="${question.id}"> | ||
|
|
||
| <c:forEach var="i" begin="0" end="${num-1}"> | ||
| <div style="border:1px solid #ccc; padding:10px; margin-bottom:15px;"> | ||
| <input type="text" name="a${i}"> | ||
| <input type="text" name="b${i}"> | ||
| <input type="text" name="c${i}"> | ||
| <input type="text" name="d${i}"> | ||
| </div> | ||
| </c:forEach> | ||
| <input type="text" name="e"> | ||
| <button type="submit">OK</button> | ||
| </form> | ||
|
|
||
|
|
||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %> | ||
| <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> | ||
| <html> | ||
| <head> | ||
| <title>Space Quest</title> | ||
| </head> | ||
| <body> | ||
| <%-- Берем имя из сессии --%> | ||
|
|
||
| <h3>${question.text}</h3> | ||
|
|
||
|
|
||
| <%-- Если игра НЕ закончена, рисуем кнопки ответов --%> | ||
| <form method="post" action="play"> | ||
| <input type="hidden" name="questId" value="${questId}"> | ||
| <input type="hidden" name="questionId" value="${question.id}"> | ||
|
|
||
| <c:forEach items="${question.answers}" var="answer"> | ||
| <button type="submit" name="answerId" value="${answer.id}"> | ||
| ${answer.text} | ||
| </button> | ||
| </c:forEach> | ||
| </form> | ||
|
|
||
|
|
||
| <%-- Если это финал (победа или поражение) --%> | ||
|
|
||
| </body> | ||
| </html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Статическое поле 'atomicInteger' для генерации ID разделяется между всеми экземплярами класса в рамках JVM. Это может привести к непредсказуемому поведению в многопоточной среде сервлетов. Лучше перенести генерацию ID на уровень репозитория.