외부에서 서버에 있는 프로그램을 실행하려면 클라이언트인 브라우져와 서버인 WAS가 있어야 한다. 스프링에서 클래스를 원격프로그램으로 등록하고, 메서드를 URL과 맵핑하면 WAS인 톰캣이 자동으로 객체를 만들어서 사용할 수 있게 해준다.
구체적인 클래스 타입을 알지 못해도, 그 클래스의 이름만 가지고 정보(메서드, 타입, 변수 등등)에 접근할 수 있게 해주는 자바 API.
리소스에는 프로그램, 스트리밍같은 동적 리소스와 이미지, Html, Css, Js같은 정적 리소스가 있다.
클라이언트에서 서버(톰캣)에 요청을 보내면, 톰캣에서 이 요청을 받아서, 객체를 생성한다음 요쳥의 정보를 저장한다. 그리고 이 객체를 맵핑된 메서드에 매개변수로 제공한다.
역할에 따라 클라이언트와 서버를 구분한다.
클라이언트는 서비스를 서버에 요청하고, 서버에서 응답으로 받는 애플리케이션이고, 서버는 서비스를 클라이언트에 제공하는 애플리케이션이다.
서버의 종류는 어떤 서비스를 제공하는지에 따라 이메일서버, 파일서버, 웹서버 등으로 달라지고, 각 서버는 포트 번호로 구분된다. 하나의 서버에는 하나의 포트만 연결되므로, 한 대의 PC에 여러개의 서버가 존재해도, 포트번호로 구별할 수 있다.
서버가 요청을 받기 위해서는 먼저 서버와 포트가 binding 즉 연결 되어 있어야 하고, 요청을 기다리는 Listening 상태여야 한다.
WAS는 웹 애플리케이션을 서비스하는 서버 즉, 웹 프로그램을 서비스하는 서버이다. 서버에 프로그램을 설치해 놓고, 클라이언트가 이 프로그램을 사용할 수 있게 하는 것으로, 이를통해 클라이언트에서 원격으로 프로그램 호출이 가능하고, 업데이트 등의 유지보수에 유리하다.
톰캣은 Server, Service, Engine, Host, Context, Servlet으로 구성되어 있다. 서버에 요청이 들어오면 Server(톰캣)의 Thread Pool에서 미리 만들어놓은 쓰레드를 할당받고, Service의 Connector로 요청에 맞는 프로토콜을 연결한다. 그다음 Engine, Host, Context를 거쳐서 요청으로 받은 URL과 연결된 Servlet이 작업을 수행 후 클라이언트로 응답을 전달한다.
작은 서버 프로그램이란 뜻으로 컨트롤러와 같은 서버에서 실행되는 프로그램이다.
server.xml과 web.xml이 있다.
server.xml은 Tomcat 서버의 설정 파일로서, Server, Service, Engine, Host, Context의 설정이 들어있고, web.xml에는 DispatcherServlet같은 Servlet의 설정이 들어있다.
(톰캣 폴더의 파일을 스프링이 복사해서 사용)
<!-- Connector에서 포트번호 8080 --> 80으로 변경 -->
<Connector connectionTimeout="20000" port="80" protocol="HTTP/1.1" redirectPort="8443"/>
<!-- Engine은 여러 Host를 포함 가능. 그 중에서 어떤 Host를 default로 할 것인지 지정 할 수 있음 -->
<!-- 기본 설정은 아래처럼 localhost를 default로 지정 -->
<Engine defaultHost="localhost" name="Catalina">
<!-- Host의 appBase="webapps"는 Tomcat의 webapps폴더를 뜻함. -->
<!-- unpackWar="true"는 .war파일로 webapps에 배포를 하면, 자동으로 압축을 풀어라는 뜻 -->
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<!-- Context의 path="/ch2"는 context 경로, reloadable="true"는 변경되면 자동으로 리로드 해라는 뜻 -->
<Context docBase="ch2" path="/ch2" reloadable="true" source="org.eclipse.jst.jee.server:ch2"/></Host>
web.xml에서 원격프로그램 등록, URL맵핑을 하는 것 보다
주로 @Controller, @RequestMapping을 사용.
<!-- 원격프로그램 등록 -->
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- URL 맵핑 -->
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
서로 간의 통신을 위한 약속 또는 규칙으로, HTTP와 같이 주고 받을 데이터에 대한 형식을 정의한 것이다. 이를 통해 데이터를 해석할 수 있다.
텍스트 기반의 프로토콜로, 단순하고 읽기 쉽고, 커스텀 헤더를 추가해서 확장 가능하지만, 상태를 유지하지 않는 stateless이기 때문에 클라이언트의 정보를 저장할 수 없다. 이를 쿠키와 세션을 사용해서 보완 할 수 있다.
1xx는 Informational(정보교환), 2xx는 Success, 3xx는 Redirect, 4xx는 Client Error, 5xx는 Server Error
요청메세지와 응답메세지가 있고, 구조는 요청라인이나 상태라인, 헤더, 바디로 나눠진다.
클라이언트에서 서버로 보내는 메세지로, GET메서드와 POST메서드가 있다.
GET은 서버에서 리소스를 가져오는 것이다. 바디가 없이 쿼리스트링을 통해 데이터를 전달하고, 이를 통해 URL에 데이터가 노출되어서 보안에 불리하지만, 검색엔진의 검색단어 전송같은 데이터 공유에 유리하다.
POST는 서버에 데이터를 포스팅하는 것이다. 바디에 데이터를 넣어서 서버에 전달하고, 이를 통해 HTTPS(HTTP + TLS(암호화 프로토콜))를 사용 했을 때 보안에 유리하지만 데이터 공유에는 불리하다. 게시판의 회원가입, 로그인, 글쓰기 같은 곳에 사용된다.
텍스트파일은 문자만 저장되어있는 파일로, 사람이 읽을 수 있고, 바이너리파일은 문자와 숫자가 저장되어있는 이미지, 동영상같은 파일로, 사람이 읽을 수 없다. 바이너리파일을 HTTP 프로토콜로 보내는 방법은, MIME타입을 쓰고 바이너리파일을 그대로 넣거나, Base64를 써서 바이너리를 텍스트로 변환해서 전송하는 방법이 있다.
텍스트(HTML)로 바이너리 데이터를 전송하기 위해 고안되었고, Content-Type헤더에 데이터 타입을 적어서 사용한다.
바이너리 데이터를 텍스트로 변환할 때 사용한다. 64진법인 '0'~'9', 'A'~'Z', 'a'~'z', '+', '/' 총 64개의 문자로 구성되고, 이 64개의 문자는 2의 6승, 즉 6bit이므로 6bit씩 잘라서 변환한다. 모든 인코딩의 공통인 아스키는, 128개의 문자로 구성된 2의 7승인 7bit이고, 여기서 특수문자를 제외하면 6bit인 Base64가 된다. 따라서 Base64의 6bit는 모든 인코딩의 공통이므로, 서로 다른 OS간에 데이터 전송에 안전하지만, 사이즈가 커지는 단점이 있다.
//Reflection API사용 예시
//Hello클래스의 Class객체를 얻어온다.
Class clazz = Class.forName("com.fastcampus.ch2.Hello");
Hello hello = (Hello)clazz.newInstance(); //Class객체가 가진 정보로 객체 생성
Method main = clazz.getDeclaredMethod("main"); //main메서드를 참조
main.setAccessible(true); //private인 main()을 호출가능하게함.
main.invoke(hello); //hello.main()호출, invoke뜻: 부르다.
//URL을 msg로 보낼 때 사용.
request.getRequestURL()
//HttpServletRequest의 메서드
request.getRequestURL();
String year = request.getParameter("year");
Enumeration enum = request.getParameterNames();
Map paramMap = request.getParameterMap();
//name이 "year"인 keyset이 쿼리스트링에 여러개 있을 때 String 배열로 저장
String yearArr = request.getParameterValues("year");