GET 방식과 POST방식

GET 방식

• 서버에 있는 정보를 가져오기 위해 설계됨.

• 240바이트까지 전달할 수 있음.

• QUERY_STRING 환경변수를 통해 전달.

• 형식 : http://xxx.xxx.co.kr/servlet/login?id=hj&name=hong

• URL노출로 보안성이 요구되는경우엔 사용할 수 없음.

• 검색엔진에서 검색단어 전송에 많이 이용함.

 

POST 방식

• 서버로 정보를 올리기 위해 설계됨.

• 데이터크기의 제한은 없다.

• URL에 파러미터가 표시되지 않는다.

 

서블릿구조

서블릿 로딩

• init() 메서드

• 최초 클라이언트 요청 시 init() 메서드가 호출되며 메모리에 적재됨.

 

요청 처리

• service() 메서드

• service() 메서드가 컨테이너에 의해 호출

 

처리 수행

• doGet(), doPost() 메서드 서블릿 종료

• destroy() 메서드

 

스레드는 프로세스를 스위칭하는 작업의 또다른 모델
옛날에는 프로세스와 스레드가 1:1이었다.프로세스에는 흐름이 1개였으니까
스레드에도 흐름이 1개였었다.하나의 프로그램이 자신로직을 동시실행해야하는 일이 발생
그걸 도와주기위해 프로세스안에서 스위칭이 일어나게끔 플랫폼이 새로 등장했다
프로세스안에서 여러 스위칭이, 여러함수가 개별적인 스위칭으로 왔다갔다할 수있게해주는 하나의 단위

get요청하면서 get을 처리하는 로직에게 내가 만든 값 또는 상태를 전달할 수 있는 방법이 필요하다.
1. 파일을 이용하는 방법
2. 서블릿의 저장소를 이용하는 방법(Application/session/cookie/..)
3. QueryString을 이용하는 방법 (r값전달):
   질의용(옵션 ex,커피+샷추가)
   다른서블릿에서 값전달시에도 사용

sendRedirect : post로 왔다가 다시 get요청을 할 수있게해준다. 추가적값을 전달해서 상태유지하게해준다.

 


if(req.getMethod().equals("POST"))

첫get요청에서는 이부분이 실행되지않아도됨

서버쪽에서 get요청인지, 값을 넣고 전달한 post요청인지 알아야한다.

Request 가 모든정보를 보여준다. Request Method가 POST일때 실행하도록한다.

 

변수를 POST조건문보다 먼저 선언했어야했다.

int x = 0;
int y = 0;
int result = 0;
String x_=null;
String y_=null; 를 먼저 선언할것

POST일때만 동작하는지 확인방법 :

System.out.println("calc");를 조건문 안에 넣어서 POST일경우 calc를 서버안에서 출력하도록한다.

사용자가 덧셈을 누르면 POST가되어 calc가 서버에 출력된다.

 

 

웹브라우저 : 사용자

이닛멤버메소드를 실행한다.

초기화할수있도록 비어있는 메소드이다. 오버라이드할수있다.

스레드란..?

 

프로그램만들면 메인함수부터 절차가 진행한다.(수행절차)

흐름을 그어보면 하나의 선으로 그어진다.(수행절차)

그 흐름을 스레드라고 한다.

실행흐름 = 스레드

동시에 다른흐름이생기는 경우가있다.

별도의 프로세스로 빼서 작업했었다

ex, 이북을 동시 다운로드(파일 카피) while문,반복문이 끝날때까지 다른것들 응답없음이 뜨게된다.

하나의 프로세스가 진행되는 과정에서 다운로드는 따로실행되게하고싶다.

흐름안에 흐름만드는방법이 없어서 

fork()사용(프로세스가 자식을 만드는것,프로그램이 프로그램을 실행) 

(프로그램은 살아있지않다. 프로세스가 다운됐어가 옳바른용어)

프로그램이올라가서 프로세스가된다.

자식프로세스가 필요

자기 로직의 일부를 별도프로세스올림.

일부로직인데, 서로 데이터를 공유해야하는 상황

원래 프로세스는 각자 개별적으로 자기만의 데이터로 혼자 실행되는것

프로세스간의 데이터공유, 컨텍스트 스위칭에 대한 부담 (프로세스 수가많아지면 전환되는과정에 부담)

여러개프로세스를 동시에실행하는게아니라 그렇게보이는것

(만화가 움직이는것처럼)

포인터가 프로세스정보를 가지고있다.

스위칭과정 : 콘텍스트스위칭

하나의 프로세스안에서 갖게되는 흐름 : 프로세스는 x , 스레드라한다

맨위에있는 스택에있는함수만 실행된다.

하나의 흐름만 갖고있는 방식으로는 검색,다운로드를 병렬수행할수없게된다.

스택을 2개만든다.

동시에 실행되면서 힙에있는것

함수를 스위칭하는방식 

자바는 new Thread()클래스가있음. 스레드클래스를통해 메인과 다른함수가 동시에실행할 수있다.

스레드로 수행하고있다.

 

서비스는 개별적으로 스레드로 동작

객체는 하나, 함수는 여러개

서비스흐름이끝나도 객체는 살아있다.

요청이안오면 사라진다.

3개의함수를 오버라이드할 수있다. 

super.service(req, resp);를 지웠을때 doGET(),doPost() 오버라이드된 게 안뜬다. 

doGet과 doPost를 호출하는 장본인이 service이다.

Service를 오버라이드하는 순간 doGet과 doPost를 호출하는걸 담고있는 로직이 지워진것(부모가갖고있는)이다.

부모안에 doGet과 doPost이 있었는데 오버라이드하면서 없어진것.

Service를 오버라이드하면서  doGet과 doPost이사라짐.

 

의도적으로 doGet과 doPost로직을 처리하면서 추가적으로 겟에 대한내용과 포스트에대한 내용을 할수있겠지만
일반적으로 service()를 작성하지않는다.
calc class에서 service()를 작성안하면 톰캣이 부모service()를 호출하고 거기에 적절하게 오버라이드된 doGet과 doPost가 호출된다.

servie()함수를 오버라이드하고 super.service()를 호출안헀을때 doGet과 doPost가 호출되지않는다.
calc에 오버라이드된 service함수안에 super.service()를 호출하면 calc안에 오버라이드된 doGet, doPost가 호출된다. 

 

 

POST와 GET요청의 이해와 코드 분리하기

1. doGet()과 doPost()로 분리

 

 

2. 사용자가 값을 입력하고 덧셈을 누르면 백지가나온다.

사용자가 숫자입력하면 흰화면

3 . 사용자에게 결과값을 돌려주는 출력을 하지 않았다.

숫자를 넣고 덧셈을누르면 다음화면으로넘어가지만 결과값이 나오지않는다.

사용자에게 출력한코드가없다.

다시 출력해줄때 write(HTML)코드를 다시넣어야하나 ? (똑같은코드를 두번쓰는건 비효율적)

아니다, 다시 get요청을 할 수있는 함수가 있다.

 

문서를 출력하는것은 post가 할게아니라 get한다.

처리한 결과를 get을 이용해서해야한다. 

doGet(res,resp);를 넣어보자. -> result를 전역변수로 해보자.

결과값을 공유하지 못한다.. 

 

calc라는 일반클래스가 아니다. web의 흐름

 

post요청이왔다면 다시 get요청을받을수있게 흐름을 잡아야함

사용자가 글을적고 등록을 누르면 목록페이지로 전환된다.

클릭-문의글등록-포스트-목록페이지로 전환(새로운 GET요청)

스레드가 연결이안되어있다.

포스트서블렛이 올라갔다 바로내려감 ,메모리에아무것도없음 다시 겟서블릿생성

doget은 어떠한 지역변수도 볼수없음.

상태값을 유지할 방법이 필요하다.

 

 

get요청하면서 get을 처리하는 로직에게 내가 만든 값 또는 상태를 전달할 수 있는 방법이 필요하다.

1. 파일을 이용하는 방법
2. 서블릿의 저장소를 이용하는 방법(Application/session/cookie/..)
3. QueryString을 이용하는 방법 (r값전달)

   질의용(옵션 ex,커피+샷추가)

   다른서블릿에서 값전달시에도 사용

 

resp.sendRedirect("/add?r="+result);

내가 어떤 서블릿코드에서 get요청을하고싶을때 사용한다. 

get을 재활용하는데 쿼리스트링을 이용해서 값을 공유하도록했다. 

 

doget에서 result는 출력할목적

dopost에서 result는 계산목적

sendRedirect : post로 왔다가 다시 get요청을 할 수있게해준다. 추가적값을 전달해서 상태유지하게해준다.

 

package com.newlecture.web;

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;


@WebServlet("/add")
public class Calc extends HttpServlet{
	
	int result;
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//GET만 따로처리
		resp.setCharacterEncoding("UTF-8");//UTF로 인코딩보낸것,보내는방식지정
		resp.setContentType("text/html;charset=UTF-8");//1.브라우저가읽는방식,브라우저가 정상적으로 읽을수있도록		
		
		//1.입출력도구가 추가되었다.
		int x = 0;
		int y = 0;
		int result = 0;
		String x_=null;
		String y_=null;
		String r_= req.getParameter("r");
		
		if(r_ != null)
			result = Integer.parseInt(r_);

    	//문서를 동적으로 만드는 코드: 이 코드로 만들어진 결과물 , 동적인 문서, 서버문서 
    	PrintWriter out = resp.getWriter();
   	
    	out.write("<!DOCTYPE html>");
    	out.write("<html>");
    	out.write("<head>");
    	out.write("<meta charset=\"UTF-8\">");//2.브라우저가읽는방식,브라우저에게 이코드방식으로 읽어라 최근방식
    	out.write("<title>Insert title here</title>");
    	out.write("</head>");
    	out.write("<body>");
    	out.write("  <section>");
    	out.write("    <h1>계산기</h1>");
    	out.write("    <div>");
    	
    	if(x_ != null)//처음페이시 요청했을떄 안나오도록
    		out.write("    <div>"+x +"+"+ y+"=</div>"); //계산했던 연산식
    	
    	out.write("         <form action=\"/add\"method=\"post\">");
    	out.write("            <input type=\"text\" name=\"x\">+<input type=\"text\" name=\"y\"><br>");
    	out.write("            <input type=\"submit\" value=\"덧셈\"><span>"+result+"</span>");//출력용
    	out.write("         </form>");
    	out.write("      </div>");
    	out.write("   </section>");
    	out.write("</body>");
    	out.write("</html>");    	    	
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//POST에서 사용되는것만 분리
		int x = 0;
		int y = 0;
		int result = 0;
		String x_=null;
		String y_=null;
		
//		if(req.getMethod().equals("POST")){//대문자와비교
			System.out.println("calc");//서버에 출력
			
			x_ = req.getParameter("x");
    	if(x_ != null && !x_.equals("")) //null이면 0
    		x = Integer.parseInt(x_);
    	
    		y_ = req.getParameter("y");
    	if(y_ != null && !y_.equals("")) 
    		y = Integer.parseInt(y_);
    	
