[SERVER] TIL 045 - 23.09.15

유진·2023년 9월 15일
0
post-thumbnail

기본적인 웹서비스 개념

  • 웹서비스

    • 정적 서비스
      : 요청할때마다 항상 동일한 값만 보여주는 것(하드코딩된 html, css, js)
      : 웹서버 (ex. 아파치, Nginx, WAS(Web Application Server == Servlet Container) )
    • 동적 서비스(요즘 웹페이지)
      : 요청할때 보내는 값의 결과가 다르게 나타나는 것
      ex) localhost:8080?inputName = 홍길동 &
      : (ex. 톰캣)
      : 오늘날의 동적 서비스 = 동적 & 정적
  • 아파치 톰캣 == Web Application Server == Servlet Container


http://tomcat.apache.org/


-> 코드가 변하면 자동으로 새로고침
-> UTF-8 맞는지 확인

  • Servers = 프로젝트별 사용할 서버 설정하는 곳
    Next 2번 누르기
  • Context root = 최상위주소
  • Content directory = 웹배포폴더 배포 == 인터넷 올라감, 주소치면 화면 보임
    (배포시 필요한 파일만 모아둔 폴더-> html, css, js, jsp, .class,
  • web.xml 꼭 체크해야함 !!!!★
  • src/main/java
    = java 코드 작성할 파일들 모아둔 폴더(백엔드 폴더)
  • src/main/webapp (== Content directory)
    = 배포할 코드 작성 폴더(html, css, jsp, js, 이미지...)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  
  <!-- 
  	web.xml (배포 서술자(설명서))
  	Server가 켜지자 마자(Start) 제일 처음 읽는 문서
   -->
  
  
  
  <display-name>ServletProject</display-name>
  
  <!-- 메인페이지로 사용할 파일 명 목록 (webapp 폴더(배포해주는 파일)에 파일 생성) -->
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>default.htm</welcome-file>
  </welcome-file-list>
</web-app>

VSCode

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Servlet 프로젝트</title>
</head>
<body>
    <h1>이유진</h1>
    <h2>index 또는 default라는 이름의 html, jsp 파일은 메인 페이지 역할을 한다!</h2>
    <h3>web.xml 파일을 확인해라.</h3>

    <hr>

    <h1>서버 제출 테스트1</h1>
    <pre>
        이름과 나이를 입력받아서 서버(Java 코드)로 제출

        * 준비물 *
        1) form 태그 : 내부에 작성된 input 값을 지정된 경로로 제출
        - action : 제출할 경로
        - method : 제출 방법(GET/POST)
        제출 == 클라이언트 요청

        2) input 태그 : 값을 입력하는 양식 제공
        - name : 서버로 제출 시 key 역할
        - 입력된 값 또는 value : 서버로 제출 시 value 역할

        ?inputName=홍길동
        
        ** GET : Get을 통한 요청은 URL 주소 끝에 파라미터로 포함되어 전송되며,
        이부분을 query string 이라고 부른다.
        방식은 URL 끝에 "?"를 붙이고 그다음 변수명1=값1&변수명2=값2...
        ex) www.example.com/show?name1=value1&name2=value2
        -> 서버에서는 name1과 name2라는 파라미터 명으로 각각 value1과 value2
        파라미터 값을 전달받을 수 있다.

        [장점]
        - 단순함
        - 캐싱(caching, 저장) 가능
            -> 주소 저장 == 북마크, 즐겨찾기, 주소 공유

        [단점]
        - 글자수 제한이 있다.
        - 보안에 취약하다(비밀번호 주소에 보임..) <!-- POST : 보안에 강함 -->

    </pre>


    <form action="/example1" method="GET">
        이름 : <input name="inputName">
        <br>
        나이 : <input type="number" name="inputAge">
        <br>
        <button>서버로 제출하기(==요청하기)</button>
    </form>

    <hr>
    <h1>커피 주문하기</h1>


    <form action="/example2" method="get">
        주문자 : <input name="orderer">
        <br>

        <!-- option에 value 없으면 작성된 내용이 value -->
        커피 : <select name="coffee">
            <option>아메리카노</option>
            <option>카페라떼</option>
            <option>카푸치노</option>
            <option>콜드브루</option>
            <option>민트초코칩프라페</option>
        </select>

        <br><br>
        ICE <input type="radio" name="type" value="ICE">
        HOT <input type="radio" name="type" value="HOT">

        <br><br>
        옵션 <br>
        샷 추가 <input type="checkbox" name="opt" value="shot">
        <br>
        연하게 <input type="checkbox" name="opt" value="mild">

        <br><br>
        <button>주문하기</button>

    </form>

    <hr>

    <h1>POST 방식 요청 및 응답</h1>
    <pre>
        Get 방식과는 다르게
        전달되는 값을 주소가 아닌
        HTTP BODY에 담아서 전달하는 방식
        name1=value1&name2=value2
        json 타입이라면
        {
            "name1" : "value1" ,
            "name2" : "value2"
            ...
        }

        [장점]
        - 길이 제한 X
        - 데이터를 숨겨서 전달(보안성 향상)

        [단점]
        - 캐싱 불가능 (북마크 하면 원하는 페이지를 볼 수 없음)
        - 서버에서 추가적인 문자 인코딩 처리 필요

    </pre>

    <h3>회원가입</h3>

    <form action="/signUp" method="post">
        아이디 : <input type="text" name="inputId" required> <br>
        비밀번호 : <input type="password" name="inputPw" required> <br>
        비밀번호 확인 : <input type="password" required> <br>
        이름 : <input name="inputName" required> <br>
        
        자기소개 (선택) <br>
        <textarea name="intro" cols="50" rows="5"></textarea>

        <button>회원 가입</button>
    </form>
