Skip to content

Step1 구현하기 #34

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

Merged
merged 30 commits into from
Jan 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
6794a83
Enum 클래스 RequstMethod 구현 및 활용을 통해 요청Path 가져오도록 함
leejh903 Jan 16, 2019
2ea81f4
요구사항1 구현 완료
leejh903 Jan 16, 2019
e5e74e9
Url 객체(accesspath, queryString) 구현 및 테스트
leejh903 Jan 17, 2019
3579360
Url이 맨처음에 나온다는 점을 이용하여 Url객체 생성하여 코드 단순화
leejh903 Jan 17, 2019
e16122e
Requirement3 implemented! - extract POST Body value and make User Object
leejh903 Jan 18, 2019
52f49ae
Requirement4 implemented! - redirect to index.html after creating Use…
leejh903 Jan 18, 2019
93a53c9
root 디렉토리 생성 및 MappingHandler 구현
leejh903 Jan 18, 2019
85e06b9
MappingHandler 내method invoke메서드 구현 및 데모를 통해 확인
leejh903 Jan 18, 2019
cab1c56
Url queryString GET, POST 모두 대응할 수 있도록 리팩토링
leejh903 Jan 18, 2019
bcffce4
ParameterBinder 구현 중 - Url 클래스 내 queryValue 자료구조 변경(String -> Map<Str…
leejh903 Jan 18, 2019
c611281
ParameterBinder 구현 및 테스트 완료
leejh903 Jan 19, 2019
1991f2a
viewResolver 구현 및 테스트 완료
leejh903 Jan 19, 2019
9d37ac8
response300 에서 redirect할 url path 부분 리팩토링(기존 서버 도메인 하드코딩 -> 상수값 처리)
leejh903 Jan 19, 2019
aa97f94
Request 객체 만들어서 적용중 - 이전의 Url 중심의 코드가 많아 리팩토링 계속 진행중, Url getter를 없애는…
leejh903 Jan 19, 2019
ba96bdd
cookie값 입히기 구현
leejh903 Jan 19, 2019
38b2cd0
Request 객체 -> Header로 리팩토링 및 Cookie 리팩토링 -> 새로운 쿠키 HttpSession, 기존쿠키값…
leejh903 Jan 19, 2019
07c70e6
쿠키 설정시 wrong content length 에러 해결
leejh903 Jan 19, 2019
d8fe9c5
최대한 header 객체 생성시 초기화 할 수 있도록 리팩토링
leejh903 Jan 20, 2019
8eb2f11
기존 Url 객체 의존관계를 Header객체를 통하도록 최대한 제거
leejh903 Jan 20, 2019
bad6fc5
Parameter Binding에서 HttpSession객체 만들 때 쿠키값 넣어지도록 구현
leejh903 Jan 20, 2019
316612f
bidning parameter에서 버그발견 - 파라미터의 필드에 따르는게 아니라 쿼리 필드명에 따라 파라미터 타입 결정해야함
leejh903 Jan 20, 2019
30abf3e
parameter binding 버그 에러 해결
leejh903 Jan 20, 2019
48c880a
Requirement5. login function completed
leejh903 Jan 20, 2019
20b2eed
queryValue가 없을때 MappingHandler 내 isValidForQuery() 통과하는 버그 수정
leejh903 Jan 20, 2019
750ab3b
HomeController 추가 - / 접속시 index.html 매핑
leejh903 Jan 20, 2019
d9a553a
ContentLength 사이즈 mismatch로 인해 발생하는 오류로 인해 if-else구문 이용
leejh903 Jan 20, 2019
e0f010b
하드코딩으로 UserList 치환 구현 - 이후 수정 필요
leejh903 Jan 20, 2019
11152c2
css 반영되도록 수정 - 여전히css가 적용이 되었다가 안되었다가, js파일 적용되었다가 안되었다가 왔다갔다함
leejh903 Jan 20, 2019
562d74f
테스트가 통과되도록 수정
leejh903 Jan 20, 2019
06fea46
파일 경로 정리
leejh903 Jan 20, 2019
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
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ repositories {
}

dependencies {
compile('org.reflections:reflections:0.9.10')
compile('com.google.guava:guava:27.0-jre')
compile('ch.qos.logback:logback-classic:1.2.3')
compile('org.apache.commons:commons-dbcp2:2.5.0')
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/codesquad/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package codesquad;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
}

17 changes: 17 additions & 0 deletions src/main/java/codesquad/RequestMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package codesquad;

import codesquad.model.RequestMethod;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {

String value() default "";

RequestMethod method() default RequestMethod.GET;
}
14 changes: 14 additions & 0 deletions src/main/java/codesquad/controller/HomeController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package codesquad.controller;

import codesquad.Controller;
import codesquad.RequestMapping;
import codesquad.model.RequestMethod;

@Controller
public class HomeController {

@RequestMapping(value = "/", method = RequestMethod.GET)
public String home() {
return "/index.html";
}
}
43 changes: 43 additions & 0 deletions src/main/java/codesquad/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package codesquad.controller;

import codesquad.Controller;
import codesquad.RequestMapping;
import codesquad.model.HttpSession;
import codesquad.model.RequestMethod;
import codesquad.model.User;
import codesquad.service.UserService;
import org.slf4j.Logger;

import static org.slf4j.LoggerFactory.getLogger;

@Controller
public class UserController {
private static final Logger log = getLogger(UserController.class);

@RequestMapping(value = "/user/create", method = RequestMethod.POST)
public String create(User user) {
log.debug(user.toString());
UserService.create(user);
return "redirect:/index.html";
}

@RequestMapping(value = "/user/login", method = RequestMethod.POST)
public String login(User user, HttpSession session) {
log.debug(user.toString());
Copy link

Choose a reason for hiding this comment

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

우연찮게 저장소를 보게 되어서 의견을 남깁니다.

toString() 을 미리 호출하지 않는것이 디버거 레벨이 낮을 때 성능 향상에 도움이 됩니다.

slf4j 면 보통 아래와 같은 스타일로 많이 씁니다.

log.debug("login을 시도한 사용자 : {} " , user);

자세한 내용은 https://www.slf4j.org/faq.html#logging_performance 을 참조하실 수 있습니다.

try {
UserService.login(user);
session.setAttribute("logined", true);
return "redirect:/index.html";
} catch(Exception e) {
log.error(e.getMessage());
Copy link

Choose a reason for hiding this comment

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

에러 로깅에도 대체로 stacktrace를 다 남기는 것이 오류를 찾는데 도움이 됩니다.
예상한 오류가 있다면 catch절에 구체적인 Exception을 명시하는 것이 좋을것 같습니다.

Copy link

Choose a reason for hiding this comment

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

https://www.baeldung.com/slf4j-log-exceptions 을 참고하실수 있는데. log.error(..) 메서드 중에 Throwable을 넘길수 있는 것이 있습니다.

Copy link
Author

Choose a reason for hiding this comment

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

@benelog 소중한 의견 감사드립니다. 피드백에 반영할 수 있었습니다!

return "/user/login_failed.html";
}
}

@RequestMapping(value = "/user/list", method = RequestMethod.GET)
public String list(HttpSession session) {
log.debug(session.toString());
if(!session.getAttribute("logined").equals("true")) return "/user/login.html";
return "/user/list.html";
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package db;
package codesquad.db;

import java.util.Collection;
import java.util.Map;

import com.google.common.collect.Maps;

import model.User;
import codesquad.model.User;

public class UserRepository {

public class DataBase {
private static Map<String, User> users = Maps.newHashMap();

public static void addUser(User user) {
Expand All @@ -21,4 +22,11 @@ public static User findUserById(String userId) {
public static Collection<User> findAll() {
return users.values();
}

static {
// test data
users.put("brad903", new User("brad903", "1234", "brad", "brad903@naver.com"));
users.put("alex407", new User("alex407", "1234", "alex", "alex@naver.com"));
users.put("leejh903", new User("leejh903", "1234", "leejunghyun", "junghyun@naver.com"));
}
}
123 changes: 123 additions & 0 deletions src/main/java/codesquad/model/Header.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package codesquad.model;

import codesquad.util.HttpRequestUtils;
import codesquad.util.IOUtils;
import codesquad.model.responses.Response;
import codesquad.model.responses.ResponseCode;
import codesquad.webserver.ViewResolver;
import com.google.common.collect.Maps;
import org.slf4j.Logger;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static org.slf4j.LoggerFactory.getLogger;

public class Header {
private static final Logger log = getLogger(Header.class);

private Url url;

private int contentLength = 0;

private Map<String, String> cookie = Maps.newHashMap();

private boolean cookieModified = false;

private List<String> accept;

private ResponseCode responseCode = ResponseCode.OK;

public Header(Url url, Map<String, String> headers) {
this.url = url;
if (headers.containsKey("Accept")) this.accept = Arrays.asList(headers.get("Accept").split(","));
if (headers.containsKey("Content-Length")) contentLength = Integer.parseInt(headers.get("Content-Length"));
if (headers.containsKey("Cookie")) cookie = HttpRequestUtils.parseCookies(headers.get("Cookie"));
}

public void addCookie(HttpSession httpSession) {
cookieModified = true;
httpSession.putCookie(cookie);
}

public Response getResponse(Map<ResponseCode, Response> responses) {
return responses.get(responseCode);
}

public void generateResponseCode(Object result) {
String newAccessPath = (String) result;
if (newAccessPath.contains("redirect")) {
url.renewAccessPath(newAccessPath.split(":")[1]);
responseCode = ResponseCode.FOUND;
return;
}
url.renewAccessPath(newAccessPath);
}

public String writeCookie() {
if (cookie.isEmpty()) return "";
StringBuilder sb = new StringBuilder("Set-Cookie: ");
for (String key : cookie.keySet()) {
sb.append(key + "=" + cookie.get(key) + ";");
}
sb.append(" Path=/");
return sb.toString();
}

public boolean isCookieModified() {
return cookieModified;
}

public byte[] writeBody() throws IOException {
if (url.getAccessPath().equals("/user/list.html")) return ViewResolver.renewUserList();
return Files.readAllBytes(new File(url.generateFilePath()).toPath());
}

public Method findMappingMethod(Map<Url, Method> mappingHandler) {
return mappingHandler.get(this.url);
}

public String generateAccessPath() {
return this.url.generateAccessPath();
}

public void setBodyValue(BufferedReader br) throws IOException {
this.url.setQueryValue(IOUtils.readData(br, contentLength));
}

public boolean hasAllThoseFields(List<String> fields) {
return url.hasAllThoseFields(fields);
}

public Object bindingQuery(Object aInstance) {
return url.bindingQeury(aInstance);
}

public void putCookie(Map<String, Object> newCookie) {
for (String key : cookie.keySet()) {
newCookie.put(key, cookie.get(key));
}
}

@Override
public String toString() {
return "Header{" +
"url=" + url +
", contentLength=" + contentLength +
", cookie=" + cookie +
", cookieModified=" + cookieModified +
", accept=" + accept +
", responseCode=" + responseCode +
'}';
}

public boolean isCssFile() {
return this.accept.contains("text/css");
}
}
44 changes: 44 additions & 0 deletions src/main/java/codesquad/model/HttpSession.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package codesquad.model;

import com.google.common.collect.Maps;

import java.util.Map;

public class HttpSession {
Copy link
Contributor

Choose a reason for hiding this comment

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

세션을 이와 같이 구현할 경우 다수의 사용자별로 세션아이디를 발급하고 식별하는 것이 가능한가?


private Map<String, Object> newCookie;

public HttpSession() {
newCookie = Maps.newHashMap();
}

public void setAttribute(String key, Object value) {
newCookie.put(key, value);
}

public Object getAttribute(String key) {
return newCookie.getOrDefault(key, new Object());
}

public boolean hasValue() {
return !newCookie.isEmpty();
}

public void putCookie(Map<String, String> cookie) {
for (String key : newCookie.keySet()) {
cookie.put(key, newCookie.get(key).toString());
}
}

public Object addCookie(Header header) {
header.putCookie(newCookie);
return this;
}

@Override
public String toString() {
return "HttpSession{" +
"newCookie=" + newCookie +
'}';
}
}
16 changes: 16 additions & 0 deletions src/main/java/codesquad/model/RequestMethod.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package codesquad.model;

import java.util.Arrays;

public enum RequestMethod {
POST,
GET,
PUT,
DELETE;

static RequestMethod of(String requestMethod) {
return Arrays.stream(RequestMethod.values())
.filter(request -> request.toString().equals(requestMethod))
.findFirst().get();
}
}
Loading