Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0570af3
chore: 학습 테스트 완료
unifolio0 Sep 4, 2024
74b6cba
feat: 1단계 구현
unifolio0 Sep 4, 2024
0327a97
feat: login 성공 시 index.html로 redirect 구현
unifolio0 Sep 4, 2024
2f07450
feat: login 성공 시 쿠키 설정하는 기능
unifolio0 Sep 4, 2024
a16adfa
feat: 쿠키가 있을 시 자동 로그인 기능 구현
unifolio0 Sep 5, 2024
fed02f6
fix: remove implementation logback-classic on gradle (#501)
geoje Sep 5, 2024
7e91356
fix: add threads min-spare configuration on properties (#502)
geoje Sep 5, 2024
1f85158
refactor: HttpRequest 클래스 분리
unifolio0 Sep 5, 2024
3666831
refactor: 메서드 분리
unifolio0 Sep 5, 2024
95f3203
refactor: 메서드 분리
unifolio0 Sep 5, 2024
e0adfe5
refactor: Controller 분리
unifolio0 Sep 5, 2024
5e975b0
refactor: 불필요한 코드 삭제
unifolio0 Sep 5, 2024
450414b
refactor: 불필요한 코드 삭제
unifolio0 Sep 5, 2024
15e8bfb
refactor: 메서드명 수정
unifolio0 Sep 5, 2024
8dc6953
refactor: requestLine 파싱 로직 이동
unifolio0 Sep 5, 2024
2e1b394
chore: 학습 테스트 완료
unifolio0 Sep 4, 2024
a3b0989
feat: 1단계 구현
unifolio0 Sep 4, 2024
70e07ce
feat: login 성공 시 index.html로 redirect 구현
unifolio0 Sep 4, 2024
d36c2f6
feat: login 성공 시 쿠키 설정하는 기능
unifolio0 Sep 4, 2024
9dd932d
feat: 쿠키가 있을 시 자동 로그인 기능 구현
unifolio0 Sep 5, 2024
640b619
refactor: HttpRequest 클래스 분리
unifolio0 Sep 5, 2024
f015d37
refactor: 메서드 분리
unifolio0 Sep 5, 2024
c36e04a
refactor: 메서드 분리
unifolio0 Sep 5, 2024
7fa779c
refactor: Controller 분리
unifolio0 Sep 5, 2024
2f23bfc
refactor: 불필요한 코드 삭제
unifolio0 Sep 5, 2024
8dc940e
refactor: 불필요한 코드 삭제
unifolio0 Sep 5, 2024
43cb5ba
refactor: 메서드명 수정
unifolio0 Sep 5, 2024
2b068a4
refactor: requestLine 파싱 로직 이동
unifolio0 Sep 5, 2024
5c9de83
Merge remote-tracking branch 'origin/step1' into step1
unifolio0 Sep 6, 2024
0d10b58
feat: 학습 테스트 통과
unifolio0 Sep 6, 2024
0b35ac0
refactor: 주석 삭제
unifolio0 Sep 6, 2024
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: 0 additions & 1 deletion study/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'ch.qos.logback:logback-classic:1.5.7'
implementation 'org.apache.commons:commons-lang3:3.14.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.1'
implementation 'pl.allegro.tech.boot:handlebars-spring-boot-starter:0.4.1'
Expand Down
26 changes: 21 additions & 5 deletions study/src/main/java/cache/com/example/GreetingController.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
package cache.com.example;

import java.io.IOException;
import java.io.OutputStream;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

@Controller
public class GreetingController {

@GetMapping("/")
public String index() {
return "index";
public ResponseEntity<StreamingResponseBody> index() {
StreamingResponseBody stream = new StreamingResponseBody() {
@Override
public void writeTo(OutputStream outputStream) throws IOException {
String htmlContent = "<html><body><h1>Hello, World!</h1></body></html>";
outputStream.write(htmlContent.getBytes());
outputStream.flush();
}
};

return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_VALUE)
.body(stream);
}

/**
Expand All @@ -25,16 +41,16 @@ public String cacheControl(final HttpServletResponse response) {
.cachePrivate()
.getHeaderValue();
response.addHeader(HttpHeaders.CACHE_CONTROL, cacheControl);
return "index";
return "index.html";
}

@GetMapping("/etag")
public String etag() {
return "index";
return "index.html";
}

@GetMapping("/resource-versioning")
public String resourceVersioning() {
return "resource-versioning";
return "resource-versioning.html";
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package cache.com.example.cachecontrol;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.WebContentInterceptor;

@Configuration
public class CacheWebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(final InterceptorRegistry registry) {
WebContentInterceptor interceptor = new WebContentInterceptor();
interceptor.addCacheMapping(CacheControl.noCache().cachePrivate(), "/");
registry.addInterceptor(interceptor);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package cache.com.example.etag;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.ShallowEtagHeaderFilter;

@Configuration
public class EtagFilterConfiguration {

// @Bean
// public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
// return null;
// }
@Bean
public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
FilterRegistrationBean<ShallowEtagHeaderFilter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new ShallowEtagHeaderFilter());
filterRegistrationBean.addUrlPatterns("/*"); // 모든 URL 패턴에 대해 적용
filterRegistrationBean.setName("etagFilter");
filterRegistrationBean.setOrder(1); // 필터 순서 설정

return filterRegistrationBean;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package cache.com.example.version;

import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

Expand All @@ -20,6 +22,10 @@ public CacheBustingWebConfig(ResourceVersion version) {
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler(PREFIX_STATIC_RESOURCES + "/" + version.getVersion() + "/**")
.addResourceLocations("classpath:/static/");
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS).cachePublic())
.resourceChain(true)
.addResolver(new org.springframework.web.servlet.resource.VersionResourceResolver()
.addContentVersionStrategy("/**"));
}
}
5 changes: 5 additions & 0 deletions study/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ server:
accept-count: 1
max-connections: 1
threads:
min-spare: 2
max: 2
compression:
enabled: true
mime-types: application/json,application/xml,text/html,text/xml,text/plain
min-response-size: 1024
10 changes: 10 additions & 0 deletions study/src/main/resources/static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html lang="ko">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
Hello, World!
</body>
</html>
11 changes: 11 additions & 0 deletions study/src/main/resources/static/resource-versioning.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE HTML>
<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="{{staticUrls '/js/index.js'}}"></script>
<title>Document</title>
</head>
<body>
html > head > script 태그의 src에 version 디렉터리가 생겼다.
</body>
</html>
31 changes: 19 additions & 12 deletions study/src/test/java/study/FileTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package study;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
* 웹서버는 사용자가 요청한 html 파일을 제공 할 수 있어야 한다.
Expand All @@ -28,7 +29,7 @@ class FileTest {
final String fileName = "nextstep.txt";

// todo
final String actual = "";
final String actual = getClass().getClassLoader().getResource(fileName).getFile();

assertThat(actual).endsWith(fileName);
}
Expand All @@ -44,11 +45,17 @@ class FileTest {
final String fileName = "nextstep.txt";

// todo
final Path path = null;

// todo
final List<String> actual = Collections.emptyList();

assertThat(actual).containsOnly("nextstep");
try {
final Path path = Path.of(getClass().getClassLoader().getResource(fileName).toURI());
// todo
try {
final List<String> actual = Files.newBufferedReader(path).lines().toList();
assertThat(actual).containsOnly("nextstep");
} catch (IOException e) {

}
} catch (URISyntaxException e) {

}
}
}
34 changes: 23 additions & 11 deletions study/src/test/java/study/IOStreamTest.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package study;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import java.io.*;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;

/**
* 자바는 스트림(Stream)으로부터 I/O를 사용한다.
* 입출력(I/O)은 하나의 시스템에서 다른 시스템으로 데이터를 이동 시킬 때 사용한다.
Expand Down Expand Up @@ -53,6 +61,7 @@ class OutputStream_학습_테스트 {
* todo
* OutputStream 객체의 write 메서드를 사용해서 테스트를 통과시킨다
*/
outputStream.write(bytes);

final String actual = outputStream.toString();

Expand All @@ -78,6 +87,7 @@ class OutputStream_학습_테스트 {
* flush를 사용해서 테스트를 통과시킨다.
* ByteArrayOutputStream과 어떤 차이가 있을까?
*/
outputStream.flush();

verify(outputStream, atLeastOnce()).flush();
outputStream.close();
Expand All @@ -96,6 +106,7 @@ class OutputStream_학습_테스트 {
* try-with-resources를 사용한다.
* java 9 이상에서는 변수를 try-with-resources로 처리할 수 있다.
*/
outputStream.close();

verify(outputStream, atLeastOnce()).close();
}
Expand Down Expand Up @@ -128,7 +139,7 @@ class InputStream_학습_테스트 {
* todo
* inputStream에서 바이트로 반환한 값을 문자열로 어떻게 바꿀까?
*/
final String actual = "";
final String actual = new String(inputStream.readAllBytes());

assertThat(actual).isEqualTo("🤩");
assertThat(inputStream.read()).isEqualTo(-1);
Expand All @@ -148,6 +159,7 @@ class InputStream_학습_테스트 {
* try-with-resources를 사용한다.
* java 9 이상에서는 변수를 try-with-resources로 처리할 수 있다.
*/
inputStream.close();

verify(inputStream, atLeastOnce()).close();
}
Expand All @@ -169,12 +181,12 @@ class FilterStream_학습_테스트 {
* 버퍼 크기를 지정하지 않으면 버퍼의 기본 사이즈는 얼마일까?
*/
@Test
void 필터인_BufferedInputStream를_사용해보자() {
void 필터인_BufferedInputStream를_사용해보자() throws IOException {
final String text = "필터에 연결해보자.";
final InputStream inputStream = new ByteArrayInputStream(text.getBytes());
final InputStream bufferedInputStream = null;
final InputStream bufferedInputStream = new BufferedInputStream(inputStream);

final byte[] actual = new byte[0];
final byte[] actual = bufferedInputStream.readAllBytes();

assertThat(bufferedInputStream).isInstanceOf(FilterInputStream.class);
assertThat(actual).isEqualTo("필터에 연결해보자.".getBytes());
Expand All @@ -197,15 +209,15 @@ class InputStreamReader_학습_테스트 {
* 필터인 BufferedReader를 사용하면 readLine 메서드를 사용해서 문자열(String)을 한 줄 씩 읽어올 수 있다.
*/
@Test
void BufferedReader를_사용하여_문자열을_읽어온다() {
void BufferedReader를_사용하여_문자열을_읽어온다() throws IOException {
final String emoji = String.join("\r\n",
"😀😃😄😁😆😅😂🤣🥲☺️😊",
"😇🙂🙃😉😌😍🥰😘😗😙😚",
"😋😛😝😜🤪🤨🧐🤓😎🥸🤩",
"");
final InputStream inputStream = new ByteArrayInputStream(emoji.getBytes());

final StringBuilder actual = new StringBuilder();
final StringBuilder actual = new StringBuilder(new String(inputStream.readAllBytes()));

assertThat(actual).hasToString(emoji);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class InMemoryUserRepository {
private static final Map<String, User> database = new ConcurrentHashMap<>();

static {
final User user = new User(1L, "gugu", "password", "hkkang@woowahan.com");
final User user = new User(1L, "gugu", "1", "hkkang@woowahan.com");
database.put(user.getAccount(), user);
}

Expand Down
32 changes: 32 additions & 0 deletions tomcat/src/main/java/org/apache/coyote/http11/ContentType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.apache.coyote.http11;

import java.util.Arrays;

public enum ContentType {

CSS("text/css;charset=utf-8", "css"),
JS("application/javascript;charset=utf-8", "js"),
HTML("text/html;charset=utf-8", "html"),
PNG("image/png", "png"),
JPG("image/jpeg", "jpeg")
;

private final String contentType;
private final String extention;

Choose a reason for hiding this comment

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

extension!


ContentType(String contentType, String extention) {
this.contentType = contentType;
this.extention = extention;
}

public String getContentType() {
return contentType;
}

public static ContentType getContentType(String extention) {
return Arrays.stream(values())
.filter(contentType1 -> contentType1.extention.equals(extention))
.findAny()
.orElseThrow();
}
}
Loading