JSP - port, get, post

박종휘·2022년 11월 14일
0

JSP - 국비

목록 보기
2/2
post-thumbnail

1. port 오류 찾기 및 중복 port 끄기

  • 포트 충돌 났을 때, 하기 내용 활용

cmd
검색 명령어 : netstat -nao | findstr [port번호]
kill 명령어 : taskkill /f /pid [pid번호]


package com.koreait.web.servlet;

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("/hello") 
// 어노테이션을 선언만해주면 MyServlet이 서블릿 대상클래스로 인식되어 별도의 세팅없이 사용가능 (web.xml)
// "/hello" -> 사용자가 요청하는 URL
public class MyServlet extends HttpServlet {
	
	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 
			throws ServletException, IOException {
		
		arg1.setCharacterEncoding("UTF-8");	// 한글이 나타나게 Response를 인코딩하기
		arg1.setContentType("text/html charset=UTF-8");	// 한글이 깨지지않게 Response의 내용의 type을 설정하기
		// 브라우저에 응답을 던져줄 때, 한글을 맞춰서 던져주기 위해 설정
		// 한글이 깨지는 이유 : UTF-8이라는 인코딩 방식이 브라우저와 내가 던져줄 때의 인코딩 방식이 다 틀어졌을 가능성이 높아서
		
		// 요청객체에서 꺼내오기
		// int cnt = arg0.getParameter("cnt"); 에러가 나는 이유 : 브라우저 영역에서 넘어오는 것은 다 string 타입으로 넘어오기 때문 	/ 특정 key값을 통해 Request로 들어온 value값을 반환하기
		int cnt = Integer.parseInt(arg0.getParameter("cnt")); // int 타입으로 변환 후 int 타입에 넣어준다. / 문자열로 반환되므로 타 타입으로 바꿀 필요가 있음
		// ?cnt=3 -> cnt(key값)를 기점으로 해서 parameter를 get해오면 value인 3이 담기게됨
		
		System.out.println("cnt : " + cnt);
		
		PrintWriter out = arg1.getWriter();
		out.println("Hello Servlet Annotation!!!<br>"); // jsp에서는 줄바꿈을 하려면 <br>태그를 붙여준다.
		out.println("안녕 Servlet Annotation!!!");
	}
	// service + alt + space 자동완성으로 생성가능
}

  • setCharacterEncoding 사용 전
  • setContentType 사용 전
  • 둘 다 사용
  • cnt값 요청

2. 서버 상태코드

  • HTTP 상태 코드

2-1. 종류

  • 1XX : 정보
    -> 요청을 받았으며 프로세스를 계속한다.
  • 2XX : 성공
    -> 요청을 성공적으로 받았으며 인식했고 수용하였다.
  • 3XX : 리다이렉션
    -> 요청 완료를 위해 추가 작업 조치가 필요하다.
  • 4XX : 클라이언트 오류
    -> 요청의 문법이 잘못되었거나 요청을 처리할 수 없다.
  • 5XX : 서버 오류
    -> 서버가 명백히 유효한 요청에 대해 충족을 실패했다.

Reference


int cnt = Integer.paraseInt(arg0.getParameter("cnt"));
System.out.println("cnt : " + cnt)

-> 이거일 경우

하기 로컬 주소일 경우 에러 발생

localhost:[port num]/hello -> 파라미터를 안넘기니까 입력 받아야할 파라미터 내용이 없어서
localhost:[port num]/hello?cnt= -> 빈 문자열을 숫자로 바꾸려고 해서


String paramCnt = arg0.getParameter("cnt");
System.out.println("paramCnt : " + paramCnt);

-> 이걸로 변경하면 해결

localhost:[port num]/hello -> null 출력
localhost:[port num]/hello?cnt= -> 빈 문자열 출력

👉 둘의 차이점

int cnt = Integer.parseInt(arg0.getParameter("cnt"));
// 숫자 모양을 한 문자열을 받는데 null과 빈문자열은 숫자값으로 변경을 하지 못해서

String paramCnt = arg0.getParameter("cnt");
// 단순 문자열 String 값으로 받아와서 console창에 출력해주어서
  • 예외처리
if(paramCnt != null && !paramCnt.equals("")) {
	cnt = Integer.parseInt(paramCnt);
} else {
	cnt = 100;
}
package com.koreait.web.servlet;

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("/hello") 
// 어노테이션을 선언만해주면 MyServlet이 서블릿 대상클래스로 인식되어 별도의 세팅없이 사용가능 (web.xml)
// "/hello" -> 사용자가 요청하는 URL
public class MyServlet extends HttpServlet {
	
	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 
			throws ServletException, IOException {
		
		arg1.setCharacterEncoding("UTF-8");	// 한글이 나타나게 Response를 인코딩하기
		arg1.setContentType("text/html charset=UTF-8");	// 한글이 깨지지않게 Response의 내용의 type을 설정하기
		// 브라우저에 응답을 던져줄 때, 한글을 맞춰서 던져주기 위해 설정
		// 한글이 깨지는 이유 : UTF-8이라는 인코딩 방식이 브라우저와 내가 던져줄 때의 인코딩 방식이 다 틀어졌을 가능성이 높아서
		
		String paramCnt = arg0.getParameter("cnt");
		System.out.println("paramCnt : " + paramCnt);
		int cnt = 0;
		
		// 예외처리
		if(paramCnt != null && !paramCnt.equals("")) {
			cnt = Integer.parseInt(paramCnt);
		} else {
			cnt = 100;
		}
		
		// 요청객체에서 꺼내오기
		// int cnt = arg0.getParameter("cnt"); 에러가 나는 이유 : 브라우저 영역에서 넘어오는 것은 다 string 타입으로 넘어오기 때문 	/ 특정 key값을 통해 Request로 들어온 value값을 반환하기
		//int cnt = Integer.parseInt(arg0.getParameter("cnt")); // int 타입으로 변환 후 int 타입에 넣어준다. / 문자열로 반환되므로 타 타입으로 바꿀 필요가 있음
		// ?cnt=3 -> cnt(key값)를 기점으로 해서 parameter를 get해오면 value인 3이 담기게됨
		
		System.out.println("cnt : " + cnt);
		
		PrintWriter out = arg1.getWriter();
		out.println("Hello Servlet Annotation!!!<br>"); // jsp에서는 줄바꿈을 하려면 <br>태그를 붙여준다.
		out.println("안녕 Servlet Annotation!!!");
	}
	// service + alt + space 자동완성으로 생성가능
}

📌 연습문제

My Code

package com.koreait.web.servlet;

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("/cnt")
public class CntServlet extends HttpServlet {
	
	/*
	 * CntServlet을 servlet class로 사용하여
	 * 사용자 url요청	:	http://localhost:9090/cnt?cnt=5
	 * 화면 출력 내용		: 	1:	안녕 servlet
	 * 				 	2:	안녕 servlet
	 * 				 	3:	안녕 servlet
	 * 				 	4:	안녕 servlet
	 * 				 	5:	안녕 servlet
	 * 
	 * 
	 * 사용자 url요청	:	http://localhost:9090/cnt?	null or ""
	 * 화면 출력 내용		: 	1:	안녕 servlet
	 * 					...
	 * 				 	100:	안녕 servlet
	 */
	
	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 
			throws ServletException, IOException {
		
		arg1.setCharacterEncoding("UTF-8");
		arg1.setContentType("text/html charset=UTF-8");
		
		String paramCnt = arg0.getParameter("cnt");
		System.out.println("cnt: " + paramCnt);
		int cnt = 0;
		
		PrintWriter out = arg1.getWriter();
		if(paramCnt != null && !paramCnt.equals("")) {
			if(paramCnt.equals("5")) {
				for(int i = 1; i <= 5; i++) {
					out.println(i + ": 안녕 servlet <br>");
				}
			} 
		} else {
			for(int i = 1; i <= 100; i++) {
				out.println(i + ": 안녕 servlet <br>");
			}
		}
	}
}
Teacher's Code

package com.koreait.web.servlet;

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("/cnt")
public class CntServlet extends HttpServlet {
	
	/*
	 * CntServlet을 servlet class로 사용하여
	 * 사용자 url요청	:	http://localhost:9090/cnt?cnt=5
	 * 화면 출력 내용		: 	1:	안녕 servlet
	 * 				 	2:	안녕 servlet
	 * 				 	3:	안녕 servlet
	 * 				 	4:	안녕 servlet
	 * 				 	5:	안녕 servlet
	 * 
	 * 
	 * 사용자 url요청	:	http://localhost:9090/cnt?	null or ""
	 * 화면 출력 내용		: 	1:	안녕 servlet
	 * 					...
	 * 				 	100:	안녕 servlet
	 */
	
	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 
			throws ServletException, IOException {
		
		arg1.setCharacterEncoding("UTF-8");
		arg1.setContentType("text/html charset=UTF-8");
		
		String paramCnt = arg0.getParameter("cnt");
		System.out.println("cnt: " + paramCnt);
		
        int cnt = 100; 
		  
		 if(paramCnt != null && !paramCnt.equals("") {
		 	cnt = Integer.parseInt(paramCnt)
		 }
		 
		 PrintWriter out = arg1.getWriter();
		 for(int i = 0; i < cnt; i++) {
		 	out.println((i + 1) + " : 안녕 servlet<br>");
		 }
	}
}

📌 프론트 단에서 호출

  • cnt.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	환영합니다<br>
	<a href="cnt">인사하기</a>
	<a href="cnt?cnt=7">7번 인사하기</a>
</body>
</html>
  • form.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="cnt"> <!-- url 넣는 곳 : /cnt로 넘어감 -->
		<div>
			<label>"안녕 servlet" 몇번 듣고 싶으세요?</label>
		</div>
		<div>
			<input type="text" name="cnt"> 
			<!-- name의 cnt라고 할 때 화면에서 입력한  값이 ?cnt(key 값)의 value로 넘어옴 -->
			<input type="submit" value="출력">
			<!-- 출력 버튼을 누르면 서버로 전송된다.-->
			<!-- 그 서버가 cnt url을 처리(파싱)해 줄 수 있는 CntServlet으로 요청이 넘어간다. -->
			<!-- Servlet 클래스의 url을 기점으로 파싱해오는 것이다. -->
		</div>
	</form>
</body>
</html>

즉, 프론트 단에서 정보가 서버로 전송 -> URL을 처리해 줄 수 있는 AnySevlet(여기선 CntServlet) => 이 순으로 요청이 넘어간다.


3. get / post 방식

3-1. GET 방식

  • 서블릿에 데이터를 전송할 때, URL뒤에 key=value 형태로 전송
  • 보안에 취약
  • 전송 가능 데이터 최대 255자
  • 기본 전송 방식으로 사용이 쉬움
  • 웹 브라우저에서 직접 입력하여 전송 가능
  • 여러 개의 데이터를 전송할 때 '&'로 구분해서 전송

3-2. POST 방식

