-
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단계] 이레(이다형) 미션 제출합니다 #484
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
3e28b09
fix: redirect 오류 수정
zillionme 50c309d
test: cache 기능 구현
zillionme 63b5b23
docs: 3차 리팩터링 목록 작성
zillionme 0852a2c
refactor: HttpRequest에 세션 추가
zillionme 89f559d
refactor: HttpRequest와 HttpResponse에 세션 추가
zillionme 179710d
refactor: 서블릿 구현체와, 핸들러, RequestMapping 구현
zillionme 3ec77b2
refactor: 패키지 변경 및 세션 생명주기 수정
zillionme a45c151
refactor: 서블릿-핸들러-컨트롤러 패턴 톰캣 적용
zillionme 0c38b3c
refactor: 홈, 로그인, 회원가입 컨트롤러 및 정적 파일 핸들러 수정
zillionme 864c009
refactor: 응답 헤더 완성 기능 수정
zillionme 83fe281
test: 세션 적용으로 인한 테스트 수정
zillionme 4952ce3
feat: 4단계 스레드 적용
zillionme 10e02ca
refactor: 리다이렉트 응답 수정
zillionme 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 +1,14 @@ | ||
# 톰캣 구현하기 | ||
|
||
## 3단계 리팩터링 | ||
1차 구조 | ||
- coyote -> catalina -> jwp 의존 관계 | ||
|
||
### 기능구현 목록 | ||
- [x] HttpRequest에 세션 추가 | ||
- [x] HttpResponse 변경 및 수정 | ||
- [x] Servlet, DispatcherServlet 구현 | ||
- [x] HttpRequest와 세션 생명 주기 수정 | ||
- [x] RequestMapping 클래스 생성 | ||
- [x] 패키지 분리 및 핸들러 인터페이스와 컨트롤러 추상클래스 생성 | ||
- [x] 패키지 분리 및 컨트롤러 클래스 수정 |
10 changes: 10 additions & 0 deletions
10
study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.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 |
---|---|---|
@@ -1,13 +1,23 @@ | ||
package cache.com.example.cachecontrol; | ||
|
||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.http.CacheControl; | ||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; | ||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
import org.springframework.web.servlet.mvc.WebContentInterceptor; | ||
|
||
@Configuration | ||
public class CacheWebConfig implements WebMvcConfigurer { | ||
|
||
@Override | ||
public void addInterceptors(final InterceptorRegistry registry) { | ||
CacheControl cacheControl = CacheControl | ||
.noCache() | ||
.cachePrivate(); | ||
|
||
WebContentInterceptor webContentInterceptor = new WebContentInterceptor(); | ||
webContentInterceptor.addCacheMapping(cacheControl, "/**"); | ||
registry.addInterceptor(webContentInterceptor); | ||
} | ||
} |
16 changes: 12 additions & 4 deletions
16
study/src/main/java/cache/com/example/etag/EtagFilterConfiguration.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 |
---|---|---|
@@ -1,12 +1,20 @@ | ||
package cache.com.example.etag; | ||
|
||
import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.filter.ShallowEtagHeaderFilter; | ||
|
||
import static cache.com.example.version.CacheBustingWebConfig.PREFIX_STATIC_RESOURCES; | ||
|
||
@Configuration | ||
public class EtagFilterConfiguration { | ||
|
||
// @Bean | ||
// public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() { | ||
// return null; | ||
// } | ||
@Bean | ||
public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() { | ||
FilterRegistrationBean<ShallowEtagHeaderFilter> registrationBean = new FilterRegistrationBean<>(new ShallowEtagHeaderFilter()); | ||
registrationBean.addUrlPatterns("/etag"); | ||
registrationBean.addUrlPatterns("/resources/*"); | ||
return registrationBean; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,19 @@ | ||
package nextstep; | ||
|
||
import nextstep.jwp.controller.LoginController; | ||
import nextstep.jwp.controller.RegisterController; | ||
import nextstep.jwp.controller.RootController; | ||
import org.apache.catalina.DispatcherServlet; | ||
import org.apache.catalina.RequestMapping; | ||
import org.apache.catalina.startup.Tomcat; | ||
|
||
public class Application { | ||
|
||
public static void main(String[] args) { | ||
final var tomcat = new Tomcat(); | ||
tomcat.start(); | ||
RequestMapping requestMapping = new RequestMapping().addHandler("/", new RootController()) | ||
.addHandler("/login", new LoginController()) | ||
.addHandler("/register", new RegisterController()); | ||
tomcat.start(new DispatcherServlet(requestMapping)); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
tomcat/src/main/java/nextstep/jwp/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,30 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import org.apache.catalina.Handler; | ||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.request.RequestMethod; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
import static org.apache.coyote.http11.request.RequestMethod.GET; | ||
import static org.apache.coyote.http11.request.RequestMethod.POST; | ||
|
||
public abstract class AbstractController implements Handler { | ||
@Override | ||
public void handle(final HttpRequest request, final HttpResponse response) throws Exception { | ||
RequestMethod requestMethod = request.getRequestLine().getRequestMethod(); | ||
if (requestMethod == GET) { | ||
doGet(request, response); | ||
return; | ||
} | ||
if (requestMethod == POST) { | ||
doPost(request, response); | ||
return; | ||
} | ||
} | ||
|
||
protected void doPost(HttpRequest request, HttpResponse response) throws Exception { | ||
} | ||
|
||
protected void doGet(HttpRequest request, HttpResponse response) throws Exception { | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
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,53 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import nextstep.jwp.db.InMemoryUserRepository; | ||
import nextstep.jwp.model.User; | ||
import org.apache.catalina.Session; | ||
import org.apache.catalina.SessionManager; | ||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.request.RequestBody; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
import static org.apache.coyote.http11.common.HttpStatus.*; | ||
|
||
public class LoginController extends AbstractController { | ||
|
||
private static final String USER_ATTRIBUTE = "user"; | ||
|
||
@Override | ||
protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { | ||
Session session = request.getSession(); | ||
if (session != null) { | ||
Session savedSession = SessionManager.findSession(session.getId()); | ||
Object sessionUserAttribute = session.getAttribute(USER_ATTRIBUTE); | ||
if (savedSession != null && sessionUserAttribute !=null && sessionUserAttribute.equals(savedSession.getAttribute(USER_ATTRIBUTE))) { | ||
response.httpStatus(FOUND) | ||
.header("Location", "/index.html") | ||
.redirectUri("/index.html"); | ||
return; | ||
} | ||
} | ||
response.httpStatus(OK) | ||
.redirectUri("/login.html"); | ||
} | ||
|
||
@Override | ||
protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { | ||
RequestBody requestBody = request.getRequestBody(); | ||
String account = requestBody.getContentValue("account"); | ||
String password = requestBody.getContentValue("password"); | ||
|
||
User user = InMemoryUserRepository.findByAccount(account) | ||
.orElseThrow(); | ||
if (user.checkPassword(password)) { | ||
request.getSession().setAttribute(USER_ATTRIBUTE, user); | ||
response.httpStatus(FOUND) | ||
.header("Location", "/index.html") | ||
.redirectUri("/index.html"); | ||
return; | ||
} | ||
response.httpStatus(UNAUTHORIZED) | ||
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. 401, 404, 500 등등 에러가 발생할 경우 현재는 각각 처리를 하고 있는데 이를 한곳에서 에러 핸들링을 하면 더 처리가 편하지 않을까요 ?! 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. 오션의 의견이 맞는것 같습니다. 예외 처리를 한다면 상위 객체로 예외를 몰아 처리를 해야할 것 같습니다. |
||
.header("Location", "/401.html") | ||
.redirectUri("/401.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.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.request.RequestBody; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
import static org.apache.coyote.http11.common.HttpStatus.FOUND; | ||
import static org.apache.coyote.http11.common.HttpStatus.OK; | ||
|
||
public class RegisterController extends AbstractController { | ||
|
||
@Override | ||
protected void doGet(final HttpRequest request, final HttpResponse response) throws Exception { | ||
response.httpStatus(OK) | ||
.redirectUri("/register.html"); | ||
} | ||
|
||
@Override | ||
protected void doPost(final HttpRequest request, final HttpResponse response) throws Exception { | ||
RequestBody requestBody = request.getRequestBody(); | ||
String account = requestBody.getContentValue("account"); | ||
String email = requestBody.getContentValue("email"); | ||
String password = requestBody.getContentValue("password"); | ||
InMemoryUserRepository.save(new User(account, password, email)); | ||
response.httpStatus(FOUND) | ||
.header("Location", "/index.html"); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
tomcat/src/main/java/nextstep/jwp/controller/RootController.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,15 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
import static org.apache.coyote.http11.common.HttpStatus.OK; | ||
|
||
public class RootController extends AbstractController { | ||
|
||
@Override | ||
protected void doGet(HttpRequest request, HttpResponse response) throws Exception { | ||
response.httpStatus(OK) | ||
.redirectUri("/root.html"); | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
tomcat/src/main/java/org/apache/catalina/DispatcherServlet.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,47 @@ | ||
package org.apache.catalina; | ||
|
||
import org.apache.coyote.http11.Servlet; | ||
import org.apache.coyote.http11.common.HttpCookie; | ||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.request.RequestHeader; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
public class DispatcherServlet implements Servlet { | ||
|
||
private final RequestMapping requestMapping; | ||
|
||
public DispatcherServlet(final RequestMapping requestMapping) { | ||
this.requestMapping = requestMapping; | ||
} | ||
|
||
@Override | ||
public void service(final HttpRequest httpRequest, final HttpResponse httpResponse) throws Exception { | ||
Handler handler = requestMapping.getHandler(httpRequest); | ||
setSessionOnHttpRequest(httpRequest); | ||
handler.handle(httpRequest, httpResponse); | ||
addSessionToHttpResponse(httpRequest, httpResponse); | ||
} | ||
|
||
private void setSessionOnHttpRequest(final HttpRequest httpRequest) { | ||
RequestHeader requestHeader = httpRequest.getRequestHeader(); | ||
HttpCookie cookie = requestHeader.getCookie(); | ||
String jsessionid = cookie.getCookieValue("JSESSIONID"); | ||
Session session = SessionManager.findSession(jsessionid); | ||
if (session == null) { | ||
return; | ||
} | ||
session.setFirstSent(false); | ||
httpRequest.setSession(session); | ||
} | ||
|
||
private void addSessionToHttpResponse(final HttpRequest httpRequest, final HttpResponse httpResponse) { | ||
Session session = httpRequest.getSession(); | ||
if (session == null) { | ||
Session newSession = new Session(); | ||
SessionManager.addSession(newSession); | ||
httpResponse.setSession(newSession); | ||
return; | ||
} | ||
httpResponse.setSession(session); | ||
} | ||
} |
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.catalina; | ||
|
||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
public interface Handler { | ||
|
||
void handle(HttpRequest request, HttpResponse response) throws Exception; | ||
} |
23 changes: 23 additions & 0 deletions
23
tomcat/src/main/java/org/apache/catalina/RequestMapping.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,23 @@ | ||
package org.apache.catalina; | ||
|
||
import org.apache.coyote.http11.request.HttpRequest; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class RequestMapping { | ||
|
||
private final Handler staticHandler = new StaticFileHandler(); | ||
|
||
private final Map<String, Handler> handlers = new HashMap<>(); | ||
|
||
public RequestMapping addHandler(String uri, Handler handler) { | ||
handlers.put(uri, handler); | ||
return this; | ||
} | ||
|
||
public Handler getHandler(final HttpRequest httpRequest) { | ||
String requestURI = httpRequest.getRequestLine().getRequestURI(); | ||
return handlers.getOrDefault(requestURI, staticHandler); | ||
} | ||
} |
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
8 changes: 5 additions & 3 deletions
8
.../coyote/http11/common/SessionManager.java → ...a/org/apache/catalina/SessionManager.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
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.
톰캣의 인자로 DispatcherServlet을 전달한 이유가 궁금합니다!
톰캣은 서블릿을 관리하고 실행한다고 저는 생각하는데 내부에서 처리가 되어야 하는게 아닌가 싶어서요!
여기서 받은 값을 커넥터에 servlet을 인자로 가지고 가는 것에대한 이유가 궁금합니당
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.
RequestMapping 정보는 애플리케이션 실행시에 넘겨주는 xml파일 같은 거라고 생각했어요.웹 애플리케이션이 시작될 때 서블릿 컨테이너(톰캣)은 web.xml 파일 또는 자바 기반 설정을 읽어 웹 애플리케이션의 구성을 초기화하는데, 이때 톰캣에 관련 정보를 넘겨주는 것이 맞다고 생각해서 이와 같이 구성하게 되었습니다.