-
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단계] 루카(백경환) 미션 제출합니다. #489
Merged
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
53bc8ba
feat: RequestUri 구현
dooboocookie 6af43a0
test: RequestLine 테스트 추가
dooboocookie 16b4559
test: Request 테스트 추가
dooboocookie d8321b2
test: RequestParameters 테스트 추가
dooboocookie b0f0ae3
test: Headers 테스트 추가
dooboocookie dfd1221
test: StatusLine 테스트 추가
dooboocookie 3e93477
test: Response 테스트 보완 및 리팩토링
dooboocookie b364094
feat: Response가 Cookie 추가하는 기능 갖도록 수정
dooboocookie b1db534
chore: 코드 스타일 정리 및 임포트문 정리
dooboocookie be4949d
refactor: 리퀘스트 파라미터 Optional로 반환하도록 변경
dooboocookie 5328934
refactor: Controller 구현
dooboocookie 11656cd
feat: ThreadPool 설정 추가
dooboocookie 5224c13
feat: ConcurrentHashMap 변경
dooboocookie 0a74fe5
chore: 코드 컨벤션 추가
dooboocookie 1f109f6
chore: 리다이렉트 리턴 안하던 과정 추가
dooboocookie 8153bdc
chore: 코드 스멜 제거
dooboocookie b05c414
fix: POST / 요청 405 응답으로 수정
dooboocookie 73616d0
refactor: Response에서 401, 404 응답 세팅하는 메서드 삭제
dooboocookie 549b696
refactor: 없는 정보는 404응답 주도록 수정
dooboocookie 941a808
fix: 이미 요청이 SessionId를 포함하고 있고 그 SessionId를 갱신하지 않았다면 SessionId를 갱신하지…
dooboocookie de558a1
test: SoftAssertions로 수정
dooboocookie b16b372
chore: 컨벤션 수정
dooboocookie File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,20 @@ | ||
package nextstep; | ||
|
||
import nextstep.jwp.controller.HomeController; | ||
import nextstep.jwp.controller.LoginController; | ||
import nextstep.jwp.controller.RegisterController; | ||
import org.apache.catalina.startup.Tomcat; | ||
import org.apache.coyote.controller.ControllerMapper; | ||
|
||
public class Application { | ||
|
||
public static void main(String[] args) { | ||
final var tomcat = new Tomcat(); | ||
|
||
ControllerMapper.register("/", new HomeController()); | ||
ControllerMapper.register("/login", new LoginController()); | ||
ControllerMapper.register("/register", new RegisterController()); | ||
|
||
tomcat.start(); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
tomcat/src/main/java/nextstep/jwp/controller/HomeController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import org.apache.coyote.controller.AbstractController; | ||
import org.apache.coyote.http11.request.Request; | ||
import org.apache.coyote.http11.response.Response; | ||
|
||
import static org.apache.coyote.http11.response.StatusCode.METHOD_NOT_ALLOWED; | ||
|
||
public class HomeController extends AbstractController { | ||
|
||
@Override | ||
protected void doPost(final Request request, final Response response) { | ||
response.setStatusCode(METHOD_NOT_ALLOWED); | ||
} | ||
|
||
@Override | ||
protected void doGet(final Request request, final Response response) { | ||
response.writeBody("Hello world!"); | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
tomcat/src/main/java/nextstep/jwp/controller/LoginController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import nextstep.jwp.db.InMemoryUserRepository; | ||
import nextstep.jwp.model.User; | ||
import org.apache.coyote.controller.AbstractController; | ||
import org.apache.coyote.http11.request.Request; | ||
import org.apache.coyote.http11.request.Session; | ||
import org.apache.coyote.http11.response.Response; | ||
import org.apache.coyote.http11.response.StatusCode; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.Optional; | ||
|
||
import static org.apache.coyote.http11.response.StatusCode.UNAUTHORIZED; | ||
|
||
public class LoginController extends AbstractController { | ||
|
||
private static final Logger log = LoggerFactory.getLogger(LoginController.class); | ||
|
||
@Override | ||
protected void doPost(final Request request, final Response response) { | ||
final Session session = request.getSession(); | ||
final Optional<String> account = request.getParameter("account"); | ||
|
||
if (account.isEmpty()) { | ||
response.redirect("/login.html"); | ||
return; | ||
} | ||
|
||
final Optional<User> maybeUser = InMemoryUserRepository.findByAccount(account.get()); | ||
if (maybeUser.isEmpty()) { | ||
response.setStatusCode(UNAUTHORIZED); | ||
response.writeStaticResource("/401.html"); | ||
return; | ||
} | ||
final User findUser = maybeUser.get(); | ||
final Optional<String> password = request.getParameter("password"); | ||
if (password.isEmpty() || !findUser.checkPassword(password.get())) { | ||
response.setStatusCode(UNAUTHORIZED); | ||
response.writeStaticResource("/401.html"); | ||
return; | ||
} | ||
log.info("user: {}", findUser); | ||
|
||
session.setAttribute("user", findUser); | ||
|
||
response.redirect("/index.html"); | ||
} | ||
|
||
@Override | ||
protected void doGet(final Request request, final Response response) { | ||
final Session session = request.getSession(); | ||
final User user = (User) session.getAttribute("user"); | ||
if (user != null) { | ||
response.redirect("/index.html"); | ||
return; | ||
} | ||
response.setStatusCode(StatusCode.CREATED); | ||
response.writeStaticResource("/login.html"); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
tomcat/src/main/java/nextstep/jwp/controller/RegisterController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import nextstep.jwp.db.InMemoryUserRepository; | ||
import nextstep.jwp.model.User; | ||
import org.apache.coyote.controller.AbstractController; | ||
import org.apache.coyote.http11.request.Request; | ||
import org.apache.coyote.http11.response.Response; | ||
|
||
public class RegisterController extends AbstractController { | ||
|
||
@Override | ||
protected void doPost(final Request request, final Response response) { | ||
final String account = request.getParameter("account") | ||
.orElseThrow(() -> new IllegalArgumentException("계정 입력이 잘못되었습니다.")); | ||
final String password = request.getParameter("password") | ||
.orElseThrow(() -> new IllegalArgumentException("비밀번호 입력이 잘못되었습니다.")); | ||
final String email = request.getParameter("email") | ||
.orElseThrow(() -> new IllegalArgumentException("이메일 입력이 잘못되었습니다.")); | ||
|
||
final User user = new User(account, password, email); | ||
InMemoryUserRepository.save(user); | ||
|
||
response.redirect("/login"); | ||
} | ||
|
||
@Override | ||
protected void doGet(final Request request, final Response response) { | ||
response.writeStaticResource("/register.html"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
tomcat/src/main/java/org/apache/coyote/controller/AbstractController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.apache.coyote.controller; | ||
|
||
import org.apache.coyote.http11.request.Request; | ||
import org.apache.coyote.http11.response.Response; | ||
|
||
import static org.apache.coyote.http11.request.RequestMethod.GET; | ||
import static org.apache.coyote.http11.request.RequestMethod.POST; | ||
import static org.apache.coyote.http11.response.StatusCode.METHOD_NOT_ALLOWED; | ||
|
||
public abstract class AbstractController implements Controller { | ||
|
||
@Override | ||
public void service(final Request request, | ||
final Response response) { | ||
if (request.getRequestLine().getRequestMethod() == GET) { | ||
doGet(request, response); | ||
return; | ||
} | ||
if (request.getRequestLine().getRequestMethod() == POST) { | ||
doPost(request, response); | ||
return; | ||
} | ||
response.setStatusCode(METHOD_NOT_ALLOWED); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 405 에러까지 처리하셨네요 👍👍 |
||
} | ||
|
||
protected abstract void doPost(final Request request, | ||
final Response response); | ||
|
||
protected abstract void doGet(final Request request, | ||
final Response response); | ||
} |
9 changes: 9 additions & 0 deletions
9
tomcat/src/main/java/org/apache/coyote/controller/Controller.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.apache.coyote.controller; | ||
|
||
import org.apache.coyote.http11.request.Request; | ||
import org.apache.coyote.http11.response.Response; | ||
|
||
public interface Controller { | ||
|
||
void service(final Request request, final Response response); | ||
} |
29 changes: 29 additions & 0 deletions
29
tomcat/src/main/java/org/apache/coyote/controller/ControllerMapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package org.apache.coyote.controller; | ||
|
||
import org.apache.coyote.http11.request.Request; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class ControllerMapper { | ||
|
||
private static final Controller STATIC_RESOURCE_CONTROLLER = new StaticResourceController(); | ||
|
||
private static final Map<String, Controller> CONTROLLER_MAP = new HashMap<>(); | ||
|
||
private ControllerMapper() { | ||
} | ||
|
||
public static void register(final String path, | ||
final Controller controller) { | ||
CONTROLLER_MAP.put(path, controller); | ||
} | ||
|
||
public static Controller getController(final Request request) { | ||
final String path = request.getRequestLine().getRequestPath(); | ||
if (CONTROLLER_MAP.containsKey(path)) { | ||
return CONTROLLER_MAP.get(path); | ||
} | ||
return STATIC_RESOURCE_CONTROLLER; | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
tomcat/src/main/java/org/apache/coyote/controller/StaticResourceController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package org.apache.coyote.controller; | ||
|
||
import org.apache.coyote.http11.request.Request; | ||
import org.apache.coyote.http11.response.Response; | ||
|
||
import java.io.*; | ||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.net.URL; | ||
import java.nio.file.Paths; | ||
|
||
import static org.apache.coyote.http11.response.StatusCode.*; | ||
|
||
public class StaticResourceController extends AbstractController { | ||
|
||
@Override | ||
protected void doPost(final Request request, final Response response) { | ||
response.setStatusCode(METHOD_NOT_ALLOWED); | ||
} | ||
|
||
@Override | ||
protected void doGet(final Request request, final Response response) { | ||
final ClassLoader classLoader = getClass().getClassLoader(); | ||
final String name = "static" + request.getRequestLine().getRequestPath(); | ||
final URL fileURL = classLoader.getResource(name); | ||
|
||
if (fileURL == null) { | ||
response.setStatusCode(NOT_FOUND); | ||
response.writeStaticResource("/404.html"); | ||
return; | ||
} | ||
|
||
final URI fileURI; | ||
try { | ||
fileURI = fileURL.toURI(); | ||
} catch (URISyntaxException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
|
||
final StringBuilder stringBuilder = new StringBuilder(); | ||
try (final InputStream inputStream = new FileInputStream(Paths.get(fileURI).toFile()); | ||
final InputStreamReader inputStreamReader = new InputStreamReader(inputStream); | ||
final BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { | ||
|
||
String nextLine; | ||
while ((nextLine = bufferedReader.readLine()) != null) { | ||
stringBuilder.append(nextLine) | ||
.append(System.lineSeparator()); | ||
} | ||
} catch (IOException e) { | ||
throw new IllegalStateException(e); | ||
} | ||
|
||
response.writeBody(stringBuilder.toString()); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
꼼꼼한 예외처리 👍
LoginController에서는 다르게 처리하신 이유가 있으실까요?
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.
LoginController는 해당 파라미터가 있냐 없냐에 따라서 이 인증 처리의 어떻게 분기 처리할지 갈리게 되므로 그 자체를 판단하기 위해서 Optional 값이 존재하는지 확인합니다.
하지만 위의 회원가입에서는 그 입력값이 들어오지 않았던 것이므로 예외처리를 하게됩니다.
만약 스프링으로 옮긴다면
LoginController에서 리퀘스트 바디를 바인딩하다 생긴 에러는 익셉션 핸들러에 의해서 401응답을 내려주는 과정을 거쳤을 것 같습니다