Skip to content

Commit

Permalink
[1 - 2 단계 Tomcat 구현하기] 제리(김민정) 미션 제출합니다. (#569)
Browse files Browse the repository at this point in the history
* test: 파일, 입출력 스트림 학습 테스트

* docs: 1단계 요구사항 작성

* feat: 인덱스 페이지 응답

* fix: remove implementation logback-classic on gradle (#501)

* fix: add threads min-spare configuration on properties (#502)

* feat: 로그인 페이지 응답 및 회원 조회 로그 출력

* docs: 2단계 요구사항 작성

* feat: 로그인 시 302 반환 및 로그인 여부에 따라 다른 페이지 이동

* feat: 회원가입 페이지 응답 및 회원가입 요청 처리

* feat: 로그인 요청 메서드 변경

* feat: Cookie에 JSESSIONID 값 저장

* feat: Session 생성 및 로그인 상태로 로그인 페이지 접속 시 리다이렉트

* test: HTTP 활용하기 학습 테스트

* refactor: 중복되는 response 처리 코드 메서드화

* refactor: Session, SessionManager, Manager

- 매개변수 타입 수정, final 제거
- SessionManager 싱글톤 적용

* refactor: Request 객체 분리

- HeaderType, HttpCookies, RequestLine 생성

* refactor: Response 객체 분리

- StatusLine, Status 생성

* refactor: Request 내 protocolVersion, body 게터 추가

* refactor: Session 정적 팩터리 메서드 추가, SessionManager 메서드의 불필요한 예외 전파 제거

* refactor: Http11Processor 내 중복 로직 제거

* fix: 헤더 조회 메서드 오동작, 빈 request body 처리

* docs: 완료한 요구사항 체크

---------

Co-authored-by: Gyeongho Yang <[email protected]>
  • Loading branch information
mzeong and geoje authored Sep 11, 2024
1 parent 0b698a2 commit 7ba6940
Show file tree
Hide file tree
Showing 27 changed files with 797 additions and 134 deletions.
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
8 changes: 4 additions & 4 deletions study/src/main/java/cache/com/example/GreetingController.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package cache.com.example;

import jakarta.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 jakarta.servlet.http.HttpServletResponse;

@Controller
public class GreetingController {

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

/**
Expand All @@ -30,7 +29,8 @@ public String cacheControl(final HttpServletResponse response) {

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

return "index.html";
}

@GetMapping("/resource-versioning")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package cache.com.example.cachecontrol;

import static cache.com.example.version.CacheBustingWebConfig.PREFIX_STATIC_RESOURCES;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class CacheControlInterceptor implements HandlerInterceptor {

@Override
public void postHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView
) throws Exception {
if (!request.getRequestURI().startsWith(PREFIX_STATIC_RESOURCES)) {
response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, private");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ public class CacheWebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(new CacheControlInterceptor());
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package cache.com.example.etag;

import static cache.com.example.version.CacheBustingWebConfig.PREFIX_STATIC_RESOURCES;

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<>(new ShallowEtagHeaderFilter());
filterRegistrationBean.addUrlPatterns("/etag");
filterRegistrationBean.addUrlPatterns(PREFIX_STATIC_RESOURCES + "/*");
return filterRegistrationBean;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package cache.com.example.version;

import java.time.Duration;
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() + "/**")
.addResourceLocations("classpath:/static/");
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(Duration.ofDays(365)).cachePublic());
}
}
4 changes: 4 additions & 0 deletions study/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ server:
accept-count: 1
max-connections: 1
threads:
min-spare: 2
max: 2
compression:
enabled: true
min-response-size: 10
File renamed without changes.
49 changes: 27 additions & 22 deletions study/src/test/java/study/FileTest.java
Original file line number Diff line number Diff line change
@@ -1,54 +1,59 @@
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.BufferedReader;
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 java.util.Objects;
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 = "";
URL resource = getClass().getClassLoader().getResource(fileName);
final String actual = Objects.requireNonNull(resource).getFile();

assertThat(actual).endsWith(fileName);
}

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

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

try (BufferedReader bufferedReader = Files.newBufferedReader(path)) {
List<String> actual = bufferedReader.lines().toList();
assertThat(actual).containsOnly("nextstep");
} catch (Exception e) {
}

// todo
final List<String> actual = Collections.emptyList();
// final List<String> actual = Files.readLines(file, Charset.defaultCharset()); <- 나중에 해결 안 됨

assertThat(actual).containsOnly("nextstep");
// assertThat(actual).containsOnly("nextstep");
}
}
Loading

0 comments on commit 7ba6940

Please sign in to comment.