-
Notifications
You must be signed in to change notification settings - Fork 311
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[1 - 2 단계 Tomcat 구현하기] 테드(김규태) 미션 제출합니다. (#572)
* fix: remove implementation logback-classic on gradle (#501) * fix: add threads min-spare configuration on properties (#502) * test: 스터디 테스트 작성 * refactor: 자동 정렬 이전 파일로 교체 * refactor: import 변경 * refactor: 요청에 따라 자원을 반환하도록 변경 * feat: HttpRequest 추가 * feat: HttpResponse 추가 * refactor: Http11Processor에서 요청과 응답 분리 * refactor: 로그인 메서드 post로 변경 * refactor: HttpRequest에 requestBody 추가 * refactor: HttpResponse에 상태코드 추가 * feat: 요청을 처리하는 컨트롤러 구현 * feat: 매핑된 컨트롤러를 찾아서 반환하는 RequestMapping 추가 * feat: ViewResolver 및 View 추가 * refactor: Http11Processor에서 Controller를 사용하도록 변경 * refactor: HttpRequest 에서 key 값으로 찾도록 변경 * refactor: HttpResponse 에 쿠키를 포함하는 기능 추가 * feat: 쿠키 및 세션 추가 * refactor: 로그인 시, 세션 확인하는 기능 추가 * refactor: ReqeustParser를 통해 HttpRequest 를 만들도록 변경 * refactor: HttpRequest 관련 클래스 분리 * refactor: RequestMapping 싱글톤으로 변경 * refactor: RegisterController에서 request의 기능을 활용하도록 변경 * refactor: 로깅 추가 및 수정 * refactor: Accpet로 response의 ContentType 구성하도록 변경 * refactor: 정의되지 않은 요청 시, 404 페이지 반환하도록 변경 * refactor: 사용하지 않는 주석 제거 * refactor: 패키지 구조 변경 * refactor: post 요청에서 body가 존재하지 않을 경우 400을 반환하도록 변경 * refactor: cookie에 대한 NPE 처리 * refactor: SessionManager 를 static 으로 활용하도록 변경 --------- Co-authored-by: Gyeongho Yang <[email protected]>
- Loading branch information
Showing
26 changed files
with
760 additions
and
40 deletions.
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
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
3 changes: 1 addition & 2 deletions
3
study/src/main/java/cache/com/example/version/ResourceVersion.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
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 |
---|---|---|
|
@@ -6,4 +6,5 @@ server: | |
accept-count: 1 | ||
max-connections: 1 | ||
threads: | ||
min-spare: 2 | ||
max: 2 |
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
26 changes: 26 additions & 0 deletions
26
tomcat/src/main/java/com/techcourse/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,26 @@ | ||
package com.techcourse.controller; | ||
|
||
import java.io.IOException; | ||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
public abstract class AbstractController implements Controller { | ||
|
||
@Override | ||
public void service(HttpRequest request, HttpResponse response) throws IOException { | ||
String method = request.getRequestLine().getMethod(); | ||
if (method.equals("POST")) { | ||
doPost(request, response); | ||
} else if (method.equals("GET")) { | ||
doGet(request, response); | ||
} else { | ||
response.setStatus405(); | ||
} | ||
} | ||
|
||
protected void doPost(HttpRequest request, HttpResponse response) throws IOException { | ||
} | ||
|
||
protected void doGet(HttpRequest request, HttpResponse response) throws IOException { | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
tomcat/src/main/java/com/techcourse/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 com.techcourse.controller; | ||
|
||
import java.io.IOException; | ||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
public interface Controller { | ||
void service(HttpRequest request, HttpResponse response) throws IOException; | ||
} |
96 changes: 96 additions & 0 deletions
96
tomcat/src/main/java/com/techcourse/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,96 @@ | ||
package com.techcourse.controller; | ||
|
||
import com.techcourse.db.InMemoryUserRepository; | ||
import com.techcourse.model.User; | ||
import java.io.IOException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import com.techcourse.session.Session; | ||
import com.techcourse.session.SessionManager; | ||
import com.techcourse.view.View; | ||
import com.techcourse.view.ViewResolver; | ||
import org.apache.coyote.http11.HttpCookie; | ||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
|
||
public class LoginController extends AbstractController { | ||
|
||
@Override | ||
protected void doGet(HttpRequest request, HttpResponse response) throws IOException { | ||
Session session = extractSession(request); | ||
if (session != null) { | ||
User user = (User) session.getAttribute("user"); | ||
if (user != null) { | ||
responseLoginSuccess(response, session); | ||
return; | ||
} | ||
} | ||
responseLoginPage(request, response); | ||
} | ||
|
||
@Override | ||
protected void doPost(HttpRequest request, HttpResponse response) { | ||
if (!request.hasBodyData()) { | ||
throw new IllegalArgumentException("Query string is missing in the request"); | ||
} | ||
|
||
Map<String, String> requestFormData = request.getFormData(); | ||
String userName = requestFormData.get("account"); | ||
String password = requestFormData.get("password"); | ||
|
||
Optional<User> account = InMemoryUserRepository.findByAccount(userName); | ||
if (account.isEmpty()) { | ||
responseLoginFail(response); | ||
} else { | ||
User user = account.get(); | ||
if (user.checkPassword(password)) { | ||
Session session = saveSession(user); | ||
responseLoginSuccess(response, session); | ||
} else { | ||
responseLoginFail(response); | ||
} | ||
} | ||
} | ||
|
||
private Session extractSession(HttpRequest request) { | ||
String cookie = request.getCookie(); | ||
if (cookie == null) { | ||
Map<String, String> cookies = new HashMap<>(); | ||
for (String cookieParts : cookie.split(" ")) { | ||
String[] keyAndValue = cookieParts.split("="); | ||
cookies.put(keyAndValue[0], keyAndValue[1]); | ||
} | ||
|
||
String jsessionId = cookies.get("JSESSIONID"); | ||
return SessionManager.findSession(jsessionId); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
private Session saveSession(User user) { | ||
Session session = new Session(); | ||
session.setAttribute("user", user); | ||
SessionManager.add(session); | ||
return session; | ||
} | ||
|
||
private void responseLoginPage(HttpRequest request, HttpResponse response) throws IOException { | ||
View view = ViewResolver.getView("/login.html"); | ||
response.setStatus200(); | ||
response.setResponseBody(view.getContent()); | ||
response.setContentType(request.getContentType()); | ||
} | ||
|
||
private void responseLoginSuccess(HttpResponse response, Session session) { | ||
response.setStatus302(); | ||
response.setLocation("/index.html"); | ||
response.setCookie(HttpCookie.ofJSessionId(session.getId())); | ||
} | ||
|
||
private void responseLoginFail(HttpResponse response) { | ||
response.setStatus302(); | ||
response.setLocation("/401.html"); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
tomcat/src/main/java/com/techcourse/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,58 @@ | ||
package com.techcourse.controller; | ||
|
||
import com.techcourse.db.InMemoryUserRepository; | ||
import com.techcourse.model.User; | ||
import java.io.IOException; | ||
import java.util.Map; | ||
import com.techcourse.view.View; | ||
import com.techcourse.view.ViewResolver; | ||
import org.apache.coyote.http11.request.HttpRequest; | ||
import org.apache.coyote.http11.response.HttpResponse; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class RegisterController extends AbstractController { | ||
|
||
private static final Logger log = LoggerFactory.getLogger(RegisterController.class); | ||
|
||
@Override | ||
protected void doPost(HttpRequest request, HttpResponse response) { | ||
try { | ||
if (!request.hasBodyData()) { | ||
throw new IllegalArgumentException("RequestBody is missing in the request"); | ||
} | ||
|
||
Map<String, String> requestFormData = request.getFormData(); | ||
String account = requestFormData.get("account"); | ||
String password = requestFormData.get("password"); | ||
String email = requestFormData.get("email"); | ||
|
||
User user = new User(account, password, email); | ||
InMemoryUserRepository.save(user); | ||
responseRegisterSuccess(response); | ||
|
||
} catch (IllegalArgumentException e) { | ||
response.setStatus400(); | ||
response.setResponseBody(e.getMessage()); | ||
log.info("Bad Request: {}", e.getMessage()); | ||
|
||
} | ||
} | ||
|
||
@Override | ||
protected void doGet(HttpRequest request, HttpResponse response) throws IOException { | ||
responseRegisterPage(request, response); | ||
} | ||
|
||
private void responseRegisterSuccess(HttpResponse response) { | ||
response.setStatus302(); | ||
response.setLocation("/index.html"); | ||
} | ||
|
||
private void responseRegisterPage(HttpRequest request, HttpResponse response) throws IOException { | ||
View view = ViewResolver.getView("/register.html"); | ||
response.setStatus200(); | ||
response.setResponseBody(view.getContent()); | ||
response.setContentType(request.getContentType()); | ||
} | ||
} |
Oops, something went wrong.