-
Notifications
You must be signed in to change notification settings - Fork 309
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단계] 레오(차영호) 미션 제출합니다. #309
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 코드 잘 봤습니다.
handler로 매핑하는 부분 멋집니다.
몇가지 코멘트 남겼습니다. 확인해주세요
JS("text/javascript", "js"); | ||
|
||
private final String contentType; | ||
private final String matchingType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
matching type이라는 변수명보다 좋은 것은 없을까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확장자 성격이라 extension 으로 수정했습니다😀
private static final Map<String, ContentType> contentTypes = | ||
Collections.unmodifiableMap(Stream.of(values()) | ||
.collect(Collectors.toMap(ContentType::getMatchingType, Function.identity())) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
map으로 하는 것 좋아보여요
하지만 요건 상수인데 선언 위치를 이동하는 것은 어떤가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
동의합니다!
해당 map의 위치를 enum 변수인 httpContentType, extension 위에 놓을까 고민하다가 ENUM객체의 각 변수들에 대한 정보라 ENUM객체 -> 변수명 -> map 순으로 배치했습니다!
public static ContentType findMatchingType(String uri) { | ||
int fileTypeStartIndex = uri.indexOf('.'); | ||
String uriType = uri.substring(fileTypeStartIndex + 1); | ||
|
||
if (contentTypes.containsKey(uriType)) { | ||
return contentTypes.get(uriType); | ||
} | ||
return contentTypes.get(HTML.matchingType); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uri를 받아서 자르고 가공해서 반환하는 것보다 matching type을 받아서 반환하는 것은 어떤가요?
그리고 if()~~~ 를 contentype.getOrDefault로 해도 좋을 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ResponseEntity에서 한 번만 가공해서 보내주면 좋겠네요!
감사합니다 ㅎㅎ
Map<String, String> cookies = Arrays.stream(cookieValue.split(COOKIE_DELIMITER)) | ||
.map(cookieElement -> cookieElement.trim().split("=")) | ||
.collect(Collectors.toMap(cookie -> cookie[0], cookie -> cookie[1])); | ||
return new Cookie(cookies); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
왜 세미콜론만 상수화 하셨죠? 차별하시나요?
그리고 collecting then이라는 것을 사용하면 한번에 만들 수 있을 것 같아요, 물론 가독성측면에서 취향 차이일 것 같지만요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
상수화 했습니다 ㅎ..
다른 클래스도 산수화 못한거 하겠습니다!
private FileReader() { | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's good ~
private final ResponseStatus responseStatus; | ||
private final List<String> responseHeaders; | ||
private final String responseBody; | ||
private final Map<String, String> cookies = new HashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
왜 열심히 만들어놓으신 cookie 클래스를 사용안하시고..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그러게요,, 수정했습니다
List<String> headers = List.of( | ||
String.join(" ", "Content-Type:", ContentType.findMatchingType(endPoint).getContentType()), | ||
String.join(" ", "Content-Length:", String.valueOf(fileData.getBytes().length)) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
header를 보니 list보다 다른 자료구조가 좋을 것 같아보이네용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Map 으로 수정했습니다!
List 사용한 이유가 기존 테스트코드는 isEqualTo로 response 검증해서 Map을 사용하면 header 정보를 response로 만들 때 Map 내부 header 정보들의 순서가 섞여서 LinkedHashMap 쓰려다가 그냥 List 사용했습니다.
지금은 test코드를 isEqualTo 검증에서 contains 검증으로 수정했습니다~
String requestFirstLine = request.readLine(); | ||
String[] requestLine = validateRequestFirstLine(requestFirstLine); | ||
|
||
RequestMethod requestMethod = RequestMethod.find(requestLine[METHOD_INDEX]); | ||
String requestUri = requestLine[URI_INDEX]; | ||
HttpVersion httpVersion = HttpVersion.find(requestLine[HTTP_VERSION_INDEX]); | ||
|
||
int queryStringIndex = requestUri.indexOf(QUERY_STRING_DELIMITER); | ||
String endPoint = extractEndPoint(requestUri, queryStringIndex); | ||
Map<String, String> queryStrings = extractQueryStrings(requestUri, queryStringIndex); | ||
|
||
RequestHeader requestHeader = RequestHeader.from(request); | ||
int contentLength = requestHeader.getContentLength(); | ||
if (contentLength > 0) { | ||
char[] buffer = new char[contentLength]; | ||
request.read(buffer, 0, contentLength); | ||
String requestBody = new String(buffer); | ||
queryStrings = parseQueryStrings(requestBody); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
클래스를 나누어 해당 객체에 parsing하는 책임을 주면 보다 코드가 깔끔해질 것 같은데 3단계에 리팩토링이 있으니 그때 하셔도 좋을 것 같네요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
queryString, responseBody 정보를 파싱해서 들고 있는 RequestData 객체를 추가해서 데이터 파싱 책임을 분리해서 가독성을 높여봤습니다!
"Content-Length: " + responseBody.getBytes().length + " ", | ||
"", | ||
responseBody); | ||
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
br 조금 불편하네요 ㅋ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ㅎㅎ 수정했습니다
|
||
private static final Pattern FILE_PATTERN = Pattern.compile("css|js|ico|html"); | ||
|
||
private static final Map<String, Handler> myHandlers = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
핸들러를 멋지게 분리하셨는데 이 구현체 핸들러들의 패키지를 이동해봐도 좋을 것 같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어떻게 이동하는게 좋을까요..? 마땅히 떠오르지 않네요..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저라면 jwp 패키지 아래에 뒀을 것 같아용 apache 패키지가 inmemory user repository를 알고 있다는 것이 별로인 것 같아서요.
물론 저는 추상화를 3단계에 하려고 다 apache에 있는데 레오는 추상화를 멋지게 해놔서 말씀드려봅니다.
Kudos, SonarCloud Quality Gate passed! 0 Bugs 0.0% Coverage 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. |
꼼꼼한 리뷰 감사합니다 ^.^ HttpRequest를 만들 때 queryString이나 requestBody로 들어온 데이터를 파싱 후 가지고 있는 RequestData 를 추가해 책임 분리를 통해 가독성을 높여봤습니다. 그리고 Response의 Header 정보를 Map을 통해 관리하도록 수정했습니다!! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
안녕하세요 레오
코드 잘 봤습니다.
아주 깔끔하고 좋았습니다. 많이 배웠습니다
궁금한 것 위주로 코멘트 달았습니다.
수고하십시오 머지 하겠습니다
if (!SESSIONS.containsKey(id)) { | ||
throw new IllegalArgumentException("존재하지 않는 세션입니다."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good
String fileData = FileReader.readFile(request.getEndPoint()); | ||
return ResponseEntity.ok(fileData, request.getEndPoint()); | ||
return ResponseEntity.ok(fileData, ContentType.findMatchingType(fileExtension)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
goood
private final String responseBody; | ||
private final Map<String, String> cookies = new HashMap<>(); | ||
private final Cookie cookie = Cookie.from(""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cookie도 정적 팩토리 메서드에서 같이 생성해주는 것은 어떤가요>
|
||
private static final Pattern FILE_PATTERN = Pattern.compile("css|js|ico|html"); | ||
|
||
private static final Map<String, Handler> myHandlers = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저라면 jwp 패키지 아래에 뒀을 것 같아용 apache 패키지가 inmemory user repository를 알고 있다는 것이 별로인 것 같아서요.
물론 저는 추상화를 3단계에 하려고 다 apache에 있는데 레오는 추상화를 멋지게 해놔서 말씀드려봅니다.
안녕하세요 박스터!
톰캣 미션 제출합니다!!
전체적인 흐름은 사진과 같고, 정적파일을 읽어야 할 때는 FileReader를 통해 읽어오고 있습니다.
HttpRequest 객체는 request의 전반적인 정보를 담고 있습니다. 그래서 처음 입력받은 BufferedReader를 통해 정보를 파싱하는데 코드 수정이 좀 필요할 것 같아요 ㅎ.. (괜찮은 방법 있으면 조언 부탁드립니다..)
Handler는 request method, endpoint 등등을 보고 적절하게 파일을 읽거나, 리다이렉션을 시켜서 요청을 처리하는 역할을 하고 있습니다.
ResponseEntity는 reponse status, header, body 등을 조합해 응답 String을 만들고 있습니다.