Skip to content

Commit

Permalink
[톰캣 구현하기 1 & 2단계] 파워(송재백) 미션 제출합니다 (#348)
Browse files Browse the repository at this point in the history
* feat: httpRequest 구현

* feat: httpResponse 구현

* feat: HttpProcessor 구현

* chore: 학습 테스트

* feat: html 파일을 읽어오기위한 FileIOUtils 생성

* feat: servlet mapper를 통해서 컨트롤러를 선택할 수 있게 수정

* feat: post요청으로 회원가입 로그인을 수행하도록 구현

* feat: 세션 구현 및 로그인시 세션에 유저정보를 저장하게 구현

* feat: 모든 요청에 세션을 생성하지않고 특정 요청에만 세션을 생성할 수 있게 수정

* feat: 컨트롤러 중복 코드 제거 및 리펙터링

* feat: HttpRequest 생성자 분리 및 리팩터링

* feat: HttpResponse 순서대로 출력하기위해 LinkedHashMap사용

* feat: 접근제어자 등 리팩터링

* feat: 컨트롤러 중복코드 제거

* feat: isNotRedirect에서 NPE이 발생하는 문제 해결

* error: Http11Processor 클래스에 개행이 제대로 되지않는 문제 해결

* refactor: HttpHeaders 상수 클래스 생성

* feat: HttpServlet안에 로직을 넣기에는 경우에 수가 많아서 각 컨트롤러에서 뷰를 렌더링 하도록 수정

* refactor: sonarqube java:S2583 반영

* fix: session을 제대로 불러오지 못하는 문제 해결

* fix: 페이지를 제대로 랜더링 하지못하는 문제 해결

* feat: 테스트 추가 작성 및 리팩터링

* chore: 캐시 학습 테스트

* feat: RequestParam이 인코딩된 문자열을 읽을수있게 수정
  • Loading branch information
thdwoqor authored Sep 5, 2023
1 parent 68db530 commit 39596a2
Show file tree
Hide file tree
Showing 43 changed files with 1,130 additions and 144 deletions.
10 changes: 2 additions & 8 deletions study/src/main/java/cache/com/example/GreetingController.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package cache.com.example;

import javax.servlet.http.HttpServletResponse;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletResponse;

@Controller
public class GreetingController {

@GetMapping("/")
public String index() {
public String index(final HttpServletResponse response) {
return "index";
}

Expand All @@ -20,11 +19,6 @@ public String index() {
*/
@GetMapping("/cache-control")
public String cacheControl(final HttpServletResponse response) {
final String cacheControl = CacheControl
.noCache()
.cachePrivate()
.getHeaderValue();
response.addHeader(HttpHeaders.CACHE_CONTROL, cacheControl);
return "index";
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package cache.com.example.cachecontrol;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

Expand All @@ -9,5 +14,17 @@ public class CacheWebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(new HandlerInterceptor() {
@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response,
final Object handler)
throws Exception {
String cacheControl = CacheControl
.noCache()
.cachePrivate().getHeaderValue();
response.addHeader(HttpHeaders.CACHE_CONTROL, cacheControl);
return HandlerInterceptor.super.preHandle(request, response, handler);
}
});
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
package cache.com.example.etag;

import cache.com.example.version.ResourceVersion;
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;
// }
private final ResourceVersion version;

public EtagFilterConfiguration(final ResourceVersion version) {
this.version = version;
}

@Bean
public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
FilterRegistrationBean<ShallowEtagHeaderFilter> filterRegistrationBean = new FilterRegistrationBean<>(
new ShallowEtagHeaderFilter());
filterRegistrationBean.addUrlPatterns("/etag");
filterRegistrationBean.addUrlPatterns("/resources/"+version.getVersion()+"/js/*");
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,7 @@ public CacheBustingWebConfig(ResourceVersion version) {
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler(PREFIX_STATIC_RESOURCES + "/" + version.getVersion() + "/**")
.setCacheControl(CacheControl.maxAge(31536000L, TimeUnit.SECONDS).cachePublic())
.addResourceLocations("classpath:/static/");
}
}
4 changes: 4 additions & 0 deletions study/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ server:
max-connections: 1
threads:
max: 2
compression:
enabled: true
mime-types: text/html,text/plain,text/css,application/javascript,application/json
min-response-size: 10
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void testCompression() {
.expectHeader().valueEquals(HttpHeaders.TRANSFER_ENCODING, "chunked")
.expectBody(String.class).returnResult();

log.info(response.getResponseHeaders().toString());
log.info("response body\n{}", response.getResponseBody());
}

Expand All @@ -63,7 +64,6 @@ void testETag() {
.expectStatus().isOk()
.expectHeader().exists(HttpHeaders.ETAG)
.expectBody(String.class).returnResult();

log.info("response body\n{}", response.getResponseBody());
}

Expand Down
42 changes: 22 additions & 20 deletions study/src/test/java/study/FileTest.java
Original file line number Diff line number Diff line change
@@ -1,53 +1,55 @@
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.URI;
import java.net.URISyntaxException;
import java.net.URL;
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 파일을 제공 할 수 있어야 한다.
* File 클래스를 사용해서 파일을 읽어오고, 사용자에게 전달한다.
* 웹서버는 사용자가 요청한 html 파일을 제공 할 수 있어야 한다. File 클래스를 사용해서 파일을 읽어오고, 사용자에게 전달한다.
*/
@DisplayName("File 클래스 학습 테스트")
class FileTest {

/**
* resource 디렉터리 경로 찾기
*
* File 객체를 생성하려면 파일의 경로를 알아야 한다.
* 자바 애플리케이션은 resource 디렉터리에 HTML, CSS 같은 정적 파일을 저장한다.
* resource 디렉터리의 경로는 어떻게 알아낼 수 있을까?
* <p>
* File 객체를 생성하려면 파일의 경로를 알아야 한다. 자바 애플리케이션은 resource 디렉터리에 HTML, CSS 같은 정적 파일을 저장한다. resource 디렉터리의 경로는 어떻게 알아낼 수
* 있을까?
*/
@Test
void resource_디렉터리에_있는_파일의_경로를_찾는다() {
final String fileName = "nextstep.txt";

// todo
final String actual = "";

// https://parkadd.tistory.com/113
// https://whitecold89.tistory.com/9
URL resource = getClass().getClassLoader().getResource(fileName);
final String actual = resource.getFile();
assertThat(actual).endsWith(fileName);
}

/**
* 파일 내용 읽기
*
* 읽어온 파일의 내용을 I/O Stream을 사용해서 사용자에게 전달 해야 한다.
* File, Files 클래스를 사용하여 파일의 내용을 읽어보자.
* <p>
* 읽어온 파일의 내용을 I/O Stream을 사용해서 사용자에게 전달 해야 한다. File, Files 클래스를 사용하여 파일의 내용을 읽어보자.
*/
@Test
void 파일의_내용을_읽는다() {
void 파일의_내용을_읽는다() throws URISyntaxException, IOException {
final String fileName = "nextstep.txt";

// todo
final Path path = null;
URI uri = getClass().getClassLoader().getResource(fileName).toURI();
final Path path = Path.of(uri);

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

assertThat(actual).containsOnly("nextstep");
}
Expand Down
Loading

0 comments on commit 39596a2

Please sign in to comment.