Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[톰캣 구현하기 - 1, 2단계] 푸우(백승준) 미션 제출합니다. #311

Merged
merged 55 commits into from
Sep 6, 2023

Conversation

BGuga
Copy link

@BGuga BGuga commented Sep 3, 2023

1, 2 단계 마치고 미션 제출합니다!
설계한 구조는 아래와 같습니다.
image

크게 3가지 요청 타입이 존재합니다!!

  1. 정적파일 요청
  2. 컨트롤러를 통한 동적 요청
  3. 기본 응답 ( Hello World)

1, 2번의 경우 응답 Response 를 반환하는 역할을 ResourceProvider 와 HandlerMapper에 할당했습니다 ㅎㅎ
리뷰 잘 부탁드립니다!!

@gitchannn gitchannn self-requested a review September 5, 2023 03:52
Copy link

@gitchannn gitchannn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

푸우 안녕하세요!

진짜 깔끔하게 거의 Dispatcher Servlet을 만들어주셨네요
어쩌면 Pooh Servlet Engine >>> Tomcat일지도...

객체가 각자 분리되어서 각자 알아서 할 일을 하는게 합쳐져서 HTTP 서버가 되는게 아주 환상적인 코드에요...!
워낙에 역할이 잘 나누어져 있어서 크게 코멘트할 부분이 없지만, 한 번에 Approve 해버리는건 또 서운할 수 있으니 코멘트 선택적 반영하고 나서 다시 요청주세요!

private InMemoryUserRepository() {}
public static void save(User user) {
User saveUser = new User(++publishedId, user.getAccount(), user.getPassword(), user.getEmail());
database.put(saveUser.getAccount(), saveUser);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼하게 auto increment까지 👍

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

세세한 것 까지 봐주셨네요 ㅎㅎ 감사합니다!

final String fileName = "nextstep.txt";

// todo
final String actual = "";
File file = new File(getClass().getClassLoader().getResource("nextstep.txt").toURI());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
File file = new File(getClass().getClassLoader().getResource("nextstep.txt").toURI());
File file = new File(getClass().getClassLoader().getResource(fileName).toURI());

상수 부분 위에서 정의했던 변수 그대로 사용하는게 좀더 안정적일 것 같아요! (취향인 것 같슴니당)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

참고: . toURI() 대신에 .getFile()을 사용하면 URISyntaxException 예외를 처리하지 않아도 되는 것 같습니다.

Copy link
Author

@BGuga BGuga Sep 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수 부분 위에서 정의했던 변수 그대로 사용하는게 좀더 안정적일 것 같아요! (취향인 것 같슴니당)

저도 원래 그걸 선호하는데... 급하게 하다보니.. 크흠 ㅋㅋ

참고: . toURI() 대신에 .getFile()을 사용하면 URISyntaxException 예외를 처리하지 않아도 되는 것 같습니다.

오 대박이네요👍 ResourceProvider 에서도 toURI 를 사용해서 try catch 문이 있었는데 제거할 수 있었네요 ㅎㅎ 감사합니다!!


try (final var inputReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
final var outputStream = connection.getOutputStream()) {
HttpRequest httpRequest = HttpRequest.makeRequest(inputReader);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

객체 내에서 파싱하도록 아주 잘 설계한 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다 ㅎㅎ

return "Content-Type: text/css ";
}
if (fileName.endsWith(".html")) {
return "Content-Type: text/html;charset=utf-8 ";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

charset=utf-8은 컨텐트 타입이 css인 경우에도 사용해도 괜찮지 않을까요?
공통적인 부분이어서 꼭 html로 분기한 곳에만 넣어놓을 필요가 없을 것 같아요!

Copy link
Author

@BGuga BGuga Sep 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

text/css 도 해주는게 좋을 것 같네요!! css 파일 내에서 인코딩 순서를 다음과 결정한다하네요!! 링크
이런걸 전혀 인지하고 있지 못했네요 감사합니다 ㅎㅎ
javascript 의 경우에는 이런 header 가 의미있는지 확인하기가 어렵네요 ㅠㅠ 혹시 어떤 경우에 charset 을 지정해줘야 하나요??

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅋㅋ저도 이부분은 잘 모르겠어요..
막 알아보고 만들었다기보다는 요구사항에 있는 최소한만 만족하려고 만들었거등요 ㅎㅎㅎ
직접 할 일은 없을테니 이만큼 알아간거로도 훌륭하지 않을까?(?)

}
throw new IllegalArgumentException("파일이 존재하지 않습니다.");
} catch (IOException e) {
return null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

데이터베이스 읽기에 실패했을 때 Null을 반환하는 것이 안전할까요?
저는 에러를 터뜨리는게 더 좋을 것 같아요

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인정하는 부분입니다 ㅎㅎ 👍

request -> "/register".equals(request.getRequestLine().getPath()) &&
HttpMethod.GET.equals(request.getRequestLine().getMethod()),
new SignUpViewController());
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dispatcher Servlet을 만드신 것 같네요!!! ㄷㄷ

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

푸스패쳐 서블릿이라 불러주세요 ㅎㅎ

return stringJoiner.toString();
}

private String responseNoBody(HttpResponse<Object> httpResponse) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무 노바디노바디 벗츄 같으니깐 responseWithoutBody는 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅋㅋㅋㅋㅋㅋㅋㅋㅋ 좋습니다 ㅎㅎ with 적었으면 without 바로 나왔어야 했는데 얼탔네요 ㅋㅋㅋ 🫡

private static final String SESSION_COOKIE = "JSESSIONID";
private static final String COOKIE_SPLITER = ";";
private static final String COOKIE_VALUE_SPLITER = "=";
private final Map<String, String> cookieValues;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static final, final 사이에 한 줄 공백 있으면 좋을 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상당히 숨막히네요 반영했습니다 !!

GET("GET"),
POST("POST"),
PUT("PUT"),
DELETE("DELETE");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enum 자체의 name과 같은 필드로 별도로 만들 필요가 있을까요?!!
HttpMethod.GET.name()으로 사용해도 좋을 것 같은데, 별도로 동일한 이름으로 필드를 만든 이유가 궁금합니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그 이유는 몰랐기 때문이죠 감사합니다 ㅎㅎ

.isInstanceOf(IllegalArgumentException.class)
.hasMessage("파일이 존재하지 않습니다.");
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단위테스트 정말 꼼꼼히 작성하셨네요..!

로그인이나 회원가입에 대한 테스트도 작성하면 더 좋을 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TDD 로 가려다가 급 선회 했네요 ㅎㅎ 테스트는 3단계에서 일괄적으로 적용하겠습니다 !!

@sonarcloud
Copy link

sonarcloud bot commented Sep 5, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

0.0% 0.0% Coverage
0.0% 0.0% Duplication

warning The version of Java (11.0.20.1) you have used to run this analysis is deprecated and we will stop accepting it soon. Please update to at least Java 17.
Read more here

@gitchannn gitchannn merged commit e5a610c into woowacourse:bguga Sep 6, 2023
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants