Web Application
Web Server
์ ์ ๋ฆฌ์์ค(HTML, CSS, JS, Img, Video ..) ์ ๊ณต
Web Application Server (WAS)
Web server ๊ธฐ๋ฅ ํฌํจ + ์ ์ ๋ฆฌ์์ค
Application Logic ์ํ
๋์ HTML, REST API, Servlet, JSP, Spring MVC
Web System
Client -> Web Server -> WAS -> DB
WAS์ ์๋ฒ ๊ณผ๋ถํ ๋ฌธ์ ํด๊ฒฐ
Web Server ์์ ์ ์ ๋ฆฌ์์ค ์ฒ๋ฆฌ
WAS ์์๋ Application Logic ๋์ ์ฒ๋ฆฌ
ํจ์จ์ ์ธ ๋ฆฌ์์ค ๊ด๋ฆฌ (ํ์์ ๋ฐ๋ผ ์๋ฒ ์ฆ์ค)
Servlet
Servlet
urlPatterns์ URL์ด ํธ์ถ๋๋ฉด ์๋ธ๋ฆฟ ์ฝ๋ ์คํ
HttpServletRequest ๋ก HTTP ์์ฒญ ์ ๋ณด๋ฅผ ํธ๋ฆฌํ๊ฒ ์ฌ์ฉ
HttpServletResponse ๋ก HTTP ์๋ต ์ ๋ณด๋ฅผ ํธ๋ฆฌํ๊ฒ ์ ๊ณต
Servlet Container
Servlet ์ ์ง์ํ๋ WAS
Servlet ๊ฐ์ฒด๋ฅผ ์์ฑ/์ด๊ธฐํ/ํธ์ถ/์ข
๋ฃํ๋ ์๋ช
์ฃผ๊ธฐ ๊ด๋ฆฌ
Servlet ๊ฐ์ฒด๋ ์ฑ๊ธํค์ผ๋ก ๊ด๋ฆฌ
JSP ๋ Servlet ์ผ๋ก ๋ณํ ๋์ด ์ฌ์ฉ
๋์ ์์ฒญ์ ์ํ ๋ฉํฐ ์ฐ๋ ๋ ์ฒ๋ฆฌ ์ง์
Multi Thread
Thread
Application ์ฝ๋๋ฅผ ํ๋ํ๋ ์์ฐจ์ ์ผ๋ก ์คํํ๋ ๊ฒ
Thread pool
ํ์ํ Thread ๋ฅผ Thread Pool ์ ๋ณด๊ดํ๊ณ ๊ด๋ฆฌ
Thread Pool ์ ์์ฑ ๊ฐ๋ฅํ Thread ์ ์ต๋์น๋ฅผ ๊ด๋ฆฌ
Tomcat default : ์ต๋ 200๊ฐ
WAS ์ฃผ์ ํ๋ ํฌ์ธํธ๋ Max Thread
๋๋ฌด ๋ฎ์ ๊ฒฝ์ฐ : ๋์ ์์ฒญ์ด ๋ง์ผ๋ฉด, ์๋ฒ ๋ฆฌ์์ค๋ ์ฌ์ ๋กญ์ง๋ง, ํด๋ฆฌ์ด์ธํธ๋ ์๋ต ์ง์ฐ
๋๋ฌด ๋์ ๊ฒฝ์ฐ : ๋์ ์์ฒญ์ด ๋ง์ผ๋ฉด, CPU, ๋ฉ๋ชจ๋ฆฌ ๋ฆฌ์์ค ์๊ณ์ ์ด๊ณผ๋ก ์๋ฒ ๋ค์ด
์ฅ์ ๋ฐ์ ์ : ํด๋ผ์ฐ๋์ผ ๊ฒฝ์ฐ ์๋ฒ๋ฅผ ๋๋ฆฐ ํ ํ๋, ์๋๋ฉด ๊ทธ๋ฅ ๋นกํ๋..
๊ฐ๋ฐ์๊ฐ Multi Thread ๊ด๋ จ ์ฝ๋๋ฅผ ์ ๊ฒฝ์ฐ์ง ์์๋ ๋จ (Multi Thread ์ ๋ํ ๋ถ๋ถ์ WAS๊ฐ ์ฒ๋ฆฌ)
๋จ, Max Thread ํ๋์ด ์ค์
์ฑ๋ฅ ํ
์คํธ Tool : nGrinder, Apache ab, JMeter
HTML, API, SSR, CSR
HTMl
Static Resources
HTML, CSS, JS, image, vedio ..
Web Browser โ Web Server โ Static Resources
HTML ํ์ด์ง
๋์ HTML ํ์ผ์ ์์ฑํด์ ์ ๋ฌ
Web Browser โ WAS (HTML) โ DB
HTML API
๋ฐ์ดํฐ(์ฃผ๋ก JSON) ์ ๋ฌ
Web Browser โ WAS (DATA) โ DB
Web/App Client, Server to Server
SSR
์๋ฒ์์ ์ต์ข
HTML์ ์์ฑํด์ ํด๋ผ์ด์ธํธ์ ์ ๋ฌ (์ฃผ๋ก ์ ์ ํ๋ฉด)
CSR
HTML ๊ฒฐ๊ณผ๋ฅผ Javascript๋ฅผ ์ฌ์ฉํด ์น ๋ธ๋ผ์ฐ์ ์์ ๋์ ์ผ๋ก ์์ฑํด์ ์ ์ฉ (Google Map, Gmail ..)
Servlet
Project
IntelliJ
JSP ์ฌ์ฉ์ ์ํด War Packaging ์ฌ์ฉ
Java ์ง์ ์คํ ์ค์
Preferences Build โ Execution โ Deployment Build Tools Gradle
Lombok ์ ์ฉ
Preferences โ plugin โ lombok
Preferences โ Annotation Processors โ Enable annotation processing check
HTTP ์์ฒญ ๋ฉ์์ง ๋ก๊ทธ ํ์ธ
application.properties
logging.level.org.apache.coyote.http11=debug
HttpServletRequest
HTTP Start Line ์กฐํ
private void printStartLine(HttpServletRequest request) {
System.out.println("request.getMethod() = " + request.getMethod()); //GET
System.out.println("request.getProtocal() = " + request.getProtocol()); // HTTP/1.1
System.out.println("request.getScheme() = " + request.getScheme()); //http
System.out.println("request.getRequestURL() = " + request.getRequestURL()); // http://localhost:8080/request-header
System.out.println("request.getRequestURI() = " + request.getRequestURI()); // request-header
System.out.println("request.getQueryString() = " + request.getQueryString()); // username=park
System.out.println("request.isSecure() = " + request.isSecure()); //https ์ฌ์ฉ ์ ๋ฌด
}
HTTP Header ํธ์ ์กฐํ
private void printHeaderUtils(HttpServletRequest request) {
System.out.println("[Host]");
System.out.println("request.getServerName() = " + request.getServerName()); //Host ํค๋
System.out.println("request.getServerPort() = " + request.getServerPort()); //Host ํค๋
System.out.println("[Accept-Language]");
request.getLocales().asIterator()
.forEachRemaining(locale -> System.out.println("locale = " + locale));
System.out.println("request.getLocale() = " + request.getLocale());
System.out.println("[cookie]");
if (request.getCookies() != null) {
for (Cookie cookie : request.getCookies()) {
System.out.println(cookie.getName() + ": " + cookie.getValue());
}
}
System.out.println("[Content]");
System.out.println("request.getContentType() = " + request.getContentType()); //Get Method ์ผ ๊ฒฝ์ฐ null
System.out.println("request.getContentLength() = " + request.getContentLength());
System.out.println("request.getCharacterEncoding() = " + request.getCharacterEncoding());
}
HTTP ๊ธฐํ ์ ๋ณด
private void printEtc(HttpServletRequest request) {
System.out.println("[Remote ์ ๋ณด]");
System.out.println("request.getRemoteHost() = " + request.getRemoteHost());
System.out.println("request.getRemoteAddr() = " + request.getRemoteAddr());
System.out.println("request.getRemotePort() = " + request.getRemotePort());
System.out.println("[Local ์ ๋ณด]");
System.out.println("request.getLocalName() = " + request.getLocalName());
System.out.println("request.getLocalAddr() = " + request.getLocalAddr());
System.out.println("request.getLocalPort() = " + request.getLocalPort());
}
HTTP Request Data
HTTP ์์ฒญ ๋ฉ์์ง๋ฅผ ํตํด ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ
Get(URL Query Parameter)
๋ฉ์์ง ๋ฐ๋ ์์ด URL ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํด์ ์ ๋ฌ
HTTP Message Body ๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฏ๋ก Content-type ์ด ์์
ex) ๊ฒ์, ํํฐ, ํ์ด์ง ...
/**
* http://localhost:8080/request-param?username=hello&age=20
*/
// ๋จ์ผ ํ๋ผ๋ฏธํฐ ์กฐํ
String username = request.getParameter("username");
// ํ๋ผ๋ฏธํฐ ์ด๋ฆ ๋ชจ๋ ์กฐํ
Enumeration<String> parameterNames = request.getParameterNames();
// ํ๋ผ๋ฏธํฐ๋ฅผ Map์ผ๋ก ์กฐํ
Map<String, String[]> parameterMap = request.getParameterMap();
// ๋ณต์ ํ๋ผ๋ฏธํฐ ์กฐํ
String[] usernames = request.getParameterValues("username");
Post(HTML Form)
HTTP Message Body ์ ๋ฐ์ดํฐ๋ฅผ ํฌํจํด์ ์ ๋ฌํ๋ฏ๋ก Content-type ์ ํฌํจ๋ ๋ฐ์ดํฐ ํ์์ ์ง์
ex) ํ์๊ฐ์
, ์ํ์ฃผ๋ฌธ, HTML Form ...
/**
* http://localhost:8080/basic/hello-form.html
*
* content-type: application/x-www-form-urlencoded
* message body: username=hello&age=20
*/
// URL Query Parameter ํ์๊ณผ ๋์ผํ๊ฒ ์กฐํ
String username = request.getParameter("username");
HTTP Message Body
HTTP message body ์ ๋ฐ์ดํฐ๋ฅผ ์ง์ ๋ด์์ ์์ฒญ
HTTP API ์์ ์ฃผ๋ก ์ฌ์ฉ(JSON, XML, TEXT)
๋ฐ์ดํฐ ํ์์ ์ฃผ๋ก JSON(POST, PUT, PATCH)
/**
* POST http://localhost:8080/request-body-string
*
* content-type: text/plain
* message body: hello
*/
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
response.getWriter().write("ok");
/**
* POST http://localhost:8080/request-body-json
*
* content-type: application/json
* message body: {"username": "hello", "age": 20}
*/
ServletInputStream inputStream = request.getInputStream();
String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
response.getWriter().write("ok");
HttpServletResponse
Status-line
response.setStatus(HttpServletResponse.SC_OK); //200
Content-type
// = response.setHeader("Content-Type", "text/plain;charset=utf-8");
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
Response-headers
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // ์บ์ ๋ฌดํจํ
response.setHeader("Pragma", "no-cache"); // ์บ์ ๋ฌดํจํ(๊ณผ๊ฑฐ ๋ฒ์ )
response.setHeader("my-header","hello");
Cookie
// = response.setHeader("Set-Cookie", "myCookie=good; Max-Age=600");
Cookie cookie = new Cookie("myCookie", "good");
cookie.setMaxAge(600); // sec
response.addCookie(cookie);
Redirect
// response.setStatus(HttpServletResponse.SC_FOUND); // 302
// response.setHeader("Location", "/basic/hello-form.html");
response.sendRedirect("/basic/hello-form.html");
Mmessage body
PrintWriter writer = response.getWriter();
writer.println("ok");
HTTP Response Data
HTTP ์๋ต ๋ฉ์์ง
๋จ์ ํ
์คํธ
response.getWriter().println("ok");
HTML
//Content-Type: text/html;charset=utf-8
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<body>");
writer.println(" <div>HTML Test</div>");
writer.println("</body>");
writer.println("</html>");
HTML API (MessageBody JSON)
//..
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Content-Type: application/json
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
HelloData data = new HelloData();
data.setUsername("kim");
data.setAge(20);
//Object to Json
//{"username":"kim","age":20}
String result = objectMapper.writeValueAsString(data);
response.getWriter().write(result);
}