Skip to content
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

[보스독] 4단계 - HTTP 웹 서버 리팩토링 미션 제출합니다. #187

Open
wants to merge 10 commits into
base: yeonnseok
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
- [x] 지금까지 구현한 소스 코드는 stylesheet 파일을 지원하지 못하고 있다. Stylesheet 파일을 지원하도록 구현하도록 한다.
- [x] “로그인” 메뉴 클릭하면 /user/login.html 으로 이동해 로그인할 수 있다. 로그인이 성공 시 index.html로 이동, 로그인이 실패 시 /user/login_failed.html로 이동한다.
- [x] 로그인이 성공하면 cookie를 활용해 로그인 상태를 유지 한다. 로그인이 성공 시 요청 header의 Cookie 값이 logined=true, 로그인이 실패하면 Cookie 값이 logined=false로 전달되어야 한다.
- [ ] 사용자가 “로그인” 상태일 경우 /user/list 로 접근했을 때 사용자 목록을 출력한다. 만약 로그인하지 않은 상태라면 로그인 페이지로 이동한다.
- [ ] 동적으로 html을 생성하기 위해 handlebars.java template engine을 활용한다.
- [ ] 서블릿에서 지원하는 HttpSession API의 일부를 지원 한다.
- [ ] String getId() : 현재 세션에 할당되어 있는 고유한 세션 아이디를 반환
- [ ] void setAttribute(String name, Object value) : 현재 세션에 value 인자로 전달되는 객체를 name 인자 이름으로 저장
- [ ] Object getAttribute(String name) : 현재 세션에 name 인자로 저장되어 있는 객체 값을 찾아 반환
- [ ] void removeAttribute(String name) : 현재 세션에 name 인자로 저장되어 있는 객체 값을 삭제
- [ ] void invalidate() : 현재 세션에 저장되어 있는 모든 값을 삭제
- [ ] 세션의 고유 아이디는 JDK에서 제공하는 UUID 클래스를 사용해 고유한 아이디를 활용한다.
- [ ] 세션 관리를 위한 자료구조는 Map을 사용하며, Map<String, HttpSession>와 같은 구조가 된다. 이 때, 키는 UUID이다.
- [x] 사용자가 “로그인” 상태일 경우 /user/list 로 접근했을 때 사용자 목록을 출력한다. 만약 로그인하지 않은 상태라면 로그인 페이지로 이동한다.
- [x] 동적으로 html을 생성하기 위해 handlebars.java template engine을 활용한다.
- [x] 서블릿에서 지원하는 HttpSession API의 일부를 지원 한다.
- [x] String getId() : 현재 세션에 할당되어 있는 고유한 세션 아이디를 반환
- [x] void setAttribute(String name, Object value) : 현재 세션에 value 인자로 전달되는 객체를 name 인자 이름으로 저장
- [x] Object getAttribute(String name) : 현재 세션에 name 인자로 저장되어 있는 객체 값을 찾아 반환
- [x] void removeAttribute(String name) : 현재 세션에 name 인자로 저장되어 있는 객체 값을 삭제
- [x] void invalidate() : 현재 세션에 저장되어 있는 모든 값을 삭제
- [x] 세션의 고유 아이디는 JDK에서 제공하는 UUID 클래스를 사용해 고유한 아이디를 활용한다.
- [x] 세션 관리를 위한 자료구조는 Map을 사용하며, Map<String, HttpSession>와 같은 구조가 된다. 이 때, 키는 UUID이다.
- [x] service application과 server/servlet부분을 멀티 모듈로 분리한다.
- [x] web-server, web-common, service-app 세개의 모듈로 분리

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모듈 잘 분리해주셨네요! 피드백은 이쪽에 작성하겠습니다 :)

  1. 전체 프로젝트에 적용되어야 할 의존성을 common 모듈을 사용하셨네요. root level 에 build.gradle 을 정의하여 전체 프로젝트에 적용되어야 할 설정을 작성해보는 것은 어떨까요?

  2. web-server 모듈을 완전한 라이브러리로 분리해보시는 것은 어떨까요? 그동안 구현하셨던 웹서버를 어떤 어플리케이션 비지니스에도 녹일 수 있도록 작성하셨을 것이라고 생각합니다. 그러나 현재의 web-server 모듈은 비지니스를 포함하고 있는 것 처럼 보이네요 :) 어떤 어플리케이션에서도 해당 라이브러리를 사용할 수 있도록 조금 더 분리해보시길 바랍니다.

  3. common 이란 네이밍은 다소 위험함이 있습니다. common 이라는 추상적인 네이밍은 네이밍이 가진 추상적인 의미 때문에 어떠한 코드도 들어갈 수 있습니다. 그래서 되도록이면 명시적인 네이밍을 작성할 것을 추천합니다. 실제로 추상적인 네이밍으로 어마무시한 슈퍼 모듈이 만들어지고 이 슈퍼 모듈이 스파게티 의존을 만들어내는 경우들을 많이 보아왔습니다.

  4. 각 모듈은 본인이 작성한 의도가 있긴 할텐데요. 그것을 다른 사람이 보았을 때도 명확히 이해하기 힘들 수 있습니다. 아무리 명시적으로 하려고 해도 추상적인 의미를 갖는 네이밍을 갖기도 할텐데요. README.md 를 각 모듈별로 작성하여, 해당 모듈의 책임과 역할이 어느 범위인지를 명시해주면 좋을 것 같습니다 :)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

