Skip to content

Commit 60af6d9

Browse files
committed
initial commit
1 parent 7e97b08 commit 60af6d9

32 files changed

+2126
-2
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/bin/
2+
/.settings/
3+
/target/
4+
/.classpath
5+
/.project
6+
/.idea
7+
*.iml
8+
.DS_Store

README.md

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,63 @@
1-
# java-was
2-
웹 애플리케이션 서버를 구현하는 실습
1+
# 웹 애플리케이션 서버
2+
## 웹 서버 시작 및 테스트
3+
* webserver.WebServer 는 사용자의 요청을 받아 RequestHandler에 작업을 위임하는 클래스이다.
4+
* 사용자 요청에 대한 모든 처리는 RequestHandler 클래스의 run() 메서드가 담당한다.
5+
* WebServer를 실행한 후 브라우저에서 http://localhost:8080으로 접속해 "Hello World" 메시지가 출력되는지 확인한다.
6+
7+
## 각 요구사항별 학습 내용 정리
8+
* 구현 단계에서는 각 요구사항을 구현하는데 집중한다.
9+
* 구현을 완료한 후 구현 과정에서 새롭게 알게된 내용, 궁금한 내용을 기록한다.
10+
* 각 요구사항을 구현하는 것이 중요한 것이 아니라 구현 과정을 통해 학습한 내용을 인식하는 것이 배움에 중요하다.
11+
12+
----
13+
## 코드 리뷰 과정
14+
> 저장소 브랜치에 자신의 github 아이디에 해당하는 브랜치가 존재해야 한다. 자신의 github 아이디에 해당하는 브랜치가 있는지 확인한다.
15+
>
16+
> 자신의 github 아이디에 해당하는 브랜치가 없는 경우 [브랜치 생성 요청](https://codesquad-members.slack.com/messages/C74HH4RJ8/) 채널을 통해 브랜치 생성을 요청한다.
17+
18+
----
19+
1. 프로젝트를 자신의 계정으로 fork한다. 저장소 우측 상단의 fork 버튼을 활용한다.
20+
21+
2. fork한 프로젝트를 자신의 컴퓨터로 clone한다.
22+
```
23+
git clone https://github.com/{본인_아이디}/{저장소 아이디}
24+
ex) https://github.com/javajigi/java-racingcar
25+
```
26+
27+
3. clone한 프로젝트 이동
28+
```
29+
cd {저장소 아이디}
30+
ex) cd java-racingcar
31+
```
32+
33+
4. 본인 아이디로 브랜치를 만들기 위한 checkout
34+
```
35+
git checkout -t origin/본인_아이디
36+
ex) git checkout -t origin/javajigi
37+
```
38+
39+
5. commit
40+
```
41+
git status //확인
42+
git rm 파일명 //삭제된 파일
43+
git add 파일명(or * 모두) // 추가/변경 파일
44+
git commit -m "메세지" // 커밋
45+
```
46+
47+
6. 본인 원격 저장소에 올리기
48+
```
49+
git push origin 본인_아이디
50+
ex) git push origin javajigi
51+
```
52+
53+
7. pull request
54+
* pull request는 github 서비스에서 진행할 수 있다.
55+
* pull request는 반드시 original 저장소의 브랜치와 fork한 자신의 저장소 브랜치 이름이 같아야 하며, 브랜치 이름은 자신의 github 아이디여야 한다.
56+
57+
8. code review 및 push
58+
* pull request를 통해 피드백을 받는다.
59+
* 코드 리뷰 피드백에 대한 개선 작업을 하고 다시 PUSH한다.
60+
61+
## 앞의 코드 리뷰 과정은 [영상 보기](https://youtu.be/ZSZoaG0PqLg) 를 통해 참고 가능
62+
63+
## 실습 중 모든 질문은 [웹백엔드 java 레벨4 채널](https://codesquad-members.slack.com/messages/C74DD7R7S/)에서...

pom.xml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>org.nhnnext</groupId>
5+
<artifactId>web-application-server</artifactId>
6+
<version>1.0</version>
7+
<packaging>jar</packaging>
8+
9+
<properties>
10+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
11+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
12+
</properties>
13+
14+
<dependencies>
15+
<!-- unit testing -->
16+
<dependency>
17+
<groupId>junit</groupId>
18+
<artifactId>junit</artifactId>
19+
<version>4.11</version>
20+
<scope>test</scope>
21+
</dependency>
22+
23+
<dependency>
24+
<groupId>com.google.guava</groupId>
25+
<artifactId>guava</artifactId>
26+
<version>18.0</version>
27+
</dependency>
28+
29+
<!-- logger -->
30+
<dependency>
31+
<groupId>ch.qos.logback</groupId>
32+
<artifactId>logback-classic</artifactId>
33+
<version>1.1.2</version>
34+
</dependency>
35+
</dependencies>
36+
37+
<build>
38+
<finalName>web-application-server</finalName>
39+
<sourceDirectory>src/main/java</sourceDirectory>
40+
<testSourceDirectory>src/test/java</testSourceDirectory>
41+
<testOutputDirectory>target/test-classes</testOutputDirectory>
42+
43+
<resources>
44+
<resource>
45+
<directory>src/main/resources</directory>
46+
</resource>
47+
</resources>
48+
49+
<plugins>
50+
<plugin>
51+
<artifactId>maven-eclipse-plugin</artifactId>
52+
<version>2.9</version>
53+
</plugin>
54+
<plugin>
55+
<groupId>org.apache.maven.plugins</groupId>
56+
<artifactId>maven-compiler-plugin</artifactId>
57+
<version>3.1</version>
58+
<configuration>
59+
<source>1.8</source>
60+
<target>1.8</target>
61+
<encoding>utf-8</encoding>
62+
</configuration>
63+
</plugin>
64+
<plugin>
65+
<groupId>org.apache.maven.plugins</groupId>
66+
<artifactId>maven-dependency-plugin</artifactId>
67+
<version>2.4</version>
68+
<executions>
69+
<execution>
70+
<id>copy-dependencies</id>
71+
<phase>package</phase>
72+
<goals>
73+
<goal>copy-dependencies</goal>
74+
</goals>
75+
</execution>
76+
</executions>
77+
</plugin>
78+
</plugins>
79+
</build>
80+
</project>

src/main/java/db/DataBase.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package db;
2+
3+
import java.util.Collection;
4+
import java.util.Map;
5+
6+
import com.google.common.collect.Maps;
7+
8+
import model.User;
9+
10+
public class DataBase {
11+
private static Map<String, User> users = Maps.newHashMap();
12+
13+
public static void addUser(User user) {
14+
users.put(user.getUserId(), user);
15+
}
16+
17+
public static User findUserById(String userId) {
18+
return users.get(userId);
19+
}
20+
21+
public static Collection<User> findAll() {
22+
return users.values();
23+
}
24+
}

src/main/java/model/User.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package model;
2+
3+
public class User {
4+
private String userId;
5+
private String password;
6+
private String name;
7+
private String email;
8+
9+
public User(String userId, String password, String name, String email) {
10+
this.userId = userId;
11+
this.password = password;
12+
this.name = name;
13+
this.email = email;
14+
}
15+
16+
public String getUserId() {
17+
return userId;
18+
}
19+
20+
public String getPassword() {
21+
return password;
22+
}
23+
24+
public String getName() {
25+
return name;
26+
}
27+
28+
public String getEmail() {
29+
return email;
30+
}
31+
32+
@Override
33+
public String toString() {
34+
return "User [userId=" + userId + ", password=" + password + ", name=" + name + ", email=" + email + "]";
35+
}
36+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package util;
2+
3+
import java.util.Arrays;
4+
import java.util.Map;
5+
import java.util.stream.Collectors;
6+
7+
import com.google.common.base.Strings;
8+
import com.google.common.collect.Maps;
9+
10+
public class HttpRequestUtils {
11+
/**
12+
* @param queryString은
13+
* URL에서 ? 이후에 전달되는 field1=value1&field2=value2 형식임
14+
* @return
15+
*/
16+
public static Map<String, String> parseQueryString(String queryString) {
17+
return parseValues(queryString, "&");
18+
}
19+
20+
/**
21+
* @param 쿠키
22+
* 값은 name1=value1; name2=value2 형식임
23+
* @return
24+
*/
25+
public static Map<String, String> parseCookies(String cookies) {
26+
return parseValues(cookies, ";");
27+
}
28+
29+
private static Map<String, String> parseValues(String values, String separator) {
30+
if (Strings.isNullOrEmpty(values)) {
31+
return Maps.newHashMap();
32+
}
33+
34+
String[] tokens = values.split(separator);
35+
return Arrays.stream(tokens).map(t -> getKeyValue(t, "=")).filter(p -> p != null)
36+
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
37+
}
38+
39+
static Pair getKeyValue(String keyValue, String regex) {
40+
if (Strings.isNullOrEmpty(keyValue)) {
41+
return null;
42+
}
43+
44+
String[] tokens = keyValue.split(regex);
45+
if (tokens.length != 2) {
46+
return null;
47+
}
48+
49+
return new Pair(tokens[0], tokens[1]);
50+
}
51+
52+
public static Pair parseHeader(String header) {
53+
return getKeyValue(header, ": ");
54+
}
55+
56+
public static class Pair {
57+
String key;
58+
String value;
59+
60+
Pair(String key, String value) {
61+
this.key = key.trim();
62+
this.value = value.trim();
63+
}
64+
65+
public String getKey() {
66+
return key;
67+
}
68+
69+
public String getValue() {
70+
return value;
71+
}
72+
73+
@Override
74+
public int hashCode() {
75+
final int prime = 31;
76+
int result = 1;
77+
result = prime * result + ((key == null) ? 0 : key.hashCode());
78+
result = prime * result + ((value == null) ? 0 : value.hashCode());
79+
return result;
80+
}
81+
82+
@Override
83+
public boolean equals(Object obj) {
84+
if (this == obj)
85+
return true;
86+
if (obj == null)
87+
return false;
88+
if (getClass() != obj.getClass())
89+
return false;
90+
Pair other = (Pair) obj;
91+
if (key == null) {
92+
if (other.key != null)
93+
return false;
94+
} else if (!key.equals(other.key))
95+
return false;
96+
if (value == null) {
97+
if (other.value != null)
98+
return false;
99+
} else if (!value.equals(other.value))
100+
return false;
101+
return true;
102+
}
103+
104+
@Override
105+
public String toString() {
106+
return "Pair [key=" + key + ", value=" + value + "]";
107+
}
108+
}
109+
}

src/main/java/util/IOUtils.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package util;
2+
3+
import java.io.BufferedReader;
4+
import java.io.IOException;
5+
6+
public class IOUtils {
7+
/**
8+
* @param BufferedReader는
9+
* Request Body를 시작하는 시점이어야
10+
* @param contentLength는
11+
* Request Header의 Content-Length 값이다.
12+
* @return
13+
* @throws IOException
14+
*/
15+
public static String readData(BufferedReader br, int contentLength) throws IOException {
16+
char[] body = new char[contentLength];
17+
br.read(body, 0, contentLength);
18+
return String.copyValueOf(body);
19+
}
20+
}

0 commit comments

Comments
 (0)