Lekce 2 - Java server - Parametry serveru
V minulé lekci, Java server - Úvod, jsme si připravili základní strukturu projektu.
V dnešním tutoriálu začneme tvořit serverovou část, konkrétně
zpracování parametrů. Veškeré třídy, které vytvoříme, se budou
vztahovat k modulu server
, není-li uvedeno jinak.
Parametry serveru
Server bude jednoduchá konzolová aplikace, takže veškeré nastavení budeme muset předat pomocí parametrů při spuštění programu. Časem přidáme i jednoduché interaktivní ovládání.
Parametry budou následující:
- číslo portu: definuje, na jakém portu bude náš server poslouchat
- počet klientů: maximální počet připojených klientů, kteří budou aktivně komunikovat se serverem
- velikost čekací fronty: pokud bude na serveru maximální počet klientů, tak se zařadí do čekací fronty
Jednotlivé parametry budou na příkazové řádce odděleny čárkou.
Každý parametr se bude skládat z dvojice -název=hodnota
.
Výsledný formát tedy bude následující:
-port=6298, -clients=2, -max_waiting_queue=5
Když jsme si zadefinovali, jak budou vypadat parametry serveru, můžeme je
implementovat do třídy, která se nám bude starat o parsování parametrů z
příkazové řádky. Vytvoříme nový balíček s názvem cmd
, ve
kterém vytvoříme rozhraní IParameterProvider
. Toto rozhraní
bude definovat metody, pomocí kterých budeme získávat parametry.
package cz.stechy.chat.cmd; public interface IParameterProvider { String DEFAULT_STRING = ""; int DEFAULT_INTEGER = -1; default String getString(String key) { return getString(key, DEFAULT_STRING); } String getString(String key, String def); default int getInteger(String key) { return getInteger(key, DEFAULT_INTEGER); } int getInteger(String key, int def); }
V rozhraní jsme nadefinovali celkem 4 metody. Dvě pro získání textu a dvě pro získání čísla. Využíváme zde možnosti defaultních metod v rozhraní, abychom nemuselu implementovat zbytečně všechny metody.
Nyní si ve stejném balíčku vytvoříme třídu, která bude toto
rozhraní implementovat, nazvěme ji CmdParser
. Nadefinujeme si
konstanty reprezentující názvy jednotlivých parametrů:
public static final String PORT = "port"; public static final String CLIENTS = "clients"; public static final String MAX_WAITING_QUEUE = "max_waiting_queue";
Dále si nadefinujeme Mapu, která bude uchovávat veškeré parametry:
private final Map<String, String> map = new HashMap<>();
Vytvoříme konstruktor třídy, který bude jako parametr přijímat vstupní argumenty z příkazové řádky:
public CmdParser(String[] args) { for (String arg : args) { arg = arg.replace("-", ""); String[] raw = arg.split("="); map.put(raw[0], raw[1]); } }
V konstruktoru zpracujeme jednotlivé parametry. Nejdříve se zbavíme znaku
-
před každým názvem parametru, následně rozdělíme
jednotlivé dvojice název=hodnota
do pole o dvou hodnotách. Tyto
hodnoty vložíme do mapy.
Nakonec zbývá implementovat metody, které po nás vyžaduje rozhraní
IParameterProvider
:
@Override public String getString(String key, String def) { final String s = map.get(key); return s == null ? def : s; } @Override public int getInteger(String key, int def) { final String s = map.get(key); return s == null ? def : Integer.parseInt(s); }
Implementace je velmi jednoduchá. Z mapy se získá hodnota, která by měla odpovídat klíči. Pokud tato hodnota neexistuje, vrátíme výchozí hodnotu, jinak vrátíme hodnotu, která byla získána z mapy.
Test
Abychom si ověřili, že naše třída funguje jak má, napíšeme si
jednoduchý jednotkový
test. K vytváření testů máme složku test/
. Ve složce
test/java/
si vytvoříme odpovídající balíček, tedy:
cz.stechy.chat.cmd
. Zde vytvoříme novou třídu
ParametersTest
. Nejdříve si nadefinujeme konstantu, která bude
reprezentovat parametry tak, jak budou přicházet z příkazové řádky:
private static final String[] PARAMETERS = { "-port=6298", "-clients=5", "-max_waiting_queue=5", "name=test" };
Dále si vytvoříme proměnnou, která bude typu
IParameterProvider
:
private IParameterProvider parameterProvider;
V setUp()
metodě inicializujeme tuto proměnnou:
@Before public void setUp() throws Exception { parameterProvider = new CmdParser(PARAMETERS); }
Nyní můžeme otestovat, zda-li jsme správně implementovali rozhraní. Vytvoříme si tedy čtyři testovací metody. Dvě pro získání textu a dvě pro získání čísla:
@Test public void getStringTest() { final String key = "name"; final String name = "test"; assertEquals("Chyba, hodnota názvu serveru se neshoduje.", name, parameterProvider.getString(key)); } @Test public void getStringNegativeTest() { final String key = "unknown"; final String value = CmdParser.DEFAULT_STRING; assertEquals("Chyba, je špatně definovaná výchozí hodnota.", value, parameterProvider.getString(key)); } @Test public void getIntegerTest() { final String key = "port"; final int value = 6298; assertEquals("Chyba, hodnota portu se neshoduje.", value, parameterProvider.getInteger(key)); } @Test public void getIntegerNegativeTest() { final String key = "unknown"; final int value = CmdParser.DEFAULT_INTEGER; assertEquals("Chyba, je špatně definovaná výchozí hodnota.", value, parameterProvider.getInteger(key)); }
V první metodě je pozitivní test na získání textu na základě klíče. Druhá metoda obsahuje negativní test, který testuje, zda-li dostanu výchozí hodnotu, pokud klíč není nalezen. Testy pro získání čísla jsou obdobné.
To by bylo pro dnešek vše.
V příští lekci, Java server - Google Guice, implementujeme správu závislostí pomocí knihovny Google guice.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 35x (239.95 kB)
Aplikace je včetně zdrojových kódů v jazyce Java