Skip to content

Commit ca8b8a7

Browse files
authored
[톰캣 구현하기 3, 4단계] 키아라(김도희) 미션 제출합니다 (#487)
* feat: 휴리스틱 캐싱 제거하기 * feat: HTTP Compression 설정하기 * feat: ETag/If-None-Match 적용하기 * feat: 캐시 무효화(Cache Busting) * refactor: http 요청 응답 클래스명 변경 * refactor: 세션id로 유저 가져오는 기능 구현 * refactor: 응답 디폴트 지정 및 바디 호출 기능 분리 * refactor: AbstractController 상속하도록 구현 * test: ThreadPoolsTest 통과하도록 변경 * feat: Executors로 Thread Pool 적용 * feat: 동시성 컬렉션 사용하기 * refactor: FileReader 패키지 이동 * refactor: RequestBody 확장성 열어두기 * test: 테스트 코드 수정
1 parent 1f443e1 commit ca8b8a7

File tree

27 files changed

+432
-289
lines changed

27 files changed

+432
-289
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package cache.com.example.cachecontrol;
2+
3+
import org.springframework.http.CacheControl;
4+
import org.springframework.web.servlet.HandlerInterceptor;
5+
6+
import javax.servlet.http.HttpServletRequest;
7+
import javax.servlet.http.HttpServletResponse;
8+
9+
import static org.springframework.http.HttpHeaders.CACHE_CONTROL;
10+
11+
public class CacheControlInterceptor implements HandlerInterceptor {
12+
13+
@Override
14+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
15+
CacheControl cacheControl = CacheControl.noCache().cachePrivate();
16+
String cacheControlValue = cacheControl.getHeaderValue();
17+
response.addHeader(CACHE_CONTROL, cacheControlValue);
18+
return true;
19+
}
20+
}

study/src/main/java/cache/com/example/cachecontrol/CacheWebConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package cache.com.example.cachecontrol;
22

3+
import org.springframework.context.annotation.Bean;
34
import org.springframework.context.annotation.Configuration;
45
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
56
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -9,5 +10,11 @@ public class CacheWebConfig implements WebMvcConfigurer {
910

1011
@Override
1112
public void addInterceptors(final InterceptorRegistry registry) {
13+
registry.addInterceptor(cacheControlInterceptor()).addPathPatterns("/**");
14+
}
15+
16+
@Bean
17+
public CacheControlInterceptor cacheControlInterceptor() {
18+
return new CacheControlInterceptor();
1219
}
1320
}
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
package cache.com.example.etag;
22

3+
import org.springframework.boot.web.servlet.FilterRegistrationBean;
4+
import org.springframework.context.annotation.Bean;
35
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.web.filter.ShallowEtagHeaderFilter;
47

58
@Configuration
69
public class EtagFilterConfiguration {
710

8-
// @Bean
9-
// public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
10-
// return null;
11-
// }
11+
@Bean
12+
public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
13+
final var registration = new FilterRegistrationBean<>(new ShallowEtagHeaderFilter());
14+
registration.addUrlPatterns("/etag");
15+
registration.addUrlPatterns("/resources/*");
16+
return registration;
17+
}
1218
}

study/src/main/java/cache/com/example/version/CacheBustingWebConfig.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
import org.springframework.beans.factory.annotation.Autowired;
44
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.http.CacheControl;
56
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
67
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
78

9+
import java.time.Duration;
10+
811
@Configuration
912
public class CacheBustingWebConfig implements WebMvcConfigurer {
1013

@@ -20,6 +23,7 @@ public CacheBustingWebConfig(ResourceVersion version) {
2023
@Override
2124
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
2225
registry.addResourceHandler(PREFIX_STATIC_RESOURCES + "/" + version.getVersion() + "/**")
26+
.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)).cachePublic())
2327
.addResourceLocations("classpath:/static/");
2428
}
2529
}

study/src/main/resources/application.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ server:
77
max-connections: 1
88
threads:
99
max: 2
10+
compression:
11+
enabled: true
12+
min-response-size: 10

study/src/test/java/thread/stage0/ThreadPoolsTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ void testNewFixedThreadPool() {
3131
executor.submit(logWithSleep("hello fixed thread pools"));
3232

3333
// 올바른 값으로 바꿔서 테스트를 통과시키자.
34-
final int expectedPoolSize = 0;
35-
final int expectedQueueSize = 0;
34+
final int expectedPoolSize = 2;
35+
final int expectedQueueSize = 1;
3636

3737
assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize());
3838
assertThat(expectedQueueSize).isEqualTo(executor.getQueue().size());
@@ -46,7 +46,7 @@ void testNewCachedThreadPool() {
4646
executor.submit(logWithSleep("hello cached thread pools"));
4747

4848
// 올바른 값으로 바꿔서 테스트를 통과시키자.
49-
final int expectedPoolSize = 0;
49+
final int expectedPoolSize = 3;
5050
final int expectedQueueSize = 0;
5151

5252
assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize());
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package nextstep.jwp.exception;
2+
3+
public class ResourceNotFoundException extends RuntimeException {
4+
5+
public ResourceNotFoundException(Exception e) {
6+
super(e);
7+
}
8+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package nextstep.jwp.presentation;
2+
3+
import org.apache.coyote.http11.request.HttpRequest;
4+
import org.apache.coyote.http11.response.HttpResponse;
5+
6+
import static org.apache.coyote.http11.Method.*;
7+
8+
public abstract class AbstractController implements Controller {
9+
10+
@Override
11+
public HttpResponse service(HttpRequest httpRequest, HttpResponse httpResponse) {
12+
13+
if (GET.matches(httpRequest.getMethod())) {
14+
return doGet(httpRequest, httpResponse);
15+
}
16+
if (POST.matches(httpRequest.getMethod())) {
17+
return doPost(httpRequest, httpResponse);
18+
}
19+
throw new IllegalArgumentException("지원하지 않는 HTTP Method 입니다.");
20+
}
21+
22+
protected abstract HttpResponse doGet(HttpRequest httpRequest, HttpResponse httpResponse);
23+
24+
protected abstract HttpResponse doPost(HttpRequest httpRequest, HttpResponse httpResponse);
25+
}
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package nextstep.jwp.presentation;
22

3-
import org.apache.coyote.http11.request.RequestReader;
4-
import org.apache.coyote.http11.response.Response;
5-
6-
import java.io.IOException;
3+
import org.apache.coyote.http11.request.HttpRequest;
4+
import org.apache.coyote.http11.response.HttpResponse;
75

86
public interface Controller {
97

10-
Response service(RequestReader requestReader) throws IOException;
8+
HttpResponse service(HttpRequest httpRequest, HttpResponse httpResponse);
119
}

tomcat/src/main/java/nextstep/jwp/presentation/ControllerType.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
public enum ControllerType {
66

7-
MAIN("/", new MainController()),
8-
LOGIN("/login.html", new LoginController()),
9-
REGISTER("/register.html", new RegisterController()),
10-
INDEX("/index.html", new IndexController()),
7+
MAIN("/", MainController.getInstance()),
8+
LOGIN("/login.html", LoginController.getInstance()),
9+
REGISTER("/register.html", RegisterController.getInstance()),
10+
INDEX("/index.html", IndexController.getInstance()),
1111
;
1212

1313
private final String requestUri;
@@ -24,6 +24,6 @@ public static Controller findController(String requestUri) {
2424
.filter(findController -> findController.requestUri.equals(requestUri))
2525
.findFirst()
2626
.map(findController -> findController.controller)
27-
.orElse(new OtherController());
27+
.orElse(OtherController.getInstance());
2828
}
2929
}

0 commit comments

Comments
 (0)