데브코스 백엔드 3기 33일차

월화!
Web, Servlet, SpringMVC 등을 배웠다


Web

인터넷 연결된 컴퓨터 통해 정보 공유하는 정보공간

  • Web은 분산시스템 : 전세계에 배치된 서버에, 전세계의 브라우저가 access할 수 있음
  • URI, HTTP, HTML : 웹기술을 쓸 수 있는 근간이 됨
    • URI로 리소스 식별 -> HTTP 사용해서 접근해서 가져와서 조작 -> 랜더링하면 HTML


1. URI

웹에 존재하는 어떤 자원(Resource)에 접근하기 위한 유일한주소를 가진식별자

  • 상대경로 : 내현재 위치 기준
  • 절대경로 : /로 시작


2. Http

  1. Client - Server protocol
  2. 동기형 프로토콜 : 요청이 있으면 응답이 꼭 있음
  3. TCP/IP 기반
  4. stateless : 그 전 요청에 대한 상태 안남음


  • Http method(GET, POST, PUT, DELETE) 통해서 Resource의 특정 행위를 취함


3. HTML

Hyper Text Markup Language

  • 구조적 표현 + 태그 중심



Web Application Architecture

Web존재 - Web 위에 Web Application

  • architecture : Web App을 구성하는 시스템간의 상호작용, 구성, 동작원리, 구성환경 등을 설명하는 설계도

dd

사진출처
https://litslink.com/blog/web-application-architecture

  1. browser에서 도메인
  2. DNS에서 도메인에 해당하는 IP검색
  3. 해당하는 WebAppServer로 이동(Load Balancer가 요청 분산시켜줌)


  • 낯선 정보들
    • Caching Service에는 정보변할일이 거의 없는 데이터들 넣고
    • JobQueue는 오래걸리는일 넣어둠(ex) google drive에서 다운로드)
      -> 전문으로 하는 JobServer에 배치
      -> 압축 or 압축해제
      -> 다되면 알려줌(비동기)



Servlet

(Java Servlet -> Jakarta Servlet으로 이름 변경)
Http 요청에 대해서 특정한 기능을 수행하고 html 문서 생성 or dynamic web content 응답처리하는

사진출처
https://codeburst.io/understanding-java-servlet-architecture-b74f5ea64bf4

dd

rf

  • WAS는 다양한 vendor가 만들 수 있음 -> Servlet spec에 맞게 모든 vendor가 개발(어떻게 보면 규약같은)
  • HttpServlet 상속받아서 method들 구현해서 Servlet WAS가 http 요청 올 때 메소드들호출함


aa

  • Servlet은 WAS 올라가고 init 한번만 호출됨(WAS 올라갈 때 동시에 or 첫 요청 들어왔을 때)
    • 요청마다 Servlet instance 생성 아님
  • Multi-Thread 환경 : 요청에 해당하는 thread 생성 = 매 요청마다 다른 thread
  • Thread가 Servlet instance에 있는 service() 요청
  • doGet() or doPost() 호출
  • Client 요청 올 때마다 request를 handling


Servlet 생성방법

ex) TestServlet.java


  1. web.xml 통해서
    1) WAS에게 TestServlet이 있다는 걸 알려주어야함
    => web.xml통해서 어떤 서블릿이 존재하는지 알려줌
  2. @WebServlet annotation
  3. WebApplicationInitializer 구현(Spring이 제공해주는)
    1)WAS 올라갈 때 ServletContext를 만듬
    2) WAS가 claspath에 있는 모든 클래스 scan
    3) WebApplicationInitializer 구현체 있으면 인스턴스화해서 onStartUp() 호출
    4) ServletContext 접근할 수 있게 됨
    5) ServletContext에 Servlet 추가
  public class KdtWebApplicationInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) {
      var servletRegistration = servletContext.addServlet("test", new TestServlet());
      servletRegistration.addMapping("/*");
      servletRegistration.setLoadOnStartup(0);
    }
  }



Spring MVC

  • DispatcherServlet - RequestMapping, Handler Adapter - Handler(Controller) - DispatcherServlet - ViewResolver - DispatcherServlet

  • WebMVC에 관한 설정을 하고싶다 => imple WebMvcConfigurer
    => 하고나면 ViewResolver도 setup가능
  • ThymeleafViewResolver - SpringTemplateEngine - SpringResourceTemplateResolver


@Configuration
@EnableWebMvc
static class ServletConfig implements WebMvcConfigurer, ApplicationContextAware {

  ApplicationContext applicationContext;

