-
Notifications
You must be signed in to change notification settings - Fork 47
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
Step1 구현하기 #34
Changes from all commits
6794a83
2ea81f4
e5e74e9
3579360
e16122e
52f49ae
93a53c9
85e06b9
cab1c56
bcffce4
c611281
1991f2a
9d37ac8
aa97f94
ba96bdd
38b2cd0
07c70e6
d8fe9c5
8eb2f11
bad6fc5
316612f
30abf3e
48c880a
20b2eed
750ab3b
d9a553a
e0f010b
11152c2
562d74f
06fea46
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 { | ||
} | ||
|
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; | ||
} |
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"; | ||
} | ||
} |
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()); | ||
try { | ||
UserService.login(user); | ||
session.setAttribute("logined", true); | ||
return "redirect:/index.html"; | ||
} catch(Exception e) { | ||
log.error(e.getMessage()); | ||
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. 에러 로깅에도 대체로 stacktrace를 다 남기는 것이 오류를 찾는데 도움이 됩니다. 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. https://www.baeldung.com/slf4j-log-exceptions 을 참고하실수 있는데. 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. @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 |
---|---|---|
@@ -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"); | ||
} | ||
} |
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 { | ||
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. 세션을 이와 같이 구현할 경우 다수의 사용자별로 세션아이디를 발급하고 식별하는 것이 가능한가? |
||
|
||
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 + | ||
'}'; | ||
} | ||
} |
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(); | ||
} | ||
} |
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.
우연찮게 저장소를 보게 되어서 의견을 남깁니다.
toString()
을 미리 호출하지 않는것이 디버거 레벨이 낮을 때 성능 향상에 도움이 됩니다.slf4j 면 보통 아래와 같은 스타일로 많이 씁니다.
자세한 내용은 https://www.slf4j.org/faq.html#logging_performance 을 참조하실 수 있습니다.