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단계 주드 미션 제출합니다 #326

Merged
merged 19 commits into from
Sep 6, 2023

Conversation

kevstevie
Copy link

@kevstevie kevstevie commented Sep 4, 2023

안녕하세요 다즐
미션 참 어렵네요
지저분한 코드 리뷰 잘 부탁드립니다.. 6시 전까지 보충 좀 해보겠습니다.

대략적인 플로우는 이렇습니다

request reader -> frontcontroller -> 각 controller -> response 생성

Copy link
Member

@woo-chang woo-chang left a comment

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 Path path = null;
final Path path = Path.of(getClass().getClassLoader().getResource(fileName).getPath());
System.out.println(path);
Copy link
Member

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.

부끄럽네요..

import nextstep.jwp.model.User;
import org.junit.jupiter.api.Test;

class InMemoryUserRepositoryTest {
Copy link
Member

Choose a reason for hiding this comment

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

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)

소소하지만 한글 테스트 메서드명 사용을 위한 어노테이션을 추가하는건 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

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

image

어노테이션보다 인텔리제이 설정을 선호하는데 어떤가요

Copy link
Member

Choose a reason for hiding this comment

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

좋은 방법이라고 생각합니다 😀

저는 협업하는 과정에서는 프로젝트를 클론했을 때 개인이 별도의 인텔리제이 설정을 하지 않아도 된다는 편의성을 생각했었습니다. 현재는 개인이 진행하는 작업이기에 인텔리제이 설정으로도 충분하다는 생각이 드네요 👍

협업을 하더라도 팀끼리 컨벤션을 맞추면 되는 부분이기에 적절한 방법을 선택하면 될 것 같아요!


public class InMemoryUserRepository {

private static final Map<String, User> database = new ConcurrentHashMap<>();
private static final AtomicLong sequence = new AtomicLong(1);
Copy link
Member

Choose a reason for hiding this comment

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

동시성까지 꼼꼼하게 챙겨주셨네요 👍


final var responseBody = "Hello world!";
RequestReader requestReader = new RequestReader(new BufferedReader(new InputStreamReader(inputStream)));
Copy link
Member

Choose a reason for hiding this comment

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

BufferedReader도 자원 회수를 위해 try catch resources안에 넣어주는게 어떨까요?


final var responseBody = "Hello world!";
RequestReader requestReader = new RequestReader(new BufferedReader(new InputStreamReader(inputStream)));
requestReader.read();
Copy link
Member

Choose a reason for hiding this comment

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

생성자에서 바로 초기화해주지 않고 read 메서드를 별도로 호출하는 이유가 궁금합니다!

Copy link
Author

Choose a reason for hiding this comment

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

음 그냥 별 이유는 없이 생성자에 복잡한 로직을 넣고 싶지 않았어요

}
this.body = sb.toString();
}
headers.put(Header.CONTENT_LENGTH.getName(), String.valueOf(file.length()));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
headers.put(Header.CONTENT_LENGTH.getName(), String.valueOf(file.length()));
headers.put(Header.CONTENT_LENGTH.getName(), String.valueOf(body.length()));

큰 차이는 발생하지 않을 것 같지만, createBodyByPlainText와 동일하게 bodylength를 추가하는 것으로 일관성을 유지해도 좋을 것 같아요 ㅎㅎ

Copy link
Author

Choose a reason for hiding this comment

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

body를 밖에서 받으면서 로직 수정됐습니다!

Comment on lines 43 to 53
url = Resolver.resolve(url);
String path = getClass().getClassLoader().getResource(STATIC + url).getPath();
File file = new File(path);
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line).append(System.lineSeparator());
}
this.body = sb.toString();
}
Copy link
Member

Choose a reason for hiding this comment

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

Response 내부에서 body를 생성하기보다는 외부에서 body를 만들어서 넣어주는건 어떨까요?

그렇게 된다면 text body를 설정하는 메서드와 file body를 설정하는 메서드가 1개로 통합될 수 있을 것 같아서 제안드립니다!

Copy link
Author

Choose a reason for hiding this comment

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

좋습니다 생각해보니 실제로 responseBody는 밖에서 받고 있군요


private static final String STATIC = "static";

private final RequestReader requestReader;
Copy link
Member