</body>
</html>



<!-- WEB-INF -> views
:클라이언트 쪽에서 직접적으로 주소를 쳐서 접근하는 것이 불가함
접근하려면 Controller를 거쳤다 와야 함
보안때문에 숨겨놓은 파일-->

result.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>회원가입결과</title>
</head>
<body>
    <!-- jsp 파일을 만들기 위한 준비단계 -->
    <h3 style="color: hotpink;">홍길동님의 가입을 환영합니다.</h3>

    <ul>
        <li>id : user01</li>
        <li>pw : pass01</li>
    </ul>

    <h4>자기소개</h4>
    <p>안녕하세요?</p>
</body>
</html>

result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>회원 가입 결과</title>
</head>
<body>
	<%-- JSP 주석
		(Spring에서도 똑같이 사용되기 때문에 스크립틀릿, 표현식 익숙해져야 함!)
		<% %> : 스크립틀릿 -> 자바코드 작성
		<%= %> : 표현식 -> 자바, 서버에서 받아온 값을 표현할 때, 출력
	--%>
	
	<h3 style="color: hotpink;"><%= request.getParameter("inputName") %>님의 가입을 환영합니다.</h3>

    <ul>
        <li>id : <%= request.getParameter("inputId") %></li>
        <li>pw : <%= request.getParameter("inputPw") %></li>
    </ul>

	<% if( !request.getParameter("intro").equals("") ) {%>
	<h4>자기소개</h4>
	<p>
		<%= request.getParameter("intro") %>
	</p>
	<% } %>
	
</body>
</html>

ECLIPSE

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Servlet 프로젝트</title>
</head>
<body>
    <h1>이유진</h1>
    <h2>index 또는 default라는 이름의 html, jsp 파일은 메인 페이지 역할을 한다!</h2>
    <h3>web.xml 파일을 확인해라.</h3>

    <hr>

    <h1>서버 제출 테스트1</h1>
    <pre>
        이름과 나이를 입력받아서 서버(Java 코드)로 제출

        * 준비물 *
        1) form 태그 : 내부에 작성된 input 값을 지정된 경로로 제출
        - action : 제출할 경로
        - method : 제출 방법(GET/POST)
        제출 == 클라이언트 요청

        2) input 태그 : 값을 입력하는 양식 제공
        - name : 서버로 제출 시 key 역할
        - 입력된 값 또는 value : 서버로 제출 시 value 역할

        ?inputName=홍길동
        
        ** GET : Get을 통한 요청은 URL 주소 끝에 파라미터로 포함되어 전송되며,
        이부분을 query string 이라고 부른다.
        방식은 URL 끝에 "?"를 붙이고 그다음 변수명1=값1&변수명2=값2...
        ex) www.example.com/show?name1=value1&name2=value2
        -> 서버에서는 name1과 name2라는 파라미터 명으로 각각 value1과 value2
        파라미터 값을 전달받을 수 있다.

        [장점]
        - 단순함
        - 캐싱(caching, 저장) 가능
            -> 주소 저장 == 북마크, 즐겨찾기, 주소 공유

        [단점]
        - 글자수 제한이 있다.
        - 보안에 취약하다(비밀번호 주소에 보임..) <!-- POST : 보안에 강함 -->

    </pre>


    <form action="/example1" method="GET">
        이름 : <input name="inputName">
        <br>
        나이 : <input type="number" name="inputAge">
        <br>
        <button>서버로 제출하기(==요청하기)</button>
    </form>

    <hr>
    <h1>커피 주문하기</h1>


    <form action="/example2" method="get">
        주문자 : <input name="orderer">
        <br>

        <!-- option에 value 없으면 작성된 내용이 value -->
        커피 : <select name="coffee">
            <option>아메리카노</option>
            <option>카페라떼</option>
            <option>카푸치노</option>
            <option>콜드브루</option>
            <option>민트초코칩프라페</option>
        </select>

        <br><br>
        ICE <input type="radio" name="type" value="ICE">
        HOT <input type="radio" name="type" value="HOT">

        <br><br>
        옵션 <br>
        샷 추가 <input type="checkbox" name="opt" value="shot">
        <br>
        연하게 <input type="checkbox" name="opt" value="mild">

        <br><br>
        <button>주문하기</button>

    </form>

    <hr>

    <h1>POST 방식 요청 및 응답</h1>
    <pre>
        Get 방식과는 다르게
        전달되는 값을 주소가 아닌
        HTTP BODY에 담아서 전달하는 방식
        name1=value1&name2=value2
        json 타입이라면
        {
            "name1" : "value1" ,
            "name2" : "value2"
            ...
        }

        [장점]
        - 길이 제한 X
        - 데이터를 숨겨서 전달(보안성 향상)

        [단점]
        - 캐싱 불가능 (북마크 하면 원하는 페이지를 볼 수 없음)
        - 서버에서 추가적인 문자 인코딩 처리 필요

    </pre>

    <h3>회원가입</h3>

    <form action="/signUp" method="post">
        아이디 : <input type="text" name="inputId" required> <br>
        비밀번호 : <input type="password" name="inputPw" required> <br>
        비밀번호 확인 : <input type="password" required> <br>
        이름 : <input name="inputName" required> <br>
        
        자기소개 (선택) <br>
        <textarea name="intro" cols="50" rows="5"></textarea>

        <button>회원 가입</button>
    </form>
</body>
</html>



<!-- WEB-INF -> views
:클라이언트 쪽에서 직접적으로 주소를 쳐서 접근하는 것이 불가함
접근하려면 Controller를 거쳤다 와야 함
보안때문에 숨겨놓은 파일-->

ExampleController1.java