  • 서블릿에 데이터를 전송할 때 TCP/IP 프로토콜 데이터의 HEAD영역에 숨겨진채 전송
  • 보안에 유리
  • 전송 데이터 용량 무제한
  • 전송시 서블릿에서 또 다시 가져오는 작업이 필요하므로 GET 방식보다 처리 속도가 느림

👉 get 방식

reg.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<!-- 기본 : method="get" -> form 태그에 따로 명시하지 않았을 때 -->
	<form action="regit" >
		<div>
			<label>제목 : </label>
			<input type="text" name="title">
		</div>
		<div>
			<label>내용 : </label>
			<textarea name="content"></textarea>
		</div>
		<div>
			<input type="submit" value="출력">
		</div>
	</form>
</body>
</html>
RegitServlet.java


package com.koreait.web.servlet;

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("/regit")
public class RegitServlet extends HttpServlet {
	
	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 
			throws ServletException, IOException {
		
		arg1.setCharacterEncoding("UTF-8");
		arg1.setContentType("text/html charset=UTF-8");
		
		PrintWriter out = arg1.getWriter();
		
		String title = arg0.getParameter("title");
		String content = arg0.getParameter("content");
		// String title: 자바단
		// getParameter("title"): 프론트단
		// 이름을 동일하게 하면 헷갈리지 않는다. => DB 컬럼명도 동일하게 (DB 설계가 첫번째로)
		
		out.println(title);
		out.println(content);
	}
}


요청 => 클라이언트가 요청을 보냄 -> 전부 Request에 담김 -> 파라미터에 대한 내용도 Request 객체에서 getParameter 메서드 사용해서 꺼내줌
응답 => Response 객체에 담아만 주면 http 통신을 통해서 날아감

👉 post 방식

📌 연습 문제

calc.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<!-- 
		result is [덧셈 결과값 입력]
		이 결과값을 출력하는 servlet을 작성
	 -->
	<form action="add" method="post">
		<div>
			<label>x : </label>
			<input type="text" name="x">
		</div>
		<div>
			<label>y : </label>
			<input type="text" name="y">
		</div>
		<input type="submit">
	</form>
</body>
</html>
AddServlet.java


package com.koreait.web.servlet;

import java.io.IOException;

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 AddServlet extends HttpServlet{
	
	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 
			throws ServletException, IOException {
		
		String xStr = arg0.getParameter("x");
		String yStr = arg0.getParameter("y");
		
		System.out.println("xStr : " + xStr); // request에서 xStr을 잘 받아오는지 확인
		System.out.println("yStr : " + yStr);
		
		int x = 0;
		int y = 0;
		
		if(xStr != null && !xStr.equals("")) {
			System.out.println("x : " + x); // if문을 잘 탔는지 x 값 출력
			x = Integer.parseInt(xStr);
		}
		
		if(yStr != null && !yStr.equals("")) {
			System.out.println("y : " + y);
			y = Integer.parseInt(yStr);
		}
		
		int result = x + y;
		System.out.println("result : " + result); // result 값이 잘나오는 지 확인
		arg1.getWriter().println("result is " + result);
		
	}
}

calc2.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<!-- 
		result is [연산 결과값 입력
		덧셈 버튼 클릭 -> 덧셈 연산결과
		뺄셈 버튼 클릭 -> 뺄셈 연산결과
		이 결과 값을 출력하는 servlet을 작성
	 -->
	<form action="calc" method="post">
		<div>
			<label>x : </label>
			<input type="text" name="x">
		</div>
		<div>
			<label>y : </label>
			<input type="text" name="y">
		</div>
		<input type="submit" name="operator" value="덧셈">
		<input type="submit" name="operator" value="뺄셈">
	</form>
</body>
</html>
CalcServlet.java


package com.koreait.web.servlet;

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("/calc")
public class CalcServlet extends HttpServlet{
	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 
			throws ServletException, IOException {
		
		String xStr = arg0.getParameter("x");
		String yStr = arg0.getParameter("y");
		String op = arg0.getParameter("operator");
		
		System.out.println("xStr : " + xStr);
		System.out.println("yStr : " + yStr);
		System.out.println("op : " + op);
		
		int x = 0;
		int y = 0;
		int result = 0;
		
		if(xStr != null && !xStr.equals("")) {
			System.out.println("x : " + x);
			x = Integer.parseInt(xStr);
		}
		
		if(yStr != null && !yStr.equals("")) {
			System.out.println("y : " + y);
			y = Integer.parseInt(yStr);
		}
		
		if(op.equals("덧셈")) {
			result = x + y;
		} else {
			result = x - y;
		}
		System.out.println(result);
		
		PrintWriter out = arg1.getWriter();
		out.println("result is " + result);
	}
}

  • get일 때
  • post일 때

📌 form 태그에 똑같은 이름의 input 태그가 있을 때

calc3.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="calc3" method="post">
		<input type="text" name="num">
		<input type="text" name="num">
		<input type="text" name="num">
		<input type="text" name="num">
		
		<input type="submit" name="operator" value="덧셈">
	</form>
</body>
</html>
package com.koreait.web.servlet;

import java.io.IOException;

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("/calc3")
public class Calc3Servlet extends HttpServlet {
	
	@Override
	protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 
			throws ServletException, IOException {
		
		String[] numStr = arg0.getParameterValues("num"); 
        // getParameterValues ↓
        // 배열을 이용해 값을 저장할 때 사용
		
		int result = 0;
		
		for(int i = 0; i < numStr.length; i++) {
			 int num = Integer.parseInt(numStr[i]);
			 System.out.println(num);
			 result += num;
		}
		
		arg1.getWriter().println("result is " + result);
		
	}
}

4. Servlet Filter

  • 클라이언트로부터의 요청이 백엔드로 가기 전에 가로채기 위해서 서버로부터의 응답이 클라이언트로 보내지기 전에 조작하기 위해 사용한다.

ex 01) 한글에 대한 처리 부분을 모든 java 파일에 수작업으로 넣는 것은 번거로우니 servlet filter 영역에다 기재를 하는 것이 좋다.
ex 02) 로그인 유지 기능 -> 제한 시간동안 아무 사용이 없었을 때, 필터에서 로그인 정보를 확인하여 servlet 영역까지 오지 못하게 막아 로그아웃이 되도록 한다.


CharacterEncodingFilter.java


package com.koreait.web.servlet.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

@WebFilter("/*") 
// url을 설정해줘야 필터를 적용시킬 수 있다. url 요청이 왔을 때만 이 클래스가 캐치가 된다.
// 모든 요청에 대해서 처리를 하고 싶으면 '/*'을 사용한다. -> 공통적인 요소를 처리할 때
public class CharacterEncodingFilter implements Filter{

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		
		arg0.setCharacterEncoding("UTF-8");
		
		arg1.setCharacterEncoding("UTF-8");
		arg1.setContentType("text/html charset=UTF-8");
		
//		System.out.println("before filter");
		// filterChain으로 다음 작업 진행 여부를 정한다.
		arg2.doFilter(arg0, arg1);
//		System.out.println("after filter");
	}
	
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		
	}
}
profile
개린이의 개발 고수되기 작전!

0개의 댓글