킹뽀대님! 이번에도 섬세한 리뷰 감사합니다.!
다른 부분은 어느정도 제가 이해를 한 것 같아 반영해보았습니다.
다만 2번에서 web-server모듈을 완전한 라이브러리로 분리하는 피드백을 반영하려다보니, 비즈니스 로직을 포함하고 있는 부분을 캐치하는게 쉽지 않았습니다. ㅠㅠ 그나마 Session에 관한 내용이 요구사항으로 인해 적용되었던 점을 감안해서 Session부분을 다른 모듈로 분리해보았는데요. 의도하신 부분이 이게 맞는지는 잘 모르겠습니다.
또한 Session을 분리하고 있다고 해도 ReuqestHandler등에서 이미 HttpSession을 사용하고 있던터라, 완전한 라이브러리화는 안되고 있는 것 같은데요, 이 부분에 대해서 조금만 더 힌트를 주시면 감사드리겠습니다!

59 changes: 46 additions & 13 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,25 +1,58 @@
buildscript {
ext {
springBootVersion = '2.2.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}

plugins {
id 'java'
id 'idea'
id 'eclipse'
}

version = '1.0.0'
sourceCompatibility = 1.8
allprojects {
version = '1.0.0'
}

subprojects {
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'eclipse'

sourceCompatibility = 1.8

repositories {
mavenCentral()
}

dependencies {
implementation 'ch.qos.logback:logback-classic:1.2.3'
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
testImplementation 'org.assertj:assertj-core:3.16.1'
}

repositories {
mavenCentral()
test {
useJUnitPlatform()
}
}

dependencies {
implementation 'com.google.guava:guava:29.0-jre'
implementation 'ch.qos.logback:logback-classic:1.2.3'
implementation 'com.github.jknack:handlebars:4.2.0'
implementation 'org.springframework:spring-core:5.2.6.RELEASE'
testImplementation 'org.junit.jupiter:junit-jupiter:5.6.2'
testImplementation 'org.assertj:assertj-core:3.16.1'
project(':web-server') {
dependencies {
compile project(':web-domain')
compile project(':web-session')
}
}

test {
useJUnitPlatform()
project(':service-app') {
dependencies {
compile project(':web-domain')
compile project(':web-server')
compile project(':web-session')
}
}
4 changes: 4 additions & 0 deletions service-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## service-app module
- 웹 애플리케이션을 수행하기 위한 표현계층과 응용계층 영속계층이 정의된다. (현재 응용계층은 존재하지 않는다.)
- web-domain, web-server 모듈을 참조하고 있다.
- UrlAppender에서 enum으로 정의된 url주소와 Controller를 한 쌍으로 지정하고, web-server에서 제공하는 RequestMapper에 내용이 반영된다.
3 changes: 3 additions & 0 deletions service-app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
implementation 'com.google.guava:guava:29.0-jre'
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
package web.controller;
package interfaces;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import db.DataBase;
import model.User;
import model.UserDto;
import web.controller.AbstractController;
import web.http.HttpRequest;
import web.http.HttpRequestParams;
import web.http.HttpResponse;

public class CreateUserController extends AbstractController {
private static final Logger logger = LoggerFactory.getLogger(CreateUserController.class);

@Override
protected void doPost(HttpRequest request, HttpResponse response) {
User user = User.from(request.getRequestBody());
HttpRequestParams requestParams = request.getRequestBody();
UserDto userDto = new UserDto(
requestParams.getParameter("userId"),
requestParams.getParameter("password"),
requestParams.getParameter("name"),
requestParams.getParameter("email"));

User user = userDto.toUser();
logger.info("user : {}", user);
DataBase.addUser(user);
response.sendRedirect("/index.html");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package web.controller;
package interfaces;

import db.DataBase;
import model.User;
import web.session.HttpSession;
import web.controller.AbstractController;
import web.http.HttpRequest;
import web.http.HttpResponse;
import web.session.HttpSession;

public class LoginController extends AbstractController {
@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package web.controller;
package interfaces;

import java.util.Collection;
import java.util.HashMap;
Expand All @@ -9,6 +9,7 @@
import view.ModelAndView;
import view.View;
import web.StaticFile;
import web.controller.AbstractController;
import web.http.HttpRequest;
import web.http.HttpResponse;
import web.session.HttpSession;
Expand All @@ -31,10 +32,6 @@ protected void doGet(HttpRequest request, HttpResponse response) {
}

private boolean isLogin(HttpRequest request) {
if (request.getCookies() == null) {
return false;
}

HttpSession session = request.getSession();
Object user = session.getAttribute("user");
return user != null;
Expand Down
28 changes: 28 additions & 0 deletions service-app/src/main/java/interfaces/urlmapper/UrlAppender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package interfaces.urlmapper;

import java.util.Arrays;

import interfaces.CreateUserController;
import interfaces.LoginController;
import interfaces.UserListController;
import web.controller.Controller;
import webserver.RequestMapping;

public enum UrlAppender {
CREATE_USER_CONTROLLER("/user/create", new CreateUserController()),
LOGIN_CONTROLLER("/user/login", new LoginController()),
USER_LIST_CONTROLLER("/user/list", new UserListController());

private final String url;
private final Controller controller;

UrlAppender(String url, Controller controller) {
this.url = url;
this.controller = controller;
}

static {
Arrays.stream(values())
.forEach(v -> RequestMapping.addUrl(v.url, v.controller));
}
}
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@
<div class="wrap">
<div class="main">
<strong class="subject">
<a href="./qna/show.html">국내에서 Ruby on Rails와 Play가 활성화되기 힘든 이유는 뭘까?</a>
<a href="qna/show.html">국내에서 Ruby on Rails와 Play가 활성화되기 힘든 이유는 뭘까?</a>
</strong>
<div class="auth-info">
<i class="icon-add-comment"></i>
<span class="time">2016-01-15 18:47</span>
<a href="./user/profile.html" class="author">자바지기</a>
<a href="user/profile.html" class="author">자바지기</a>
</div>
<div class="reply" title="댓글">
<i class="icon-reply"></i>
Expand All @@ -104,12 +104,12 @@
<div class="wrap">
<div class="main">
<strong class="subject">
<a href="./qna/show.html">runtime 에 reflect 발동 주체 객체가 뭔지 알 방법이 있을까요?</a>
<a href="qna/show.html">runtime 에 reflect 발동 주체 객체가 뭔지 알 방법이 있을까요?</a>
</strong>
<div class="auth-info">
<i class="icon-add-comment"></i>
<span class="time">2016-01-05 18:47</span>
<a href="./user/profile.html" class="author">김문수</a>
<a href="user/profile.html" class="author">김문수</a>
</div>
<div class="reply" title="댓글">
<i class="icon-reply"></i>
Expand All @@ -133,7 +133,7 @@
</ul>
</div>
<div class="col-md-3 qna-write">
<a href="./qna/form.html" class="btn btn-primary pull-right" role="button">질문하기</a>
<a href="qna/form.html" class="btn btn-primary pull-right" role="button">질문하기</a>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<div class="navbar-header">
<a href="#" style="margin-left:15px;" class="navbar-btn btn btn-default btn-plus dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-home" style="color:#dd1111;"></i> Home <small><i class="glyphicon glyphicon-chevron-down"></i></small></a>
<ul class="nav dropdown-menu">
<li><a href="../user/profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li><a href="profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li class="nav-divider"></li>
<li><a href="#"><i class="glyphicon glyphicon-cog" style="color:#dd1111;"></i> Settings</a></li>
</ul>
Expand All @@ -63,8 +63,8 @@
<div class="collapse navbar-collapse" id="navbar-collapse2">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a href="../index.html">Posts</a></li>
<li><a href="../user/login.html" role="button">로그인</a></li>
<li><a href="../user/form.html" role="button">회원가입</a></li>
<li><a href="login.html" role="button">로그인</a></li>
<li><a href="form.html" role="button">회원가입</a></li>
<li><a href="#" role="button">로그아웃</a></li>
<li><a href="#" role="button">개인정보수정</a></li>
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<div class="navbar-header">
<a href="#" style="margin-left:15px;" class="navbar-btn btn btn-default btn-plus dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-home" style="color:#dd1111;"></i> Home <small><i class="glyphicon glyphicon-chevron-down"></i></small></a>
<ul class="nav dropdown-menu">
<li><a href="../user/profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li><a href="profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li class="nav-divider"></li>
<li><a href="#"><i class="glyphicon glyphicon-cog" style="color:#dd1111;"></i> Settings</a></li>
</ul>
Expand All @@ -64,8 +64,8 @@
<div class="collapse navbar-collapse" id="navbar-collapse2">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a href="../index.html">Posts</a></li>
<li><a href="../user/login.html" role="button">로그인</a></li>
<li><a href="../user/form.html" role="button">회원가입</a></li>
<li><a href="login.html" role="button">로그인</a></li>
<li><a href="form.html" role="button">회원가입</a></li>
<li><a href="#" role="button">로그아웃</a></li>
<li><a href="#" role="button">개인정보수정</a></li>
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<div class="navbar-header">
<a href="#" style="margin-left:15px;" class="navbar-btn btn btn-default btn-plus dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-home" style="color:#dd1111;"></i> Home <small><i class="glyphicon glyphicon-chevron-down"></i></small></a>
<ul class="nav dropdown-menu">
<li><a href="../user/profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li><a href="profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li class="nav-divider"></li>
<li><a href="#"><i class="glyphicon glyphicon-cog" style="color:#dd1111;"></i> Settings</a></li>
</ul>
Expand All @@ -64,8 +64,8 @@
<div class="collapse navbar-collapse" id="navbar-collapse2">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a href="../index.html">Posts</a></li>
<li><a href="../user/login.html" role="button">로그인</a></li>
<li><a href="../user/form.html" role="button">회원가입</a></li>
<li><a href="login.html" role="button">로그인</a></li>
<li><a href="form.html" role="button">회원가입</a></li>
<li><a href="#" role="button">로그아웃</a></li>
<li><a href="#" role="button">개인정보수정</a></li>
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<div class="navbar-header">
<a href="#" style="margin-left:15px;" class="navbar-btn btn btn-default btn-plus dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-home" style="color:#dd1111;"></i> Home <small><i class="glyphicon glyphicon-chevron-down"></i></small></a>
<ul class="nav dropdown-menu">
<li><a href="../user/profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li><a href="profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li class="nav-divider"></li>
<li><a href="#"><i class="glyphicon glyphicon-cog" style="color:#dd1111;"></i> Settings</a></li>
</ul>
Expand All @@ -64,8 +64,8 @@
<div class="collapse navbar-collapse" id="navbar-collapse2">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a href="../index.html">Posts</a></li>
<li><a href="../user/login.html" role="button">로그인</a></li>
<li><a href="../user/form.html" role="button">회원가입</a></li>
<li><a href="login.html" role="button">로그인</a></li>
<li><a href="form.html" role="button">회원가입</a></li>
<li><a href="#" role="button">로그아웃</a></li>
<li><a href="#" role="button">개인정보수정</a></li>
</ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<div class="navbar-header">
<a href="#" style="margin-left:15px;" class="navbar-btn btn btn-default btn-plus dropdown-toggle" data-toggle="dropdown"><i class="glyphicon glyphicon-home" style="color:#dd1111;"></i> Home <small><i class="glyphicon glyphicon-chevron-down"></i></small></a>
<ul class="nav dropdown-menu">
<li><a href="../user/profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li><a href="profile.html"><i class="glyphicon glyphicon-user" style="color:#1111dd;"></i> Profile</a></li>
<li class="nav-divider"></li>
<li><a href="#"><i class="glyphicon glyphicon-cog" style="color:#dd1111;"></i> Settings</a></li>
</ul>
Expand All @@ -64,8 +64,8 @@
<div class="collapse navbar-collapse" id="navbar-collapse2">
<ul class="nav navbar-nav navbar-right">
<li class="active"><a href="../index.html">Posts</a></li>>
<li><a href="../user/login.html" role="button">로그인</a></li>
<li><a href="../user/form.html" role="button">회원가입</a></li>
<li><a href="login.html" role="button">로그인</a></li>
<li><a href="form.html" role="button">회원가입</a></li>
<li><a href="#" role="button">로그아웃</a></li>
<li><a href="#" role="button">개인정보수정</a></li>
</ul>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package web.controller;
package interfaces;

import static org.assertj.core.api.Assertions.*;

Expand All @@ -11,6 +11,7 @@
import org.junit.jupiter.api.Test;

import db.DataBase;
import web.controller.Controller;
import web.http.HttpRequest;
import web.http.HttpResponse;
import web.http.HttpStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package web.controller;
package interfaces;

import static org.assertj.core.api.Assertions.*;

Expand All @@ -13,6 +13,7 @@

import db.DataBase;
import model.User;
import web.controller.Controller;
import web.http.HttpRequest;
import web.http.HttpResponse;
import web.http.HttpStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package web.controller;
package interfaces;

import static org.assertj.core.api.Assertions.*;

Expand All @@ -11,6 +11,7 @@
import org.junit.jupiter.api.Test;

import model.User;
import web.controller.Controller;
import web.http.HttpRequest;
import web.http.HttpResponse;
import web.http.HttpStatus;
Expand Down
Loading