Занятие №11
Курсовой проект
Михаил
Павлов
Что мы уже узнали
- Как начать свой проект
- Основы ООП в Java
- Обобщения и коллекции
- Функциональное программирование в Java
- Работа с файловой системой
- Spring Core
- Spring Boot
- Rest API
- JPA и Hibernate
- Spring Data
- Тесты
Для применения этих знаний нужен проект
Вспомним, что мы делали раньше
(на 8 занятии)
Задача:
Сделать веб-приложение со списком вопросов
Требования:
- Отображать список вопросов
- Поиск вопросов по подстроке
- Фильтрация по количеству доступных ответов (*)
- Постраничная навигация (*)
(*) - Опционально
Сделано
Следующее задание
Задача:
Доработать веб-приложение
Требования:
- Создание и редактирование вопроса (со списком ответов)
- Фильтрация по количеству доступных ответов (*)
- Постраничная навигация (*)
(*) - Опционально
Давайте применим всё, что мы узнали
Что мы сделаем сегодня
- Хранение сущности журнала в БД (Entity)
- Получение её на клиенте (Repository, Service, RestService)
- Хранение сущностей вопросов и ответов в БД
- Получение списка строк журнала вопросов
- Создание нового вопроса с ответами
Схема данных
Как подключиться к базе данных (на примере H2)
Зависимости:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.h2database:h2'
}
Настройки:
spring.datasource.url=jdbc:h2:mem:restapp;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.h2.console.enabled=true
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
Имя своей БД
Практика
- Скачать и установить nodeJS
- Выкачать репозиторий по ссылке (папка unit-12)
- Перед первым запуском клиента выполнить команду
- npm i
- Запускаем клиент через консоль в папке app-client
- npm start
- Запускаем сервер через консоль в папке app-server (или через Идею)
- gradlew bootRun
Как работает клиент
Практика
Http-запросы:
Получение метаданных журнала
Получение строк журнала
Создание вопроса
Редактирование вопроса
Получение списка вопросов для новой сессии
Сохранение новой сессии
Клиент ожидает сервер по адресу http://localhost:8080
Практика
Клиент ожидает данные по двум журналам:
- Вопросы (id = questions)
- Сессии (id = sessions)
Получение метаданных журнала
Тип метода: GET
URL: http://localhost:8080/api/journal/<строка с id журнала>
Пример: http://localhost:8080/api/journal/questions
Ожидаемый ответ:
Пример ответа (JSON):
{
id: string;
name: string;
defaultPageSize?: number;
}
{
"id": "questions",
"name": "Вопросы",
"defaultPageSize": 15
}
Получение строк журнала (вопросы)
Тип метода: PUT
URL: http://localhost:8080/api/journal/<строка с id журнала>/rows
Пример: http://localhost:8080/api/journal/questions/rows
Тело запроса:
Пример тела запроса (JSON):
{ journalId: string;
search: string;
filters: JournalFilterItem[];
page: number;
pageSize: number; }
{ type: string;
code: string;
value: string; }
JournalFilterItem:
{ "journalId": "questions",
"search": "someText",
"filters": [{
"code": "question-answer-count",
"type": "single-select",
"value": 2
}],
"page": 1,
"pageSize": 15 }
Получение строк журнала (вопросы)
Ожидаемые ответ:
Пример тела ответа (JSON):
{
total: number;
items:
[{
id: string;
name: string;
answers: AnswerItemDTO[];
}]
}
{
"total" : 2,
"items":
[{
"id": 1,
"name": "Вопрос 1",
"answers": [{
"id": 3,
"answerText": "Ответ 3",
"isCorrect": true
}]
}, {
"id": 2,
"name": "Вопрос 2",
"answers": [{
"id": 4,
"answerText": "Ответ 4",
"isCorrect": false
}]
}]
}
{ id: string;
answerText: string;
isCorrect: boolean; }
AnswerItemDTO:
Получение строк журнала (сессии)
Тип метода: PUT
URL: http://localhost:8080/api/journal/<строка с id журнала>/rows
Пример: http://localhost:8080/api/journal/sessions/rows
Тело запроса:
Пример тела запроса (JSON):
{ journalId: string;
search: string;
filters: JournalFilterItem[];
page: number;
pageSize: number; }
{ type: string;
code: string;
value: string; }
JournalFilterItem:
{ "journalId": "sessions",
"search": "someText",
"filters": [],
"page": 1,
"pageSize": 15 }
Получение строк журнала (сессии)
Ожидаемые ответ:
Пример тела ответа (JSON):
{
total: number;
items:
[{
id: string;
name: string;
insertDate: Date;
result: number;
}]
}
{
"total" : 2,
"items":
[{
"id": 1,
"name": "Иванов И.И.",
"insertDate": 1568073600,
"result": 80
}, {
"id": 2,
"name": "Сидоров А.А.",
"insertDate": 1568073600,
"result": 100
}]
}
Создание вопроса
Тип метода: POST
URL: http://localhost:8080/api/question/create
Пример: http://localhost:8080/api/question/create
Тело запроса:
Пример тела запроса (JSON):
{
name: string;
answers: AnswerItemDTO[];
}
{ answerText: string;
isCorrect: boolean; }
AnswerItemDTO:
{
"name": "Текст вопроса",
"answers": [{
"answerText": "Текст ответа",
"isCorrect": true
}]
}
Создание вопроса
Тело ответа:
Пример тела запроса (JSON):
{
id: string;
name: string;
answers: AnswerItemDTO[];
}
{
id: string;
answerText: string;
isCorrect: boolean;
}
AnswerItemDTO:
{
"id": "1",
"name": "Текст вопроса",
"answers": [{
"id": "2",
"answerText": "Текст ответа",
"isCorrect": true
}]
}
Редактирование вопроса
Тип метода: PUT
URL: http://localhost:8080/api/question/edit
Пример: http://localhost:8080/api/question/edit
Тело запроса:
Пример тела запроса (JSON):
{
id: string;
name: string;
answers: AnswerItemDTO[];
}
{ answerText: string;
isCorrect: boolean; }
AnswerItemDTO:
{
"id": "1",
"name": "Текст вопроса",
"answers": [{
"answerText": "Текст ответа",
"isCorrect": true
}]
}
Редактирование вопроса
Тело ответа:
Пример тела запроса (JSON):
{
id: string;
name: string;
answers: AnswerItemDTO[];
}
{
id: string;
answerText: string;
isCorrect: boolean;
}
AnswerItemDTO:
{
"id": "1",
"name": "Текст вопроса",
"answers": [{
"id": "2",
"answerText": "Текст ответа",
"isCorrect": true
}]
}
* ответ такой же как при создании вопроса
Список вопросов для новой сессии
Тип метода: GET
URL: http://localhost:8080/api/session/questions-new
Пример: http://localhost:8080/api/session/questions-new
Ответ (список):
[{
id: string;
name: string;
answers: AnswerItemDTO[];
}]
{
id: string;
answerText: string;
isCorrect: boolean;
}
AnswerItemDTO:
Поле "isCorrect" есть в AnswerItemDTO, но лучше его не слать с сервера :)
Пример ответа (JSON):
[{
"id": "1",
"name": "Текст вопроса",
"answers": [{
"id": "3",
"answerText": "Текст ответа"
}]
}, {
"id": "2",
"name": "Текст вопроса2",
"answers": [{
"id": "4",
"answerText": "Текст ответа2"
}]
}]
Список вопросов для новой сессии
Создание новой сессии
Тип метода: POST
URL: http://localhost:8080/api/session
Пример: http://localhost:8080/api/session
Тело запроса:
{
name: string;
questionList: AnsweredQuestionDTO[];
}
{ id: string;
answerList: SessionQuestionAnswer[]; }
AnsweredQuestionDTO:
Создание новой сессии
{ id: string;
isSelected: boolean; }
SessionQuestionAnswer:
Пример тела запроса (JSON):
{
"name": "Иванов Иван Иванович",
"questionList": [{
"id": "1",
"answerList": [{
"id": "2",
"isSelected": true
}]
}, {
"id": "3",
"answerList": [{
"id": "4",
"isSelected": true
}, {
"id": "5",
"isSelected": false
}]
}]
}
Создание новой сессии
Создание новой сессии
В ответ получаем строку - количество набранных процентов
Как посмотреть, что летит с клиента и обратно
(в Google Chrome)
1. Зайти в инструменты разработчика в браузере
Варианты, как это можно сделать:
- Кнопка с троеточием -> Дополнительные инструменты -> Инструменты разработчика
- Ctrl + Shift + I
- F12
2. Перейти на вкладку Network
3. Найти упавший запрос
4. Подробности запроса (нажать на строку)
В данном случае ошибка - статус 404, на сервере не найден метод для такого запроса
Live-coding
Курсовой проект
- Редактирование вопроса с ответами
- Создать сущность сессии (+ репозиторий + сервис + рест)
- Получение списка для реестра сессий (+ поиск)
- Получение списка вопросов для новой сессии
- Сохранение новой сессии с валидацией ответов
- Сохранять список указанных ответов, для сессии
- Тесты (в т.ч. на подсчет % правильных ответов по сессии)
Основное задание:
Курсовой проект (дополнительное задание)
*
- Постраничная навигация в реестре (вопросы, сессии)
- Фильтрация по количеству ответов в реестре вопросов
***
- Использовать только клиент из репозитория, а сервер написать полностью самостоятельно
Вопросы
Спасибо за внимание!
JavaSIS #3.20 Занятие 11
By kgubaidulin
JavaSIS #3.20 Занятие 11
Курсовой проект
- 242