  @Override
  public void configureViewResolvers(ViewResolverRegistry registry) {
      registry.jsp().viewNames("jsp/*");  //jsp, thymeleaf 둘 다 쓰기위해 네임

      var springResourceTemplateResolver = new SpringResourceTemplateResolver(); //SpringResourceTemplateResolver
      springResourceTemplateResolver.setApplicationContext(applicationContext);
      springResourceTemplateResolver.setPrefix("/WEB-INF/");
      springResourceTemplateResolver.setSuffix(".html");
      var springTemplateEngine = new SpringTemplateEngine();  //SpringTemplateEngine
      springTemplateEngine.setTemplateResolver(springResourceTemplateResolver);

      var thymeleafViewResolver = new ThymeleafViewResolver();  //ThymeleafViewResolver
      thymeleafViewResolver.setTemplateEngine(springTemplateEngine);
      thymeleafViewResolver.setOrder(1);
      thymeleafViewResolver.setViewNames(new String[]{"views/*"});
      registry.viewResolver(thymeleafViewResolver);
  }
  
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) { //정적인 컨텐츠
      registry.addResourceHandler("/resources/**")
              .addResourceLocations("/resources/")
              .setCachePeriod(60)
              .resourceChain(true)
              .addResolver(new EncodedResourceResolver()); //gzip형태로
  }
  
  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      this.applicationContext = applicationContext;
  }

}


Thyme-leaf

자바템플릿엔진

  • html을 템플릿이 파싱해줌
  • 요즘은 jsp, thymeleaf처럼 뷰랜더링해주는 것보다는 JSON등으로 뷰랜더링 안하는 추세


  • 타임리프문법
    • ${변수식}
    • {코드}
    • @{링크}
    • *{변수식} : 객체처럼 사용해서 중복코드 안쓸 수 있음


  • 오늘 Thyme-leaf와 tomcat으로 만든 페이지!
    사진은 바로바로 에버랜드! 그리워

제목 없음



오늘의 테코톡

  • 11/14 라라, 제로의 데이터베이스 인덱스
    • 특정기준으로 데이터를 정렬 => 검색 빠르게 가능(SELECT)
    • WHERE절을 통해 활용
    • INSERT(페이지분할), DELETE(사용안함 표시), UPDATE(DELETE 후 INSERT)
      • 오히려 성능저하
        -> SELECT나 WHERE, JOIN 적으면 오히려 인덱스가 없는편이 성능에 좋음
    • 클러스터링 인덱스 : 사전
      • 실제 데이터 자체가 정렬
      • 리프페이지가 데이터페이지
    • 논클러스터링 인덱스 : 별도의 찾아보기페이지
      • 실제 데이터페이지는 그대로
      • 별도의 인덱스페이지 생성(별도의 추가공간 필요, 테이블당 여러개 존재)
      • 리프 페이지에 실제 데이터페이지의 주소 담고있음
  • 11/15 봄의 AOP, Spring AOP
    • 저번주 금요일에 들은 AOP 강의를 복습하는 느낌이었다!



일기(회고)

훈팀’s Scrum Template!

훈팀노션1

  • 스크럼 템플릿을 만들었다!
    아주 마음에 든다
    우리팀 노션 마스터 ㅊㄱ!



훈팀노션2

  • 보드가 연동이 되어있어서 각자 페이지에서 할일 적으면
    스크럼 페이지에서도 보인다



훈팀노션3

  • 1일 1테코톡도 잘 진행되고 있다
    임베디드 해놓으니까 넘 좋음
    15분 내외라 회고 전에 딱 듣고 참여한다ㅋㅋ



훈팀 미팅!

  • 무려 3시간도 넘게 했다..!(열정 무슨일이야)
    각자의 코드를 보여주면서 질문도 하고 서로의 생각을 공유했다
    이런거 넘 재미써
    내 생각도 말하면서, 내가 잘못 알고 있진 않았는지도 알 수 있고
    멘토님들도 있으니까 궁금하면 바로바로 물어볼 수 있다는게 너무 좋다!
    궁금한건 참을수 없g

    1114


  • 멘토님들은 늘 본인의 생각이 답이 아니라고 강조하셨다
    그렇다하더라도 훨씬 넓게 생각한다는 점이 느껴졌고,
    나 또한 의견을 들으면서 시야가 넓어지는듯해 좋다


  • 메시지를 한 클래스에서만 사용하는데 상단에 상수화 시켜놓으니 코드가 지저분해보여서 Enum으로 관리했는데, 응집성이 떨어질까요?
    • 지금도 좋습니다 property파일에 정리하는 방법도 있어요
  • 입출력이 콘솔이 아닌 다른 곳에서 될 수도 있다고 생각해서 인터페이스를 사용했습니다 제가 생각한 방향에서 놓친 부분이 있을까요?
    • 인터페이스로 만들게 되면 리턴값과 메소드명이 모두 동일하게 되는데, 콘솔이 아닌 다른것이 되었을 때 현재의 리턴값과 메소드명은 어색하다 생각합니다
    • 인터페이스의 사용은 최대한 신중히 사용하는 것이 좋다고 생각합니다(팩토리메서드 제외하곤 거의 사용 X)
  • getter 지양에 대한 의견이 궁금합니다
    • 사람에 따라 다르겠지만 유연성이 있기 위해서는 제약이 많으면 안된다고 생각합니다 그런 의미에서 getter 사용에는 열린마음입니다
  • Request가 너무 범용적이라고 생각됩니다. 실무에서는 어떤식으로 사용하나요?
    • ㅎ님)제 회사의 경우도 여러 타입을 넣어두고, request, response 객체를 공유해서 쓰기도 합니다
    • ㄷㅎ님) 제 회사의 경우 각각의 요청마다 다른 Request를 만들어 사용하고, Response는 공유해서 사용합니다


업데이트: