데브코스 백엔드 3기 33일차
월화!
Web, Servlet, SpringMVC 등을 배웠다
Web
인터넷 연결된 컴퓨터 통해 정보 공유하는 정보공간
- Web은 분산시스템 : 전세계에 배치된 서버에, 전세계의 브라우저가 access할 수 있음
- URI, HTTP, HTML : 웹기술을 쓸 수 있는 근간이 됨
- URI로 리소스 식별 -> HTTP 사용해서 접근해서 가져와서 조작 -> 랜더링하면 HTML
1. URI
웹에 존재하는 어떤 자원(Resource)에 접근하기 위한 유일한주소를 가진식별자
- 상대경로 : 내현재 위치 기준
- 절대경로 :
/
로 시작
2. Http
- Client - Server protocol
- 동기형 프로토콜 : 요청이 있으면 응답이 꼭 있음
- TCP/IP 기반
- stateless : 그 전 요청에 대한 상태 안남음
- Http method(GET, POST, PUT, DELETE) 통해서 Resource의 특정 행위를 취함
3. HTML
Hyper Text Markup Language
- 구조적 표현 + 태그 중심
Web Application Architecture
Web존재 - Web 위에 Web Application
- architecture : Web App을 구성하는 시스템간의 상호작용, 구성, 동작원리, 구성환경 등을 설명하는 설계도
사진출처
https://litslink.com/blog/web-application-architecture
- browser에서 도메인
- DNS에서 도메인에 해당하는 IP검색
- 해당하는 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
- WAS는 다양한 vendor가 만들 수 있음 -> Servlet spec에 맞게 모든 vendor가 개발(어떻게 보면 규약같은)
- HttpServlet 상속받아서 method들 구현해서 Servlet WAS가 http 요청 올 때 메소드들호출함
- 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
web.xml
통해서
1) WAS에게 TestServlet이 있다는 걸 알려주어야함
=> web.xml통해서 어떤 서블릿이 존재하는지 알려줌@WebServlet
annotationWebApplicationInitializer
구현(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일 1테코톡도 잘 진행되고 있다
임베디드 해놓으니까 넘 좋음
15분 내외라 회고 전에 딱 듣고 참여한다ㅋㅋ
훈팀 미팅!
-
무려 3시간도 넘게 했다..!(열정 무슨일이야)
각자의 코드를 보여주면서 질문도 하고 서로의 생각을 공유했다
이런거 넘 재미써
내 생각도 말하면서, 내가 잘못 알고 있진 않았는지도 알 수 있고
멘토님들도 있으니까 궁금하면 바로바로 물어볼 수 있다는게 너무 좋다!
궁금한건 참을수 없g
- 멘토님들은 늘 본인의 생각이 답이 아니라고 강조하셨다
그렇다하더라도 훨씬 넓게 생각한다는 점이 느껴졌고,
나 또한 의견을 들으면서 시야가 넓어지는듯해 좋다
- 메시지를 한 클래스에서만 사용하는데 상단에 상수화 시켜놓으니 코드가 지저분해보여서 Enum으로 관리했는데, 응집성이 떨어질까요?
- 지금도 좋습니다 property파일에 정리하는 방법도 있어요
- 입출력이 콘솔이 아닌 다른 곳에서 될 수도 있다고 생각해서 인터페이스를 사용했습니다 제가 생각한 방향에서 놓친 부분이 있을까요?
- 인터페이스로 만들게 되면 리턴값과 메소드명이 모두 동일하게 되는데, 콘솔이 아닌 다른것이 되었을 때 현재의 리턴값과 메소드명은 어색하다 생각합니다
- 인터페이스의 사용은 최대한 신중히 사용하는 것이 좋다고 생각합니다(팩토리메서드 제외하곤 거의 사용 X)
- getter 지양에 대한 의견이 궁금합니다
- 사람에 따라 다르겠지만 유연성이 있기 위해서는 제약이 많으면 안된다고 생각합니다 그런 의미에서 getter 사용에는 열린마음입니다
- Request가 너무 범용적이라고 생각됩니다. 실무에서는 어떤식으로 사용하나요?
- ㅎ님)제 회사의 경우도 여러 타입을 넣어두고, request, response 객체를 공유해서 쓰기도 합니다
- ㄷㅎ님) 제 회사의 경우 각각의 요청마다 다른 Request를 만들어 사용하고, Response는 공유해서 사용합니다