본 포스팅은 프로그래머스 미니 데브 코스를 공부하며
학습을 기록하기 위한 목적으로 작성된 글입니다.
http://blog.example.com/entries/1
http://ranran:pass@blog.example.com:8080/search?q=test&debug=true
절대경로
/
로 시작
상대경로
/
- 루트
./
- 현재 위치
../
- 현재 위치의 상단 폴더
상대경로는현재 위치한 곳
을 기준으로 한 그곳의 위치
배포 시에는 상대경로를 사용하는 것이 좋다.
폴더일 수도 파일일 수도
특정 페이지일 수도 리소스일 수도
ASCII 문자가 아닌 문자를 사용할 경우 encode와 decode 처리가 필요하다.
HyperText Transfer Protocol
하이퍼텍스트를 교환하기 위해 만들어진 통신 규약 (하이퍼 텍스트 전송 프로토콜)
클라이언트 서버 프로토콜
HTTP는 URI로 조작대상을 지정해서, URI를 통해 가져온 리소스를 조작한다.
요청
클라이언트(웹 브라우저)가 OS자원을 이용해서 네트워크를 타고 호스트 서버에 요청을 보낸다.
응답
호스트 서버가 네트워크를 타고 OS의 커널에 보낸 응답(HTML)을 웹브라우저가 사용자의 화면에 렌더링해준다.
HTTP Messege Format
이미지 출처 : https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
헤더
와 바디
로 구성HTTP Headers
HTTP Body
리소스의 특정 행위를 취할 때
즉, HTML이란 연결성을 가지고 있는 마크업 언어이다.
Hypermedia System (하이퍼 미디어 시스템)
텍스트, 이미지, 음성 등 다양한 미디어들로 구성된 시스템
Distributed System (분산 시스템)
중앙집중 시스템 : 한 대의 컴퓨터가 모든 프로세스를 실행
분산 시스템 : 여러 대의 컴퓨터에 서버를 분산시킨다.
웹은 전세계에 배치된 서버에 전 세계의 브라우저가 접근할 수 있는 분산 시스템이다.
유저가 브라우저에 요청하면 브라우저 안에서 Frontend기술이 동작한다.
브라우저가 URL을 입력하고 리소스를 요청하면 앱에 대한 로직을 가지고 있는 웹 서버가
특정 리소스를 특정 OS의 file system에 접근해서 HTTP 프로토콜을 이용해 응답을 보낸다.
브라우저가 응답받은 리소스를 확인하고 헤더의 스크립트 코드 확인,
HTML에 의한 랜더링이 시작되면서 CSS에 의해 화면이 그려진다.
그렇게 랜더링 결과를 사용자가 볼 수 있게 된다.
(+ HTTP 프로토콜은 TCP / IP 위에 있다. 네트워크는 모두 TCP / IP 로 연결됨)
아키텍처 자세히 뜯어보기
출처 : https://litslink.com/blog/web-application-architecture
DNS
Load Balancer
Web App Servers(WAS)
Databases
Caching Service
Job Queue (optional) & Job Severs
Full-Text Search Service (optional)
Services
Data Warehouse
클라우드 스토리지
CDN
차이점 - 동적 컨텐츠를 지원하는가?
이미지 출처 : http://setgetweb.com/p/WAS9/ae/was3532.html
이미지 출처 : https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html
- Web Server에서 Http 요청이 발생한다 ->
- Web Container의 Servlet을 구동시킨다 ->
- DB Connection이 일어난다 ->
- 응답을 이용한 JSP페이지 or JSON를 생성해서 응답을 전달한다
- 웹 어플리케이션을 만들면 빌드 후 WAS에 deploy한다.
- WAS는 별도의 서버로 구동한다. (Ex: Tomcat, jetty)
- 물리적인 서버에 설치하고 WAS를 구동시킨다. (?)
- WAS를 .war 로 빌드하고 deploy -> WAS가 load된다. (?)
- 핵심 : Tomcat등의 WAS에 어플리케이션을 load한다.
+ 국내 상용 WAS : 티맥스의 제우스
동적 웹 페이지(Dynamic Web Page)를 만들 때 사용되는 자바 기반의 웹 애플리케이션 프로그래밍 기술.
서블릿 특징
서블릿 사용 흐름
서블릿 사용법
1. Container에 서블릿 등록
2. JSP 호출
RequestDispatcher
인스턴스를 이용해서 동적인 JSP 페이지를 제공할 수 있다.MVC 패턴이란?
서블릿에서의 MVC 패턴이란?
(Spring에서만 MVC 패턴을 지원하는 게 아니다~)
이미지 출처 : https://gmlwjd9405.github.io/2018/10/27/webserver-vs-was.html
Servlet의 Life Cycle 핵심
Web Service Architecture
알아두자!
spring-boot-starter-web
의존성 필요(레거시 코드 실습?)
💡 요청하는 순간 init 호출
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>test</servlet-name> <!-- 서블릿 이름 -->
<servlet-class>org.prgrms.kdt.servlet.TestServlet</servlet-class> <!-- 서블릿 클래스 -->
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/*</url-pattern> <!-- 매핑될 URL : 하위의 모든 경로을 서블릿에 매핑시킨다. -->
</servlet-mapping>
<servlet>
<servlet-name>order</servlet-name> <!-- 여러 개의 서블릿을 매핑 가능 -->
<servlet-class>org.prgrms.kdt.servlet.OrderServlet</servlet-class> <!-- 서블릿 클래스 -->
</servlet>
<servlet-mapping>
<servlet-name>order</servlet-name>
<url-pattern>/orders/*</url-pattern> <!-- 매핑될 URL : orders URL 패턴 하위의 모든 경로을 서블릿에 매핑시킨다. -->
</servlet-mapping>
</web-app>
// 서블릿
public class TestServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(TestServlet.class);
@Override
public void init() throws ServletException {
super.init(); // 서버 구동 확인 : init() 이 잘 호출되는지?
logger.info("Init Servlet");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 요청, 응답에 대한 파라미터 전달
var requestURI = req.getRequestURI();
logger.info("Got Request from {}", requestURI); // 요청이 올 때마다 로그 출력
var writer = resp.getWriter();
writer.println("Hello Servlet!");
}
}
// 로그
// 2022-08-05 20:40:20.105 INFO --- [nio-8080-exec-1] org.prgrms.kdt.servlet.TestServlet : Init Servlet
// 2022-08-05 20:40:20.121 INFO --- [nio-8080-exec-1] org.prgrms.kdt.servlet.TestServlet : Got Request from /kd_spring_order_war_exploded/
// 2022-08-05 20:40:20.240 INFO --- [nio-8080-exec-4] org.prgrms.kdt.servlet.TestServlet : Got Request from /kd_spring_order_war_exploded/
// 웹 페이지 URL에 입력하고 enter를 치면 HTTP GET 요청이 발생한다.
💡 요청을 받기 전에 미리 init
패스(경로)
", loadOnStartup = 1
)1
: 기본값. 요청을 받을 때 init-1
: 요청을 받기 전에 initweb.xml이 없으면 tomcat을 구동시켜도
WAS는 deploy가 없어도 모른다.?
WAS에게 알려주기 위한 어노테이션
// 서블릿
@WebServlet(value = "/*", loadOnStartup = -1)
public class TestServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(TestServlet.class);
@Override
public void init() throws ServletException {
super.init(); // 서버 구동 확인 : init() 이 잘 호출되는지?
logger.info("Init Servlet");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 요청, 응답에 대한 파라미터 전달
var requestURI = req.getRequestURI();
logger.info("Got Request from {}", requestURI); // 요청이 올 때마다 로그 출력
var writer = resp.getWriter();
writer.println("Hello Servlet!");
}
}
원리
그래서 ServletContainerInitializer를 직접 구현해도 되지만
WebApplicationInitializer을 구현해서 처리할 수도 있는 것이다.
public class KdtWebApplicationInitializer implements WebApplicationInitializer {
private static final Logger logger = LoggerFactory.getLogger(KdtWebApplicationInitializer.class);
// servletContext가 생성된다. WAS가 접근 가능
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
logger.info("Staring Server...");
var servletRegistration = servletContext.addServlet("test", new TestServlet());// 테스트 서블릿을 추가할 수 있다.
servletRegistration.addMapping("/*"); // 서블릿 매핑 시 넣었던 URL 패턴 입력
servletRegistration.setLoadOnStartup(1);
}
}
// 로그
// 2022-08-05 21:16:20.953 INFO --- [on(3)-127.0.0.1] o.p.k.s.KdtWebApplicationInitializer : Staring Server...
// 2022-08-05 21:16:20.994 INFO --- [on(3)-127.0.0.1] org.prgrms.kdt.servlet.TestServlet : Init Servlet
// [2022-08-05 09:16:21,013] Artifact kd-spring-order:war exploded: Artifact is deployed successfully
// [2022-08-05 09:16:21,013] Artifact kd-spring-order:war exploded: Deploy took 2,797 milliseconds
// 2022-08-05 21:16:21.347 INFO --- [nio-8080-exec-1] org.prgrms.kdt.servlet.TestServlet : Got Request from /kd_spring_order_war_exploded/
// 2022-08-05 21:16:21.478 INFO --- [nio-8080-exec-4] org.prgrms.kdt.servlet.TestServlet : Got Request from /kd_spring_order_war_exploded/
우리가 한 방식은 톰캣을 서버에 미리 설치해놓고 톰캣 구동 -> 톰캣에 war를 빌드하는 방식
remote면 war로 말아서 deploy
앞으로는 embedded Tomcat을 쓸 것이다.
legacy 어플리케이션에서는 WAS로 배포하기도
모던 아키텍쳐에서는 embedded Tomcat / embedded Survlet으로 말아서 jar로 배포하는 경우가 많다.
오류해결
새로 알게된 용어
- 토큰 : 인증 처리 시 필요
- REST란? “Representational State Transfer” 의 약자
자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다.
출처 : https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html- 수직확장과 수평확장
수평확장(Horizental Scaling), Scale Out - 장비를 추가해서 확장하는 방식 (서버 추가 )
수직확장(Vertical Scaling), Scale Up - 기존 하드웨어를 보다 높은 사양으로 업그레이드하는 것
출처 : https://tech.gluesys.com/blog/2020/02/17/storage_3_intro.html- JSP (JavaServer Pages )
Java 언어를 기반으로 하는 Server Side 스크립트 언어.
HTML 코드에 JAVA 코드를 넣어 동적 웹페이지를 생성하는 웹 어플리케이션 도구.
JSP를 통해 정적인 HTML과 동적으로 생성된 contents(HTTP 요청 파라미터)를 혼합하여 사용할 수 있다. 즉, 사용자가 입력한 contents에 맞게 동적인 웹 페이지를 생성한다
https://gmlwjd9405.github.io/2018/11/03/jsp.html
출처: https://javacpro.tistory.com/43, https://gmlwjd9405.github.io/2018/11/03/jsp.html- POJO
본래 자바의 장점을 살리는 '오래된' 방식의 '순수한' 자바객체
즉, 특정 '기술'에 종속되어 동작하는 것이 아닌 순수한 자바 객체를 의미한다.
출처 : https://siyoon210.tistory.com/120
TIP
- 기본은 80포트
- TCP는 비동기형 프로토콜이다.
- 브라우저가 URI를 통해 특정 리소스에 접근하면 HTTP프로토콜을 타고 서버에 있는 하이퍼 텍스트 리소스를 브라우저가 받아와서 랜더링한다. 하이퍼 텍스트 리소스에 링크가 있다면 또 다른 HTTP 프로토콜을 타고 또 다른 서버에 있는 리소스를 … 그런 흐름이다.
- URL은 URI의 서브셋이지만 URI와 URL의 가장 큰 차이점은 다음과 같다.
URI는 식별하고, URL은 위치를 가리킨다.
출처 : https://www.charlezz.com/?p=44767- Java Servlet은 현재 Jakarta Servlet이라는 이름으로 불린다.
- 서블릿의 동작 - 웹 브라우저에서 서버에 요청(Request)을 하면 Request(일반적으로 Http)에 맞는 동작을 수행하고 웹 브라우저에 HTTP형식으로 응답(Response)한다. 결과 : JSP 페이지.
JDBC에서 underline 작업에 대해서 몰라도 connection을 통해 DB를 조작할 수 있었던 것처럼
서블릿을 이용하면 WAS에서 실제 호출되는 과정을 몰라도 웹 브라우저의 요청과 응답에 대한 조작이 가능해진다.- 하나의 요청은 하나의 스레드 안에서 돌게 된다.
더 공부하면 좋을 포스팅
Rf