Skip to content
Open

Hw #168

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
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/runConfigurations.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 1 addition & 82 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1 @@
# Тестовое задание для Java стажеров

Привет!

Мы ищем стажера, который в перспективе станет Junior Java-разработчиком в нашей команде.
Чтобы понять, что мы подходим друг другу, предлагаем вам написать простое web-приложение. Такое задание поможет нам понять, что вы:

* можете понимать поставленную задачу;
* умеете находить необходимую техническую информацию для реализации решения;
* просто умеете кодить.

На задание у вас уйдет ориентировочно один-два вечера. Главное условие — решение должно быть написано с использованием платформы JVM. Библиотеки и фреймворки можно выбирать на свой вкус.

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

Реализовать приложение для автоматизации учёта носков на складе магазина. Кладовщик должен иметь возможность:

* учесть приход и отпуск носков;
* узнать общее количество носков определенного цвета и состава в данный момент времени.

Внешний интерфейс приложения представлен в виде HTTP API (REST, если хочется).

## Список URL HTTP-методов

### POST /api/socks/income

Регистрирует приход носков на склад.

Параметры запроса передаются в теле запроса в виде JSON-объекта со следующими атрибутами:

* color — цвет носков, строка (например, black, red, yellow);
* cottonPart — процентное содержание хлопка в составе носков, целое число от 0 до 100 (например, 30, 18, 42);
* quantity — количество пар носков, целое число больше 0.

Результаты:

* HTTP 200 — удалось добавить приход;
* HTTP 400 — параметры запроса отсутствуют или имеют некорректный формат;
* HTTP 500 — произошла ошибка, не зависящая от вызывающей стороны (например, база данных недоступна).

### POST /api/socks/outcome

Регистрирует отпуск носков со склада. Здесь параметры и результаты аналогичные, но общее количество носков указанного цвета и состава не увеличивается, а уменьшается.

### GET /api/socks

Возвращает общее количество носков на складе, соответствующих переданным в параметрах критериям запроса.

Параметры запроса передаются в URL:

* color — цвет носков, строка;
* operation — оператор сравнения значения количества хлопка в составе носков, одно значение из: moreThan, lessThan, equal;
* cottonPart — значение процента хлопка в составе носков из сравнения.

Результаты:

* HTTP 200 — запрос выполнен, результат в теле ответа в виде строкового представления целого числа;
* HTTP 400 — параметры запроса отсутствуют или имеют некорректный формат;
* HTTP 500 — произошла ошибка, не зависящая от вызывающей стороны (например, база данных недоступна).

Примеры запросов:

* /api/socks?color=red&operation=moreThan&cottonPart=90 — должен вернуть общее количество красных носков с долей хлопка более 90%;
* /api/socks?color=black&operation=lessThan?cottonPart=10 — должен вернуть общее количество черных носков с долей хлопка менее 10%.

Для хранения данных системы можно использовать любую реляционную базу данных. Схему БД желательно хранить в репозитории в любом удобном виде.

## Как это сделать

Мы ждем, что решение будет:

* написано на языке Java;
* standalone - состоять из одного выполняемого компонента верхнего уровня;
* headless - без UI;
* оформлено как форк к репозитарию и создан пул реквест.

Будет плюсом, если:

* приложение будет основано на Spring(Boot) Framework;
* для версионирования схемы базы данных будет использоваться Liquibase или Flyway;
* база данных будет подниматься рядом с приложением в докер-контейнере;
* приложение будет развернуто на любом облачном сервисе, например Heroku, и его API будет доступно для вызова.
Считает носки гет и пост запросами с помощью сервлетов и джетти
64 changes: 64 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>raif</groupId>
<artifactId>raif</artifactId>
<version>1.0</version>

<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>

<dependencies>

<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.3.0.M0</version>
</dependency>

<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.3.0.M0</version>
</dependency>

<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>

<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<outputDirectory>${basedir}</outputDirectory>
<finalName>serverSocks</finalName>
<appendAssemblyId>false</appendAssemblyId>
<archive>
<manifest>
<mainClass>main.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
Binary file added serverSocks.jar
Binary file not shown.
27 changes: 27 additions & 0 deletions src/main/java/main/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import servlets.*;
import socks.*;



public class Main {
public static void main(String[] args) throws Exception {
SocksService socksService=new SocksService();

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.addServlet(new ServletHolder(new ShowServlet(socksService)),"/show");
context.addServlet(new ServletHolder(new IncomeServlet(socksService)), "/api/socks/income");
context.addServlet(new ServletHolder(new OutcomeServlet(socksService)), "/api/socks/outcome");
context.addServlet(new ServletHolder(new SocksServlet(socksService)), "/api/socks");

Server server = new Server(8080);
server.setHandler(context);

server.start();
server.join();
}
}
101 changes: 101 additions & 0 deletions src/main/java/servlets/IncomeServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package servlets;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import socks.Socks;
import socks.SocksService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class IncomeServlet extends HttpServlet {
private final SocksService socksService;

public IncomeServlet(SocksService socksService){
this.socksService=socksService;
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//super.doPost(req, resp);
JSONParser parser=new JSONParser();
JSONObject jsonObject;
try {
jsonObject=(JSONObject)parser.parse(getBody(req));
}catch (Exception e){
throw new RuntimeException();
}
Socks socks=new Socks(jsonObject);

//пустые параметры
if(socks.getColor()==null||socks.getCottonPart()==null||
socks.getQuantity()==null){
resp.setContentType("text/html;charset=utf-8");
resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
//содержание хлопка
if(socks.getCottonPart()<0 || socks.getCottonPart()>100){
resp.setContentType("text/html;charset=utf-8");
resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
//Отрицательное число
if(socks.getQuantity()<=0){
resp.setContentType("text/html;charset=utf-8");
resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

if(socksService.addSocks(socks)){
resp.setContentType("text/html;charset=utf-8");
resp.setStatus(HttpServletResponse.SC_OK);
}else{
resp.setContentType("text/html;charset=utf-8");
resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}
//сам не знаю как объект json обработать в строку нашел на сайте
// https://question-it.com/questions/192029/poluchenie-dannyh-iz-vhodjaschego-json-v-servlete-java
public static String getBody(HttpServletRequest request) {

String body = null;
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;

try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
// throw ex;
return "";
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {

}
}
}

body = stringBuilder.toString();
return body;
}
}

Loading