-
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
[톰캣 구현하기 3, 4단계] 주디(오은비) 미션 제출합니다. #497
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.
주디 Conflict 해결 고생하셨어요~
리뷰 요청해주셔서 바로 확인해봤어요.
PR 받아서 애플리케이션 실행해봤는데 요구사항에 맞지 않는 오류가 있어요..! 🥲
확인 후 다시 리뷰 요청 부탁드리겠습니다.
01. 로그인 후 쿠키에 세션이 저장이 안돼요.
기존에 있는 gugu로 로그인 시도해봤습니다.
쿠키에 세션 정보가 없네요 ㅠㅠ
02. 회원가입 세션이 없어요.
hyena 회원가입을 진행해봤습니다.
여기도 안되네요.. 🙁
저장되나 직접 로깅해봤는데 일단 InMemory에 잘 들어가고 있네요!
03. locahost:8080/index를 찾을 수 없습니다!
04. 학습 테스트가 모두 사라졌어요! 😮
요청해주신대로 커멘트 후 머지하려고 했지만 미션 요구사항에 맞게 수정해주셔야 할 거 같아요 👍
요구사항에 맞을 때 다시 리뷰 하겠습니다!! 화이팅입니다 주디~~🚀
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. |
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.
안녕하세요 주디~
반영 고생하셨어요!
1, 2단계에서 많이 리팩터링 해주셨네요 👍
주디가 요청해주신대로 머지 먼저 하겠습니다 🚀
그래도 시간이 되신다면 제가 남긴 커맨트를 읽고 의견도 남겨주시면 재밌을거 같네요~
학습 테스트 관해서도 이야기 나눴으면 좋을텐데 ㅜㅜ
이것도 시간되신다면 학습 테스트 진행하시고 같이 더 많이 얻어갈 수 있으면 좋겠네요!
화이팅입니다 주디~
import java.io.IOException; | ||
|
||
public interface Controller { | ||
String process(HttpRequestParser httpRequestParser, HttpResponseBuilder httpResponseBuilder) throws IOException; |
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.
요구사항에 맞지 않아서 조금 아쉽네요 ㅜㅜ
LMS에 있는 방식으로도 구현해보시면 좋을거 같아요!
@Override | ||
public String process(HttpRequestParser httpRequestParser, HttpResponseBuilder httpResponseBuilder) throws IOException { | ||
return httpResponseBuilder.buildStaticFileOkResponse(httpRequestParser, | ||
httpRequestParser.findPathWithoutQueryString() + ".html"); | ||
} |
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.
쿼리 파라미터가 없다고해도 만약 index/1 이었다면 생각과 다른 결과가 나올거 같아요!
이후에 이러한 상황이 발생할 수도 있다는 것을 기억하고 있지 않다면 예외가 발생할 위험성이 있다고 생각합니다
String account = splitRequestBody[0].split(KEY_VALUE_SEPARATOR)[1]; | ||
String password = splitRequestBody[1].split(KEY_VALUE_SEPARATOR)[1]; |
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.
배열에 대한 생각을 두 번해야할거 같아요 ㅜㅜ
파싱에 대한 역할을 더 쪼개면 이후에 사용하기도 읽기도 편해질 수 있겠네요!
try { | ||
User user = InMemoryUserRepository.findByAccount(account).orElseThrow(UserNotFoundException::new); | ||
addSession(user, httpRequestParser); | ||
return redirect(password, user, httpRequestParser, httpResponseBuilder); | ||
} catch (UserNotFoundException e) { | ||
return httpResponseBuilder.buildStaticFileRedirectResponse(httpRequestParser, "/401.html"); | ||
} |
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.
로그인 실패를 try catch로 잡아주셨네요
저는 큰 오류가 있는 줄 알았어요 😂
로그인 실패 처리를 이런 방식으로 구현하신 이유가 궁금합니다
private void addCookie(HttpRequestParser httpRequestParser, Map<String, String> cookies, String uuid) { | ||
if (cookies.isEmpty()) { | ||
httpRequestParser.addHeader("Cookie", SESSION_ID + "=" + uuid); | ||
return; | ||
} | ||
//cookies에 잇는 cookie들로 Cookie header 만들어줘 | ||
String existedCookie = joinExistedCookie(cookies); | ||
httpRequestParser.addHeader("Cookie", existedCookie + "; " + SESSION_ID + "=" + uuid); | ||
} |
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.
HttpRequest 객체를 컨트롤러에서 제가 내부 값을 컨트롤할 수 있네요.
클라이언트가 보낸 정보를 조작할 수 있는게 위험할 수 있지 않을까요?
private final Map<String, Controller> getMappingControllers = new HashMap<>(); | ||
private final Map<String, Controller> postMappingControllers = new HashMap<>(); | ||
|
||
public FrontController() { | ||
getMappingControllers.put("/", new RootController()); | ||
getMappingControllers.put("/login", new GetLoginController()); | ||
getMappingControllers.put("/register", new GetRegisterController()); | ||
postMappingControllers.put("/login", new PostLoginController()); | ||
postMappingControllers.put("/register", new PostRegisterController()); | ||
} | ||
|
||
public String process(HttpRequestParser httpRequestParser, HttpResponseBuilder httpResponseBuilder) throws IOException { | ||
String method = httpRequestParser.findMethod(); | ||
String path = httpRequestParser.findPathWithoutQueryString(); | ||
Controller controller = findController(method, path); | ||
|
||
return controller.process(httpRequestParser, httpResponseBuilder); | ||
} | ||
|
||
public Controller findController(String method, String path) { | ||
if (isStaticPath(path)) { | ||
return new StaticController(); | ||
} | ||
if (method.equals("GET") && getMappingControllers.containsKey(path)) { | ||
return getMappingControllers.get(path); | ||
} | ||
if (method.equals("POST") && postMappingControllers.containsKey(path)) { | ||
return postMappingControllers.get(path); | ||
} | ||
return new NotFoundController(); | ||
} |
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.
Http 메서드에 따라 사용하는 map이 다르네요!
그래서 분기문도 나오게 된거야 같아요.
현재는 분기문이 적지만 이후에 어떻게 해결하실지 궁금하네요.
public Connector(final int port, final int acceptCount, final int maxThreads) { | ||
this.serverSocket = createServerSocket(port, acceptCount); | ||
this.threadPoolExecutor = new ThreadPoolExecutor( | ||
CORE_POOL_SIZE, | ||
maxThreads, | ||
KEEP_ALIVE_TIME, | ||
TimeUnit.SECONDS, | ||
new LinkedBlockingQueue<>(DEFAULT_ACCEPT_COUNT)); | ||
this.stopped = false; | ||
} |
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.
흠.. Executors를 이용해보라고 LMS에 있었던거 같은데 ㅜㅜ
ThreadPoolExecutor를 바로 이용하신 이유가 있나요?
public Map<String, String> findCookies() { | ||
Map<String, String> cookie = header.entrySet().stream() | ||
.filter(entry -> entry.getKey().equals("Cookie")) | ||
.map(entry -> entry.getValue().split("; ")) | ||
.flatMap(Arrays::stream) | ||
.map(line -> line.split(KEY_VALUE_DELIMITER)) | ||
.collect(Collectors.toMap(line -> line[0], line -> line[1])); | ||
return 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.
중간에 반환된 값을 변수로 받은 후 진행하면 더 읽기 편할거 같아요.
return protocol + SPACE + status + SPACE + LINE_FEED + | ||
findCookie(httpRequestParser) + | ||
contentType + SPACE + LINE_FEED + | ||
contentLength + SPACE + LINE_FEED + | ||
LINE_FEED + | ||
content; |
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.
문자열 연산이 많은데 다른 방식으로 구현해주셔도 좋을거 같아요
|
||
public enum HttpStatus { | ||
OK("200", "OK"), | ||
REDIRECT("302", "Moved Temporarily"), |
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.
302가 Moved Temporarily가 맞나요??
저는 다른거로 알고 있는데 혹시 보신 문서가 있으시다면 공유해주시면 감사하겠습니다!!
안녕하세요 헤나 ㅎㅎ 주디입니다!
3,4단계 구현하여 PR 보냅니다~ 이번에도 잘 부탁드려요!