좋았던 점.
- HTTP와 OSI 7계층에 대해 깊게 파볼 수 있는 기회를 가졌다.
- 편하게 Spring에서 제공하는 TCP Server를 사용하였으나, 직접 Socket Server를 구현해볼 수 있는 기회를 가졌다.
-
공부하였던 것.
https://app.gitbook.com/o/taSHeKNauuWjMHNBR1b2/s/81EQp5agFGCXrLLcZPJX/week-1/1-http
GitBook
app.gitbook.com
package kr.megaptera.assignment;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class App {
public enum HttpMethods {
GET, POST, PUT, PATCH, DELETE
}
public static class HttpRequestCode {
private int code;
private String message;
public void notFoundRequest() {
code = 404;
message = "Not Found";
}
public void badRequest() {
code = 400;
message = "Bad Request";
}
public void successRequest() {
code = 200;
message = "OK";
}
public void createSuccessRequest() {
code = 201;
message = "Created";
}
}
public static void main(String[] args) throws IOException {
App app = new App();
app.run();
}
private String responseBody = "";
Map<Long, String> tasks = new HashMap<>();
private void run() throws IOException {
int port = 8080;
// TODO: 요구사항에 맞게 과제를 진행해주세요.
// 1. Listen
ServerSocket listener = new ServerSocket(port);
// 2. Accept
while (true) {
Socket socket = listener.accept();
System.out.println("Accept");
// 3. Request
String request = getRequest(socket);
System.out.println(request);
String header = request.split("\\n")[0];
HttpRequestCode requestCode = processRequest(header, request);
// 4. Response
sendResponseMessage(socket, requestCode);
responseBody = "";
socket.close();
}
}
private void sendResponseMessage(Socket socket, HttpRequestCode requestCode) throws IOException {
byte[] bytes = responseBody.getBytes();
String message =
"HTTP/1.1 " + requestCode.code + " " + requestCode.message + "\n" + "Content-Length: "
+ bytes.length + "\n" + "\n" + responseBody;
Writer writer = new OutputStreamWriter(socket.getOutputStream());
writer.write(message);
writer.flush();
}
private String getRequest(Socket socket) throws IOException {
Reader reader = new InputStreamReader(socket.getInputStream());
CharBuffer charBuffer = CharBuffer.allocate(1_000_000);
reader.read(charBuffer);
charBuffer.flip();
return charBuffer.toString();
}
private HttpRequestCode processRequest(String header, String request) {
String[] methods = header.split(" ");
HttpMethods httpMethod = HttpMethods.GET;
try {
httpMethod = HttpMethods.valueOf(methods[0]);
} catch (Exception e) {
HttpRequestCode httpRequestCode = new HttpRequestCode();
httpRequestCode.notFoundRequest();
return httpRequestCode;
}
String routing = methods[1];
return switch (httpMethod) {
case GET -> containGetRequest(routing);
case POST -> containPostRequest(routing, request);
case PATCH -> {
Long id = validCheckMethods(routing);
yield containPatchRequest(routing, request, id);
}
case DELETE -> {
Long id = validCheckMethods(routing);
yield containDeleteRequest(routing, request, id);
}
default -> {
HttpRequestCode httpRequestCode = new HttpRequestCode();
httpRequestCode.notFoundRequest();
yield httpRequestCode;
}
};
}
private Long validCheckMethods(String methods) {
try {
return Long.parseLong(methods.split("/")[2]);
} catch (Exception e) {
return null;
}
}
private HttpRequestCode containDeleteRequest(String routing, String request, Long id) {
HttpRequestCode requestCode = new HttpRequestCode();
requestCode.notFoundRequest();
if (routing.contains("/tasks")) {
if (!tasks.containsKey(id)) {
return requestCode;
}
tasks.remove(id);
responseBody = new Gson().toJson(tasks);
requestCode.successRequest();
}
return requestCode;
}
private HttpRequestCode containPatchRequest(String routing, String request, Long id) {
HttpRequestCode requestCode = new HttpRequestCode();
requestCode.notFoundRequest();
if (routing.contains("/tasks")) {
if (!tasks.containsKey(id)) {
return requestCode;
}
String jsonData = getJsonData(request, "task");
updateTask(jsonData, requestCode, id);
}
return requestCode;
}
private void updateTask(String jsonData, HttpRequestCode code, Long id) {
if (jsonData == null) {
code.badRequest();
return;
}
tasks.put(id, jsonData);
responseBody = new Gson().toJson(tasks);
code.successRequest();
}
private HttpRequestCode containPostRequest(String routing, String request) {
HttpRequestCode requestCode = new HttpRequestCode();
requestCode.notFoundRequest();
if (routing.equals("/tasks")) {
String jsonData = getJsonData(request, "task");
createTask(jsonData, requestCode);
}
return requestCode;
}
private void createTask(String jsonData, HttpRequestCode code) {
if (jsonData == null) {
code.badRequest();
return;
}
tasks.put(createTaskId(), jsonData);
responseBody = new Gson().toJson(tasks);
code.createSuccessRequest();
}
private Long createTaskId() {
return (long) (tasks.size() + 1);
}
private HttpRequestCode containGetRequest(String routing) {
HttpRequestCode requestCode = new HttpRequestCode();
requestCode.notFoundRequest();
if (routing.equals("/tasks")) {
responseBody = new Gson().toJson(tasks);
requestCode.successRequest();
}
return requestCode;
}
private String getJsonData(String request, String value) {
String[] lines = request.split("\\n");
String lastLine = lines[lines.length - 1];
try {
JsonElement jsonElement = JsonParser.parseString(lastLine);
JsonObject jsonObject = jsonElement.getAsJsonObject();
return jsonObject.get(value).getAsString();
} catch (Exception e) {
return null;
}
}
}
진행을 하다가 httpie에선 정상적으로 작동하는 요청이 테스트코드에선 진행되질 않았고, 테스트 코드를 수정 했을 때 PR이 정상적으로 진행이되어 물어보았다.
이후 빠르게 피드백되어 테스트코드에 문제가 있어 수정되었다.
느낌점 / 자기 피드백
이번 주에는 어떻게 진행되는지를 파악해야했고, 그 과정에서 매주 목요일마다 데브노트가 완료되어야 한다는 사실을
나중에 알았다. 스케줄을 일요일 까지 완성 시키는 걸로 목표로 하였는데.
바로 피드백이 들어와버렸다.. ㅜ ( 열심히 매일 공부하고 있습니다.. 믿어주시죠) 차주 부턴 스케줄을 다시 잡아야 하며,
너무 OSI 계층 구조에 대해 깊게 설명하고자 노트를 쓰다보니 다른 내용을 한 주 안에 깊게 다루기가 힘이 들었기 때문에, 피드백 내용대로 데브노트를 키워드 별로 쭉 정리하고 차후 깊게 다루고 싶은 부분만 따로 때서 정리해볼 예정이다.
음 그리고, Git Hub는 많이 사용해봤지만 직접 Fork를 따고 PR을 진행해보는 건 처음이었기 때문에 진행하는 것에 어려움은 없었으나 실무에선 이런식으로도 작업할 수 있겠구나! 하는 배움도 얻었다.
마지막으로, 과제 해답 코드가 나오면 현재 내가 작성한 코드와 비교해보면서 어떤 점을 개선할 수 있었는지를 정리해볼 예정이다.
'BackEnd > 메가테라 Study' 카테고리의 다른 글
[메가테라 BE 생존코스] 4주차 회고 (0) | 2024.04.14 |
---|---|
[메가테라 BE 생존코스] 3주차 회고 (0) | 2024.04.07 |
[메가테라 BE 생존코스] 2주차 회고 (0) | 2024.03.31 |