Choose a reason for hiding this comment

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

RequestReader는 요청 관련 데이터를 가지고 있는 것으로 이해했는데, 응답에서 요청에 대한 의존성을 직접적으로 가지기 보다는 필요한 값만 가지도록 하는 것은 어떨까요?!

Comment on lines 19 to 21
public String getSession() {
return params.get(JSESSION);
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
public String getSession() {
return params.get(JSESSION);
}
public String getCookie(String name) {
return params.get(name);
}

CookierJSESSIONID명을 직접적으로 가지기보다는, name을 통해 필요한 key를 전달받아서 사용하는 건 어떠신지 궁금합니다 🤓

Copy link
Author

Choose a reason for hiding this comment

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

좋습니다 쿠키, 리퀘스트에서 모두 jsession에 대한 정보를 지웠습니다

public Response createBodyByPlainText(String text) {
this.body = text;
headers.put(Header.CONTENT_LENGTH.getName(), String.valueOf(body.length()));
return this;
Copy link
Member

Choose a reason for hiding this comment

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

스스로를 반환하게 함으로 빌더 패턴을 가져갈 수 있네요 배워갑니다 👍

Copy link
Author

@kevstevie kevstevie left a comment

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 Path path = null;
final Path path = Path.of(getClass().getClassLoader().getResource(fileName).getPath());
System.out.println(path);
Copy link
Author

Choose a reason for hiding this comment

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

부끄럽네요..

Comment on lines 12 to 18
static {
controllers.put("/", frontController.mainPageController);
controllers.put("/login", frontController.loginController);
controllers.put("/register", frontController.loginController);
controllers.put("/index", frontController.indexController);
controllers.put("/index.html", frontController.indexController);
}
Copy link
Author

Choose a reason for hiding this comment

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

좋은 것 같습니다👍

Comment on lines 19 to 21
public String getSession() {
return params.get(JSESSION);
}
Copy link
Author

Choose a reason for hiding this comment

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

좋습니다 쿠키, 리퀘스트에서 모두 jsession에 대한 정보를 지웠습니다

Comment on lines 58 to 59
String[] split = line.split(" ");
String name = split[0].substring(0, split[0].length() - 1);
Copy link
Author

Choose a reason for hiding this comment

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

그렇네요 천재인가요?


final var responseBody = "Hello world!";
RequestReader requestReader = new RequestReader(new BufferedReader(new InputStreamReader(inputStream)));
requestReader.read();
Copy link
Author

Choose a reason for hiding this comment

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

음 그냥 별 이유는 없이 생성자에 복잡한 로직을 넣고 싶지 않았어요

Comment on lines 43 to 53
url = Resolver.resolve(url);
String path = getClass().getClassLoader().getResource(STATIC + url).getPath();
File file = new File(path);
try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line).append(System.lineSeparator());
}
this.body = sb.toString();
}
Copy link
Author

Choose a reason for hiding this comment

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

좋습니다 생각해보니 실제로 responseBody는 밖에서 받고 있군요

import nextstep.jwp.model.User;
import org.junit.jupiter.api.Test;

class InMemoryUserRepositoryTest {
Copy link
Author

Choose a reason for hiding this comment

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

image

어노테이션보다 인텔리제이 설정을 선호하는데 어떤가요

}
this.body = sb.toString();
}
headers.put(Header.CONTENT_LENGTH.getName(), String.valueOf(file.length()));
Copy link
Author

Choose a reason for hiding this comment

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

body를 밖에서 받으면서 로직 수정됐습니다!

@sonarcloud
Copy link

sonarcloud bot commented Sep 6, 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 8 Code Smells

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

Copy link
Member

@woo-chang woo-chang left a comment

Choose a reason for hiding this comment

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

리뷰 반영하신거 모두 확인했습니다! 수고하셨습니다~!
구조도 개선되고 각각의 클래스가 가져야할 역할을 잘 나누신 것 같아서 읽기 편했습니다 ㅎㅎ
테스트 코드는 다음 미션을 진행하면서 채워보셔도 좋을 것 같아요 😃
다음 미션도 기대하겠습니다 :)

@woo-chang woo-chang merged commit 196bb64 into woowacourse:kevstevie 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