package edu.kh.servlet.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ExampleController1 extends HttpServlet{
	
    // doGet() 메서드
	// -> Get 방식 요청을 처리하는 메서드
	// HttpServlet의 메서드를 오버라이딩
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		// HttpServletRequest
		// - 클라이언트 요청 시 생성되는 객체
		// - 클라이언트 데이터 + 요청관련 데이터
		
		// HttpServletResponse
		// - 클라이언트 요청 시 서버에서 생성하는 객체
		// - 서버가 클라이언트에게 응답하기 위한 방법을 제공하는 객체
		
		System.out.println("--- 이름, 나이를 입력 받아 처리하는 코드 ---");
		
		// 요청 시 입력된 이름, 나이를 전달 받아오기
		
		// parameter : 매개변수 == 다른곳의 값을 전달 받아올때 사용
		
		// req.getParameter("name 속성값");
		// -> 요청 시 전달된 데이터 중
		//		name 속성 값이 일치하는 데이터의 value를 얻어와
		// 		'String' 형태로 반환
		
		
		// HTML 에서 얻어오는 모든 값은 String!!!
		String name = req.getParameter("inputName");
		String age = req.getParameter("inputAge");
		
		System.out.println("입력 받은 이름 : " + name);
		System.out.println("입력 받은 나이 : " + age);
		
		// 서버 -> 클라이언트 응답하기
		// HttpServletResponse 객체 이용
		
		// 응답하는 문서의 형식과 문자 인코딩을 지정
		// - text/html : 글자가 작성된 html 문서
		// - charset=UTF-8 : UTF-8 형식의 문자 인코딩으로 작성됨
		resp.setContentType("text/html; charset=UTF-8");
		
		// 서버 -> 클라이언트로 연결되는 스트림(통로) 얻어오기
		PrintWriter out = resp.getWriter();
		// 서버 -> 클라이언트에게 쓰다(출력)
		
		out.println("<!DOCTYPE html>");
		
		out.println("<html>");
		
		out.println("<head>");
			out.println("<title>서버 응답 결과</title>");
		out.println("</head>");
		
		out.println("<body>");
			out.println("<h1>");
			
			out.println(name + "님의 나이는 " + age + "세 입니다.");
			
			out.println("</h1>");
		out.println("</body>");
		
		out.println("</html>");
		
	}
}

ExampleController2.java

package edu.kh.servlet.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// Servlet 관련 코드를 작성하기 위해서 HttpServlet 클래스 상속 받아야 한다!

/* @Override
 * 어노테이션 : 컴파일러가 읽는 주석 
 * 
 * @WebServlet 어노테이션
 * -> 해당 클래스를 Servlet 등록하고
 * 		매핑할 주소를 연결하라고 지시하는 어노테이션
 * 
 * -> 서버 실행 시 자동으로 web.xml에
 * 		<servlet> <servlet-mapping> 를 작성하는 효과
 * 
 */

// 앞으로는 이렇게 작성!
@WebServlet("/example2")
public class ExampleController2 extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		// HttpServletRequest : 요청 데이터를 담고있는 객체
		String orderer = req.getParameter("orderer");
		String coffee = req.getParameter("coffee");
		String type = req.getParameter("type");
		
		/* name 속성 값이 같은 파라미터가 여러개인 경우
		 * String[]로 한번에 반환 받는 getParameterValues("name") 사용
		 * 
		 */
		
		String[] optionArr = req.getParameterValues("opt");
		
		// 응답 코드
		// 응답 데이터 형식, 문자 인코딩 지정
		resp.setContentType("text/html; charset=UTF-8");
		
		// 응답용 스트림(서버 -> 클라이언트) 얻어오기
		PrintWriter out = resp.getWriter();
		
		out.println("<!DOCTYPE html>");
		out.println("<html>");
		
		out.println("<head> <title> "+orderer+"님의 주문 결과 </title> </head>");
		out.println("<body>");
		
		out.println("<h3>주문자명 : " + orderer + "</h3>");
		
		out.println("<h3>주문한 커피 : ");
		
		if(type.equals("ICE")) 	out.print("차가운 ");
		else					out.print("따뜻한 ");
		
		out.print(coffee);
		out.println("</h3>");
		
		// 옵션이 선택된 경우 출력
		// -> getParameter(), getParameterValues() 수행 시
		// 전달된 값 중 name이 일치하는 값이 없으면
		// null 반환
		if(optionArr != null) {
			out.println("<ul>");
			
			for(String opt : optionArr) {
				out.println("<li>"+opt+"</li>");
			}
			
			out.println("</ul>");
		}
		
		out.println("</body>");
		out.println("</html>");

	}
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  
  <!-- 
  	web.xml (배포 서술자(설명서))
  	Server가 켜지자 마자(Start) 제일 처음 읽는 문서
   -->
  
  
  
  <display-name>ServletProject</display-name>
  
  <!-- 메인페이지로 사용할 파일 명 목록 (webapp 폴더(배포해주는 파일)에 파일 생성) -->
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>default.htm</welcome-file>
  </welcome-file-list>
  
  <!-- 특정 클래스(ExampleController1)를 Servlet으로 등록하고 이름을 지정하는 태그 -->
  <servlet>
  	<!-- 등록할 Servlet을 지칭할 명칭 -->
  	<servlet-name>ex1</servlet-name>
  	
  	<!-- Servlet으로 등록할 클래스의 패키지명+클래스명 -->
  	<servlet-class>edu.kh.servlet.controller.ExampleController1</servlet-class>
  </servlet>
  
  <!-- 요청주소를 처리할 Servlet을 연결 -->
  <servlet-mapping>
  	<!-- 등록할 Servlet을 지칭할 명칭 -->
  	<servlet-name>ex1</servlet-name>
  	
  	<!-- 연결할 요청 주소 -->
  	<url-pattern>/example1</url-pattern>
  </servlet-mapping>
  
  
  
