diff --git a/.gitignore b/.gitignore index a1c2a23..4c1a033 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +.idea/ diff --git a/RestServer.iml b/RestServer.iml index d5c0743..ef6da3f 100644 --- a/RestServer.iml +++ b/RestServer.iml @@ -7,6 +7,22 @@ + + + + + + + + + + + + + + + + + - - + \ No newline at end of file diff --git a/out/production/RestServer/at/reisinger/server/Main.class b/out/production/RestServer/at/reisinger/server/Main.class index aaf5b13..a25bfe9 100644 Binary files a/out/production/RestServer/at/reisinger/server/Main.class and b/out/production/RestServer/at/reisinger/server/Main.class differ diff --git a/src/at/reisinger/server/Main.java b/src/at/reisinger/server/Main.java index 77c75ab..8fbe999 100644 --- a/src/at/reisinger/server/Main.java +++ b/src/at/reisinger/server/Main.java @@ -1,35 +1,65 @@ package at.reisinger.server; import at.reisinger.server.msg.MsgHandler; -import at.reisinger.server.thread.ClientThread; +import at.reisinger.server.objects.Request; +import at.reisinger.server.objects.Response; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; -import java.util.concurrent.ConcurrentHashMap; +/** + * Grundlegende Server logic + * Vereint alle anderen Klassen + */ public class Main { static final int port = 80; + private Socket socket; + private int id; + private MsgHandler msgHandler; + /** + * Initial Start + * @param args Nicht Verwendet + */ public static void main(String[] args) { System.out.println("Starte Server auf Port 80"); + new Main(port); + } + + /** + * Öffnet den Server Socket und akzepiert diesen + * @param port Port auf dem der Server läuft + */ + public Main(int port){ ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(port); - int id = 0; + this.msgHandler = new MsgHandler(); + this.id = 0; while (true){ - Socket socket = serverSocket.accept(); - Thread client = new ClientThread(id, socket); - client.start(); - try { - client.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + this.socket = serverSocket.accept(); + requestResponding(); } } catch (IOException e) { e.printStackTrace(); } } + + /** + * Jeder Request durchläuft diese Funktion, reagiert auf requests + */ + public void requestResponding(){ + try{ + System.out.println("Socket von Client #" + this.id + " wurde gestartet!"); + Request rq = new Request(this.socket, this.id); + Response rp = new Response(this.id, rq.getUrl(), rq.getCmd(), rq.getOut(), this.msgHandler, rq.getPayload()); + this.msgHandler = rp.getMsghandler(); + this.socket.close(); + System.out.println("Socket von Client #" + this.id + " wurde geschlossen!"); + }catch (IOException e){ + e.printStackTrace(); + } + } } diff --git a/src/at/reisinger/server/msg/MsgHandler.java b/src/at/reisinger/server/msg/MsgHandler.java index 824afeb..b3d8ac9 100644 --- a/src/at/reisinger/server/msg/MsgHandler.java +++ b/src/at/reisinger/server/msg/MsgHandler.java @@ -4,6 +4,11 @@ import at.reisinger.server.objects.Msg; import java.util.HashMap; +/** + * Der Speicher der Nachrichten + * Mit hilfe einer HashMap werden die MsgId und die Msg selbst gespeichert + * @author Georg Reisinger + */ public class MsgHandler { private HashMap msgHashMap; private int lastID; @@ -25,7 +30,7 @@ public class MsgHandler { * Ermitelt die nächste freie Id * @return Next ID */ - public int nextId(){ + private int nextId(){ return this.lastID + 1; } @@ -44,8 +49,8 @@ public class MsgHandler { * Msg löschen * @param id Message Id */ - public void delMsg(int id){ - msgHashMap.remove(id); + public String delMsg(int id){ + return msgHashMap.remove(id); } /** @@ -53,8 +58,8 @@ public class MsgHandler { * @param id Message Id * @param msg Message Text */ - public void editMsg(int id, String msg){ - msgHashMap.replace(id, msg); + public String editMsg(int id, String msg){ + return msgHashMap.replace(id, msg); } /** diff --git a/src/at/reisinger/server/objects/Msg.java b/src/at/reisinger/server/objects/Msg.java index f3d87ae..87a2ea7 100644 --- a/src/at/reisinger/server/objects/Msg.java +++ b/src/at/reisinger/server/objects/Msg.java @@ -1,7 +1,8 @@ package at.reisinger.server.objects; /** - * Message Objekt + * Message Objekt beinmhaltet die MsgId und die Msg selbst + * @author Georg Reisinger */ public class Msg { private int id; @@ -25,15 +26,6 @@ public class Msg { return this.id; } - /** - * set field - * - * @param id Message Id - */ - public void setId(int id) { - this.id = id; - } - /** * get field * @@ -42,13 +34,4 @@ public class Msg { public String getMsg() { return this.msg; } - - /** - * set field - * - * @param msg Message String - */ - public void setMsg(String msg) { - this.msg = msg; - } } diff --git a/src/at/reisinger/server/objects/Request.java b/src/at/reisinger/server/objects/Request.java index 9bda98b..bc65127 100644 --- a/src/at/reisinger/server/objects/Request.java +++ b/src/at/reisinger/server/objects/Request.java @@ -8,6 +8,10 @@ import java.net.Socket; import java.util.ArrayList; import java.util.List; +/** + * Verarbeitet einen Request + * @author Georg Reisinger + */ public class Request { private final Socket socket; @@ -29,9 +33,11 @@ public class Request { this.id = id; this.out = new PrintStream(this.socket.getOutputStream()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); - String line; - while (!(line = bufferedReader.readLine()).isBlank()) { + String line = bufferedReader.readLine(); + while (!line.isBlank()) { rqBuilder.append(line + "\r\n"); + line = bufferedReader.readLine(); + System.out.println(line); } String request = rqBuilder.toString(); String[] requestsLines = request.split("\r\n"); @@ -66,74 +72,39 @@ public class Request { /** - * get field + * Get PrintStream --> Output * - * @return out + * @return out PrintStream --> Output */ public PrintStream getOut() { return this.out; } /** - * set field + * Command wie GET, PUT, POST, DEL * - * @param out - */ - public void setOut(PrintStream out) { - this.out = out; - } - - /** - * get field - * - * @return cmd + * @return cmd als String */ public String getCmd() { return this.cmd; } /** - * set field + * Request url * - * @param cmd - */ - public void setCmd(String cmd) { - this.cmd = cmd; - } - - /** - * get field - * - * @return url + * @return url als String */ public String getUrl() { return this.url; } /** - * set field + * Payload des Request * - * @param url - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * get field - * - * @return payload + * @return payload als String */ public String getPayload() { return this.payload; } - /** - * set field - * - * @param payload - */ - public void setPayload(String payload) { - this.payload = payload; - } } diff --git a/src/at/reisinger/server/objects/Response.java b/src/at/reisinger/server/objects/Response.java index 02d8539..fdcf320 100644 --- a/src/at/reisinger/server/objects/Response.java +++ b/src/at/reisinger/server/objects/Response.java @@ -5,6 +5,10 @@ import at.reisinger.server.msg.MsgHandler; import java.io.PrintStream; import java.net.Socket; +/** + * Erstellt und sendet eine Response anhand des Requests + * @author Georg Reisinger + */ public class Response { //private final Socket socket; @@ -12,8 +16,8 @@ public class Response { private PrintStream out; private String cmd; private String url; - private final StringBuilder rqBuilder; private MsgHandler msgHandler; + private StringBuilder rqBuilder; /** * Nimmt die Daten des requests und generiert eine Response @@ -40,33 +44,60 @@ public class Response { if(lastBit.equals("messages")){ listAllMsg(); }else{ - sendResponse(msgHandler.getMsg(Integer.parseInt(lastBit)).getMsg()); + String message = msgHandler.getMsg(Integer.parseInt(lastBit)).getMsg(); + if(message == null){ + sendError("404"); + }else { + sendResponse(message, "200"); + } } } else if (this.url.startsWith("/")) { startseite(); } }else if (this.cmd.equals("POST")){ if (this.url.startsWith("/messages")) { - sendResponse(msgHandler.addMsg(payload) + ""); + sendResponse(msgHandler.addMsg(payload) + "", "201"); } }else if (this.cmd.equals("PUT")){ if (this.url.startsWith("/messages")) { - msgHandler.editMsg(id, "Edit"); + String lastBit = this.url.substring(this.url.lastIndexOf('/') + 1); + System.out.println("Last Bit: " + lastBit); + System.out.println("Payload" + payload); + String message = msgHandler.editMsg(Integer.parseInt(lastBit), payload); + if(message == null){ + sendError("404"); + }else { + sendResponse("","200"); + } } }else if (this.cmd.equals("DELETE")){ if (this.url.startsWith("/messages")) { - msgHandler.delMsg(id); + String lastBit = this.url.substring(this.url.lastIndexOf('/') + 1); + String message = msgHandler.delMsg(Integer.parseInt(lastBit)); + if(message == null){ + sendError("404"); + }else { + sendResponse("", "200"); + } } }else{ - sendResponse(sendError()); + sendError("405"); } } } - - private String sendError() { - return ""; + /** + * Sendet einen Error Response + * @param errorCode Der Error Code + */ + private void sendError(String errorCode) { + out.print("HTTP/1.0 "+errorCode+"\r\n"); + out.print("Server: Apache/0.8.4\r\n"); + out.print("Content-Type: text/plain\r\n"); + out.print("Content-Length: 1\r\n"); + out.print("\r\n"); + //out.print(responseText); } private void startseite() { @@ -75,95 +106,35 @@ public class Response { "show first message: GET /messages/1
" + "show third message: GET /messages/3
" + "update first message: PUT /messages/1 (Payload: the message)
" + - "remove first message: DELETE /messages/1
"); + "remove first message: DELETE /messages/1
", "200"); } private void listAllMsg() { - sendResponse(msgHandler.getAllMsg()); + sendResponse(msgHandler.getAllMsg(), "200"); //sendResponse("Test"); } - private void sendResponse(String responseText){ - out.print("HTTP/1.0 200 OK\r\n"); - out.print("Date: Fri, 31 Dec 2020 23:59:59 GMT\r\n"); + /** + * Sendet eine Response + * @param responseText Text der zu senden ist + * @param code Http code + */ + private void sendResponse(String responseText, String code){ + out.print("HTTP/1.0 "+code+"\r\n"); out.print("Server: Apache/0.8.4\r\n"); out.print("Content-Type: text/plain\r\n"); - out.print("Content-Length: 59\r\n"); - out.print("Expires: Sat, 01 Jan 2025 00:59:59 GMT\r\n"); - out.print("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n"); + out.print("Content-Length: "+responseText.length()+"\r\n"); out.print("\r\n"); out.print(responseText); } /** - * get field + * Get Msg Handler * - * @return out - */ - public PrintStream getOut() { - return this.out; - } - - /** - * set field - * - * @param out - */ - public void setOut(PrintStream out) { - this.out = out; - } - - /** - * get field - * - * @return cmd - */ - public String getCmd() { - return this.cmd; - } - - /** - * set field - * - * @param cmd - */ - public void setCmd(String cmd) { - this.cmd = cmd; - } - - /** - * get field - * - * @return url - */ - public String getUrl() { - return this.url; - } - - /** - * set field - * - * @param url - */ - public void setUrl(String url) { - this.url = url; - } - - /** - * get field - * - * @return msgHandler + * @return msgHandler Handler der Nachrichten */ public MsgHandler getMsghandler() { return this.msgHandler; } - /** - * set field - * - * @param msgHandler - */ - public void setMsghandler(MsgHandler msgHandler) { - this.msgHandler = msgHandler; - } } diff --git a/src/at/reisinger/server/thread/ClientThread.java b/src/at/reisinger/server/thread/ClientThread.java deleted file mode 100644 index 2bd33a2..0000000 --- a/src/at/reisinger/server/thread/ClientThread.java +++ /dev/null @@ -1,46 +0,0 @@ -package at.reisinger.server.thread; - -import at.reisinger.server.msg.MsgHandler; -import at.reisinger.server.objects.Request; -import at.reisinger.server.objects.Response; - -import java.io.*; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; - -public class ClientThread extends Thread{ - private final Socket socket; - private final int id; - private MsgHandler msgHandler; - - /** - * Neuer Client wird erstellt - * @param id Id des Clients - * @param socket Socket des Clients - */ - public ClientThread(int id, Socket socket) { - this.id = id; - this.socket = socket; - } - - /** - * Hauptmethode des ClientThreads - */ - @Override - public void run() { - try{ - System.out.println("Socket von Client #" + this.id + " wurde gestartet!"); - Request rq = new Request(this.socket, this.id); - Response rp = new Response(this.id, rq.getUrl(), rq.getCmd(), rq.getOut(), this.msgHandler, rq.getPayload()); - this.msgHandler = rp.getMsghandler(); - this.socket.close(); - System.out.println("Socket von Client #" + this.id + " wurde geschlossen!"); - }catch (IOException e){ - e.printStackTrace(); - } - - } - - -} diff --git a/src/test/MyTests.java b/src/test/MyTests.java new file mode 100644 index 0000000..8fa1015 --- /dev/null +++ b/src/test/MyTests.java @@ -0,0 +1,57 @@ +package test; + +import at.reisinger.server.msg.MsgHandler; +import at.reisinger.server.objects.Msg; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertTrue; + +public class MyTests{ + @Test + @DisplayName("Msg - GetMsg") + public void msgTest(){ + Msg msg = new Msg(1, "Nachricht"); + assertTrue(msg.getMsg().equals("Nachricht")); + } + + @Test + @DisplayName("Msg - getId") + public void msgIdTest(){ + Msg msg = new Msg(1, "Nachricht"); + assertTrue(msg.getId() == 1); + } + + @Test + @DisplayName("MsgHandler - GetMsg") + public void msgHandlerGetTest(){ + MsgHandler msgHandler = new MsgHandler(); + assertTrue(msgHandler.getMsg(5).getMsg().equals("Dir?")); + } + + @Test + @DisplayName("MsgHandler - AddMsg") + public void msgHandlerAddTest(){ + MsgHandler msgHandler = new MsgHandler(); + msgHandler.addMsg("Nachricht"); //id = 6 + assertTrue(msgHandler.getMsg(6).getMsg().equals("Nachricht")); + } + + @Test + @DisplayName("MsgHandler - editMsg") + public void msgHandlerEditTest(){ + MsgHandler msgHandler = new MsgHandler(); + msgHandler.addMsg("Nachricht"); //id = 6 + msgHandler.editMsg(6, "Neu"); + assertTrue(msgHandler.getMsg(6).getMsg().equals("Neu")); + } + + @Test + @DisplayName("MsgHandler - DelMsg") + public void msgHandlerDelTest(){ + MsgHandler msgHandler = new MsgHandler(); + msgHandler.addMsg("Nachricht"); //id = 6 + msgHandler.delMsg(6); + assertTrue(msgHandler.getMsg(6).getMsg() == null); + } +} \ No newline at end of file