-
Notifications
You must be signed in to change notification settings - Fork 309
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[톰캣 구현하기 - 3, 4 단계] - 제나(위예나) 미션 제출합니다 (#458)
* docs: 기능 요구사항 업데이트 * refactor: ContentType svg 추가 * refactor: 문자열 상수화. java convention * refactor: HttpStatus 추가 * feat: 정적파일 못 읽어올때 404 페이지로 리턴 * feat: controller interface 구현 * feat: uri 에 따른 컨트롤러 생성 * feat: RequestMapping 객체로 분기 처리 위임 * feat: HttpResponse 정적팩터리메소드 추가 * feat: HttpResponse 빌더패턴 삭제. setter 로 구현 * refactor: RequestMapping 분기 처리 제거 * refactor: SessionManager 동시성 컬렉션 사용 * feat: Executors 로 ThreadPool 적용 * fix: LoginController NPE 처리 * fix: Controller 싱글톤 적용 * feat: 404, 500 리다이렉션 처리 수정 * fix: test 깨지는 것 수정 * refactor: Header 상수화 * refactor: sonarlint 분석 반영 * refactor: LoginController if/else 분기 수정 * refactor: 문자열 상수화
- Loading branch information
Showing
23 changed files
with
454 additions
and
229 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
37 changes: 37 additions & 0 deletions
37
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,37 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import org.apache.coyote.Controller; | ||
import org.apache.coyote.request.HttpRequest; | ||
import org.apache.coyote.response.HttpResponse; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import static org.apache.coyote.common.ContentType.HTML; | ||
import static org.apache.coyote.common.Headers.LOCATION; | ||
import static org.apache.coyote.response.HttpStatus.FOUND; | ||
|
||
public class AbstractController implements Controller { | ||
|
||
protected static final Logger log = LoggerFactory.getLogger(AbstractController.class); | ||
|
||
@Override | ||
public void service(HttpRequest request, HttpResponse response) throws Exception { | ||
|
||
try { | ||
if (request.getRequestLine().isGetMethod()) { | ||
doGet(request, response); | ||
} | ||
if (request.getRequestLine().isPostMethod()) { | ||
doPost(request, response); | ||
} | ||
} catch (Exception e) { | ||
response.setStatus(FOUND); | ||
response.setContentType(HTML); | ||
response.addHeader(LOCATION, "/500.html"); | ||
} | ||
} | ||
|
||
protected void doPost(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } | ||
|
||
protected void doGet(HttpRequest request, HttpResponse response) throws Exception { /* NOOP */ } | ||
} |
36 changes: 36 additions & 0 deletions
36
tomcat/src/main/java/nextstep/jwp/controller/DefaultController.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,36 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import org.apache.coyote.Controller; | ||
import org.apache.coyote.common.ContentType; | ||
import org.apache.coyote.request.HttpRequest; | ||
import org.apache.coyote.request.RequestUri; | ||
import org.apache.coyote.response.HttpResponse; | ||
import org.apache.coyote.utils.FileUtils; | ||
|
||
import static org.apache.coyote.common.ContentType.HTML; | ||
import static org.apache.coyote.common.Headers.LOCATION; | ||
import static org.apache.coyote.response.HttpStatus.FOUND; | ||
|
||
public class DefaultController extends AbstractController { | ||
|
||
private static final Controller INSTANCE = new DefaultController(); | ||
|
||
public static Controller getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
@Override | ||
protected void doGet(HttpRequest request, HttpResponse response) throws Exception { | ||
RequestUri requestUri = request.getRequestLine().getRequestUri(); | ||
|
||
try { | ||
FileUtils.readFile(requestUri.getPath()); | ||
response.setContentType(ContentType.from(requestUri.getExtension())); | ||
response.setBody(FileUtils.readFile(requestUri.getPath())); | ||
} catch (NullPointerException e) { | ||
response.setStatus(FOUND); | ||
response.setContentType(HTML); | ||
response.addHeader(LOCATION, "/404.html"); | ||
} | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
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,92 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import nextstep.jwp.db.InMemoryUserRepository; | ||
import nextstep.jwp.model.User; | ||
import org.apache.catalina.manager.SessionManager; | ||
import org.apache.coyote.Controller; | ||
import org.apache.coyote.common.HttpCookie; | ||
import org.apache.coyote.common.Session; | ||
import org.apache.coyote.request.HttpRequest; | ||
import org.apache.coyote.request.HttpRequestBody; | ||
import org.apache.coyote.response.HttpResponse; | ||
import org.apache.coyote.utils.FileUtils; | ||
|
||
import java.util.Optional; | ||
|
||
import static org.apache.coyote.common.ContentType.HTML; | ||
import static org.apache.coyote.common.Headers.JSESSIONID; | ||
import static org.apache.coyote.common.Headers.LOCATION; | ||
import static org.apache.coyote.response.HttpStatus.FOUND; | ||
import static org.apache.coyote.response.HttpStatus.OK; | ||
|
||
public class LoginController extends AbstractController { | ||
|
||
private static final Controller INSTANCE = new LoginController(); | ||
|
||
public static Controller getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
@Override | ||
protected void doPost(HttpRequest request, HttpResponse response) throws Exception { | ||
HttpRequestBody httpRequestBody = request.getRequestBody(); | ||
String account = httpRequestBody.getValue("account"); | ||
String password = httpRequestBody.getValue("password"); | ||
|
||
Optional<User> user = InMemoryUserRepository.findByAccount(account); | ||
|
||
if (user.isPresent()) { | ||
user.filter(userInfo -> userInfo.checkPassword(password)) | ||
.ifPresentOrElse(registerUser -> { | ||
log.info(registerUser.toString()); | ||
loginSuccess(registerUser, response); | ||
} | ||
, () -> { | ||
log.warn("비밀번호가 틀렸습니다"); | ||
loginFail(response); | ||
}); | ||
return; | ||
} | ||
log.warn("미가입회원입니다"); | ||
loginFail(response); | ||
} | ||
|
||
private void loginSuccess(User user, HttpResponse response) { | ||
Session session = new Session(); | ||
session.setAttribute("user", user); | ||
SessionManager.add(session); | ||
|
||
HttpCookie cookie = HttpCookie.of(JSESSIONID + "=" + session.getId()); | ||
|
||
response.setStatus(FOUND); | ||
response.setContentType(HTML); | ||
response.addHeader(LOCATION, "/index.html"); | ||
response.setCookie(cookie); | ||
} | ||
|
||
private void loginFail(HttpResponse response) { | ||
response.setStatus(FOUND); | ||
response.setContentType(HTML); | ||
response.addHeader(LOCATION, "/401.html"); | ||
} | ||
|
||
|
||
@Override | ||
protected void doGet(HttpRequest request, HttpResponse response) throws Exception { | ||
HttpCookie cookie = request.getRequestHeader().getCookie(); | ||
|
||
String jsessionid = cookie.getValue(JSESSIONID); | ||
Optional<Session> session = SessionManager.findSession(jsessionid); | ||
|
||
if (session.isPresent()) { | ||
response.setStatus(FOUND); | ||
response.addHeader(LOCATION, "/index.html"); | ||
response.setContentType(HTML); | ||
return; | ||
} | ||
|
||
response.setStatus(OK); | ||
response.setContentType(HTML); | ||
response.setBody(FileUtils.readFile("/login.html")); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
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,51 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import nextstep.jwp.db.InMemoryUserRepository; | ||
import nextstep.jwp.model.User; | ||
import org.apache.coyote.Controller; | ||
import org.apache.coyote.common.ContentType; | ||
import org.apache.coyote.request.HttpRequest; | ||
import org.apache.coyote.request.HttpRequestBody; | ||
import org.apache.coyote.request.RequestUri; | ||
import org.apache.coyote.response.HttpResponse; | ||
import org.apache.coyote.utils.FileUtils; | ||
|
||
import static org.apache.coyote.common.ContentType.HTML; | ||
import static org.apache.coyote.common.Headers.LOCATION; | ||
import static org.apache.coyote.response.HttpStatus.FOUND; | ||
|
||
public class RegisterController extends AbstractController { | ||
|
||
private static final Controller INSTANCE = new RegisterController(); | ||
|
||
public static Controller getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
@Override | ||
protected void doPost(HttpRequest request, HttpResponse response) throws Exception { | ||
HttpRequestBody httpRequestBody = request.getRequestBody(); | ||
|
||
String account = httpRequestBody.getValue("account"); | ||
String password = httpRequestBody.getValue("password"); | ||
String email = httpRequestBody.getValue("email"); | ||
|
||
if (InMemoryUserRepository.findByAccount(account).isPresent()) { | ||
throw new IllegalArgumentException("중복 ID 입니다"); | ||
} | ||
|
||
InMemoryUserRepository.save(new User(account, password, email)); | ||
|
||
response.setStatus(FOUND); | ||
response.setContentType(HTML); | ||
response.addHeader(LOCATION, "/index.html"); | ||
} | ||
|
||
@Override | ||
protected void doGet(HttpRequest request, HttpResponse response) throws Exception { | ||
RequestUri requestUri = request.getRequestLine().getRequestUri(); | ||
|
||
response.setContentType(ContentType.from(requestUri.getExtension())); | ||
response.setBody(FileUtils.readFile("/register.html")); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
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,22 @@ | ||
package nextstep.jwp.controller; | ||
|
||
import org.apache.coyote.Controller; | ||
import org.apache.coyote.request.HttpRequest; | ||
import org.apache.coyote.response.HttpResponse; | ||
|
||
import static org.apache.coyote.common.ContentType.HTML; | ||
|
||
public class RootController extends AbstractController { | ||
|
||
private static final Controller INSTANCE = new RootController(); | ||
|
||
public static Controller getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
@Override | ||
protected void doGet(HttpRequest request, HttpResponse response) throws Exception { | ||
response.setContentType(HTML); | ||
response.setBody("Hello world!"); | ||
} | ||
} |
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 |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package org.apache.coyote; | ||
|
||
import org.apache.coyote.request.HttpRequest; | ||
import org.apache.coyote.response.HttpResponse; | ||
|
||
public interface Controller { | ||
void service(HttpRequest request, HttpResponse response) throws Exception; | ||
} |
36 changes: 36 additions & 0 deletions
36
tomcat/src/main/java/org/apache/coyote/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,36 @@ | ||
package org.apache.coyote; | ||
|
||
import nextstep.jwp.controller.DefaultController; | ||
import nextstep.jwp.controller.LoginController; | ||
import nextstep.jwp.controller.RegisterController; | ||
import nextstep.jwp.controller.RootController; | ||
import org.apache.coyote.request.HttpRequest; | ||
import org.apache.coyote.request.RequestUri; | ||
|
||
import java.util.Map; | ||
|
||
public class RequestMapping { | ||
|
||
private static final Map<String, Controller> mappers; | ||
|
||
static { | ||
mappers = Map.of( | ||
"/", RootController.getInstance(), | ||
"/login", LoginController.getInstance(), | ||
"/register", RegisterController.getInstance()); | ||
} | ||
|
||
|
||
public Controller getController(HttpRequest request) { | ||
RequestUri requestUri = request.getRequestLine().getRequestUri(); | ||
|
||
String path = requestUri.getPath(); | ||
|
||
return mappers.entrySet() | ||
.stream() | ||
.filter(entry -> path.equals(entry.getKey())) | ||
.map(Map.Entry::getValue) | ||
.findFirst() | ||
.orElse(DefaultController.getInstance()); | ||
} | ||
} |
Oops, something went wrong.