    		result = x + y; //계산용
    		// get요청을 하는것이 더 효율적이다.POST에서 계산후 get요청을 다시받아야한다
    		//doGet(req,resp);
    		resp.sendRedirect("/add?r="+result);//resp.sendRedirect("/add");값은안가고 문서만간다.
    		//get요청하면서 get을 처리하는 로직에게 내가 만든 값 또는 상태를 전달할 수 있는 방법이 필요하다.
    		//1.파일을 이용하는 방법
    		//2.서블릿의 저장소를 이용하는 방법(Application/session/cookie/..)
    		//3.QueryString을 이용하는 방법   		
    		
//		}
	}
	
	/*
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		resp.setCharacterEncoding("UTF-8");//UTF로 인코딩보낸것,보내는방식지정
		resp.setContentType("text/html;charset=UTF-8");//1.브라우저가읽는방식,브라우저가 정상적으로 읽을수있도록
		
		
		//1.입출력도구가 추가되었다.
		int x = 0;
		int y = 0;
		int result = 0;
		String x_=null;
		String y_=null;
		
		if(req.getMethod().equals("POST")){//대문자와비교
			System.out.println("calc");//서버에 출력
			
			x_ = req.getParameter("x");
    	if(x_ != null && !x_.equals("")) //null이면 0
    		x = Integer.parseInt(x_);
    	
    		y_ = req.getParameter("y");
    	if(y_ != null && !y_.equals("")) 
    		y = Integer.parseInt(y_);
    	
    		result = x + y;
		}
    	//문서를 동적으로 만드는 코드: 이 코드로 만들어진 결과물 , 동적인 문서, 서버문서 
    	PrintWriter out = resp.getWriter();
   	
    	out.write("<!DOCTYPE html>");
    	out.write("<html>");
    	out.write("<head>");
    	out.write("<meta charset=\"UTF-8\">");//2.브라우저가읽는방식,브라우저에게 이코드방식으로 읽어라 최근방식
    	out.write("<title>Insert title here</title>");
    	out.write("</head>");
    	out.write("<body>");
    	out.write("  <section>");
    	out.write("    <h1>계산기</h1>");
    	out.write("    <div>");
    	
    	if(x_ != null)//처음페이시 요청했을떄 안나오도록
    		out.write("    <div>"+x +"+"+ y+"=</div>"); //계산했던 연산식
    	
    	out.write("         <form action=\"/add\"method=\"post\">");
    	out.write("            <input type=\"text\" name=\"x\">+<input type=\"text\" name=\"y\"><br>");
    	out.write("            <input type=\"submit\" value=\"덧셈\"><span>"+result+"</span>");
    	out.write("         </form>");
    	out.write("      </div>");
    	out.write("   </section>");
    	out.write("</body>");
    	out.write("</html>");    	    	
    	
//    	resp.getWriter().print(x+y);
    	super.service(req, resp);
	}*/	
}

 어제 배운 부분에서는 저희가 doGet(), doPost() 메소드를 따로 분리하지 않고 service() 함수에서 사용자의 get 요청과 post 요청이 모두 처리되게 코드를 작성했었잖아요 근데 오늘은 get 요청과 post 요청을 따로 분리해서 doGet()에서는 사용자의 get 요청을 받게 하고, doPost()에서는 사용자의 post 요청을 받게 작성을 했어요

그래서 사용자가 get 요청을 했을 때는 doGet() 메소드 안의 내용이 사용자에게 보여지는 것인데, 이 때 저희가 계산기 입력 폼이 사용자에게 보여지게 doGet() 코드를 분리했었잖아요 이렇게 계산기 입력폼이 사용자에게 보여지는 것은 get요청으로 갈 수 있게 doGet() 안에 작성을 했는데 그렇게 해서 사용자에게 보여진 입력폼을 사용자가 제출할 때는 get이 아닌 post 요청으로 가서 doPost() 메소드가 호출될 수 있도록 <form action="/add" method="post"> 이렇게 폼 태그의 method 부분을 post로 작성해줘야해요..! 그래야 사용자가 입력폼을 제출했을 때 doPost() 메소드가 제대로 호출될 수 있습니다

 

맨 처음에는 사용자가 계산 입력폼 페이지를 요청을 해서 사용자에게 계산 입력폼 페이지를 보여줘야하니까 처음에는 doGet() 메소드가 호출돼요! 근데 그 다음에 사용자가 입력폼을 제출하면 form 태그의 method가 post이니까 POST 요청으로 받아들여져서 doPost() 메소드가 호출되구요. 근데 또 오늘 배운 것처럼 doPost()에서 resp.sendRedirect("/add?r="+result);를 통해 다시 doPost()에서 계산된 result의 값을 들고 doGet()이 호출이 되어서 result 값이 제대로 담긴 계산된 페이지가 사용자에게 get 요청으로 보여지게 됩니다~!

 

 

 

+ Recent posts