</web-app>

SignUpController.java

package edu.kh.servlet.controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/signUp")
public class SignUpController extends HttpServlet{
	
	// POST 요청 처리 메서드 오버라이딩
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		// 전달받은 값을 얻어와서 확인
		// -> 한글이 깨지는 문제 발생!
		
		// 왜? 요청데이터의 문자 인코딩
		//		서버의 문자 인코딩이 같지 않아서..
		
		// 해결 방법 : 전달 받은 데이터의 문자 인코딩을 서버에 맞게 변경
		req.setCharacterEncoding("UTF-8");
		
		String inputId = req.getParameter("inputId");
		String inputPw = req.getParameter("inputPw");
		String inputName = req.getParameter("inputName");
		String intro = req.getParameter("intro");
		
		// 응답화면 만들기
		// -> Java에서 작성하기 너무 귀찮고 힘들다
		// -> 누가 이것좀 대신 해주면 안될까?
		// -> JSP가 대신 화면을 만들어서 응답해줌!
		
		// JSP가 대신 화면을 만들어 주기 위해선
		// Servlet이 어떤 요청을 받았는지 알아야한다!
		
		// -> Servlet이 받은 요청을 JSP로 위임하는 작업을 진행!
		RequestDispatcher dispatcher = req.getRequestDispatcher("/WEB-INF/views/result.jsp");
		
		dispatcher.forward(req, resp);
		
		// SERVER 에러시 해야할 것.
		// 위 상단바 : Project - clean
		// 하단 : Servers - 우클릭 - clean - OK
		// 웹 창 : 강력새로고침 CTRL + SHIFT + R
		
	}
}

result.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>회원가입결과</title>
</head>
<body>
    <!-- jsp 파일을 만들기 위한 준비단계 -->
    <h3 style="color: hotpink;">홍길동님의 가입을 환영합니다.</h3>

    <ul>
        <li>id : user01</li>
        <li>pw : pass01</li>
    </ul>

    <h4>자기소개</h4>
    <p>안녕하세요?</p>
</body>
</html>

result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>회원 가입 결과</title>
</head>
<body>
	<%-- JSP 주석
		(Spring에서도 똑같이 사용되기 때문에 스크립틀릿, 표현식 익숙해져야 함!)
		<% %> : 스크립틀릿 -> 자바코드 작성
		<%= %> : 표현식 -> 자바, 서버에서 받아온 값을 표현할 때, 출력
	--%>
	
	<h3 style="color: hotpink;"><%= request.getParameter("inputName") %>님의 가입을 환영합니다.</h3>

    <ul>
        <li>id : <%= request.getParameter("inputId") %></li>
        <li>pw : <%= request.getParameter("inputPw") %></li>
    </ul>

	<% if( !request.getParameter("intro").equals("") ) {%>
	<h4>자기소개</h4>
	<p>
		<%= request.getParameter("intro") %>
	</p>
	<% } %>
	
</body>
</html>


서버로 제출하기(==요청하기) 버튼 클릭 시,

주문하기 버튼 클릭 시,
회원 가입 버튼 클릭 시,

CF ) Server 실행하는 방법

0개의 댓글