사용자 데이터 전송방식
get방식
URL창에 “ ? “ 뒤에 데이터를 입력하는 방법(쿼리스트링)으로 보낸다.
데이터가 여러 개일 경우 &로 묶어서 보낸다.
데이터 검색에 많이 사용, 데이터 크기 한계가 있으며, 보안에 취약하다
post방식
HTTP헤더의 내용으로 보내는 방식으로 데이터 크기에 제한이 없고, 헤더에 포함되어 보안이 뛰어남
☞ Servlet이 두 방식 중 하나로 전달받으면 해당하는 매소드를 호출함
html 에서 method속성을 이용해서 방식결정, default : get
서블릿 메소드
doGet
client에서 데이터를 전송 방식을 get방식으로 전송하게 되면 호출되는 메소드
doPost
client에서 데이터를 전송 방식을 Post방식으로 전송하게 되면 호출되는 메소드
☞ 반드시 ServletException 처리해야 함.
@WebServlet("/request-service")
public class ServiceMethodTestServlet extends HttpServlet {
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException{
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
/* 하위 타입으로 다운캐스팅 한 뒤 요청 받은 http 메소드가 어떤 메소드 인지를 판단한다. */
String httpMethod = httpRequest.getMethod();
System.out.println("http method : " + httpMethod);
if("GET".equals(httpMethod)) {
/* GET 요청을 처리할 메소드로 요청과 응답 정보를 전달한다.*/
doGet(httpRequest, httpResponse);
} else if("POST".equals(httpMethod)) {
/* POST 요청을 처리할 메소드로 요청과 응답 정보를 전달한다.*/
doPost(httpRequest, httpResponse);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("GET 요청을 처리할 메소드 호출 됨....");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("POST 요청을 처리할 메소드 호출 됨....");
}
}
서블릿 매개변수 객체
HttpServletRequest (interface)
HTTP Servlets을 위한 요청정보(request information)를 제공 메소드 지정
** 인터페이스 구현은 컨테이너가 알아서 설정 / 메소드만 이용 **
상속 : javax.servlet.ServletRequest (interface)
메소드명 | 내용 |
getParameter(String) | client가 보내준 값이 저장된 명칭이 매개변수와 같은 명칭에 저장된 값을 불러오는 매소드 |
getParameterNames() | client가 보내준 값을 저장한 명칭을 불러오는 매소드 |
getParameterValues(String) | client가 보내준 값이 여러개일 경우 그 값을 배 열로 불러오는 메소드 |
getParameterMap() | client가 보내준 값이 전체를 Map방식으로 불러 오는 매소드 |
setAttribute(String, object) | request객체에 전달하고 싶은 값을 String 이름으로 Object저장하는 메소드 |
getAttribute(String) | 매개변수와 동일한 객체 속성값 불어오는 메소드 |
removeAttribute(String) | request객체에 저장되어 매개변수와 동일한 속성값 삭제하 는 매소드 |
setCharacterEncoding(String) | 전송받은 reques객체의 값들의 CharaterSet을 설정해주 는 매소드 |
getRequestDispatcher(String) | 컨테이너내에서 request, response객체를 전송하여 처리 할 컨포넌트(jsp파일 등)를 불러오는 매소드로 forward()메 소드와 같이 사용 |
HttpServletResponse (interface)
요청에 대한 처리결과를 작성하기 위해 사용하는 객체
** 인터페이스 구현은 컨테이너가 알아서 설정 / 메소드만 이용 **
상속 : javax.servlet.ServletResponse (interface)
메소드명 | 내 용 |
setContentType(String) | 응답으로 작성하는 페이지의 MIME type을 정하는 매소드 |
setCharacterEncoding(String) | 응답하는 데이터의 CharacterSet을 지정해주는 매소드 |
getWriter() | 문자를 페이지에 전송을 위한 Stream을 가져오는 매소드 |
getOutputStream() | byte단위로 페이지에 전송을 위한 Stream을 가져오는 매소드 |
sendResdirect(String) | client가 매개변수의 페이지를 다시 서버에 요청하게 하는 매소드 |
GET 방식의 요청
form 태그를 이용한 get 방식 요청
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>parameter</title>
</head>
<body>
<form action="querystring" method="get">
<label>이름 : </label><input type="text" name="name">
<br>
<label>나이 : </label><input type="number" name="age">
<br>
<label>생일 : </label><input type="date" name="birthday">
<br>
<label>성별 : </label>
<input type="radio" name="gender" id="male" value="M"><label for="male">남자</label>
<input type="radio" name="gender" id="female" value="F"><label for="female">여자</label>
<br>
<label>국적 : </label>
<select name="national">
<option value="ko">한국</option>
<option value="ch">중국</option>
<option value="jp">일본</option>
<option value="etc">기타</option>
</select>
<br>
<label>취미 : </label>
<input type="checkbox" name="hobbies" id="movie" value="movie"><label for="movie">영화</label>
<input type="checkbox" name="hobbies" id="music" value="music"><label for="music">음악</label>
<input type="checkbox" name="hobbies" id="sleep" value="sleep"><label for="sleep">취침</label>
<br>
<input type="submit" value="GET 요청">
</form>
</body>
</html>
HttpServlet 클래스의 service 메소드가 요청 방식에 의해
GET 요청은 doGet() 메소드를 호출하며 request와 response를 전달해준다.
service로부터 전달받은 HttpServletRequest는 요청 시 전달한 값을 getParameter() 메소드로 추출해 올 수 있다.
이 때 인자로 input 태그에 지정한 name 속성의 값을 문자열 형태로 전달해주어야 한다.
화면에서 전달한 form 태그 내의 모든 input 태그의 값을 HashMap으로 관리하고 있는데,
원하는 값을 찾기 위해서는 key 역할을 하는 문자열이 필요하기 때문이다.
key 역할을 하는 문자열이 없을 경우 value 속성은 null로 리턴 된다.
WebServlet("/querystring")
public class QueryStringTestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
System.out.println("이름 : " + name);
/* getParameter() 메소드는 리턴 타입이 문자열 형태이다.
* 즉, 숫자를 전달해도 문자열 형태로 전달되므로 숫자로 된 값이 필요하다면
* 검증 후 parsing 해야 한다.
*/
int age = Integer.parseInt(request.getParameter("age"));
System.out.println("나이 : " + age);
/* java.sql.Date 타입으로 날짜 데이터 parsing */
java.sql.Date birthday = java.sql.Date.valueOf(request.getParameter("birthday"));
System.out.println("생일 : " + birthday);
/* radio로 전달 된 값은 여러 값 중 한가지만 전달 되기 때문에
* parameter로 전달 받은 값을 꺼내기만 하면 된다. */
String gender = request.getParameter("gender");
System.out.println("성별 : " + gender);
/* select box를 이용한 방식도 크게 다르지 않음 */
String national = request.getParameter("national");
System.out.println("국적 : " + national);
/*
* 하지만 checkbox는 다중으로 입력 될 수 있기 때문에
* 선택된 값이 문자열이 아닌 문자열 배열의 형태로 전달된다.
* 이 때 getParameterValues() 메소드를 이용하여 문자열 배열 형태로 값을 반환 받을 수 있다.
*/
String[] hobbies = request.getParameterValues("hobbies");
for (String hobby : hobbies) {
System.out.println("취미 : " + hobby);
}
}
}
POST 방식의 요청
form 태그를 이용한 post 방식 요청
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>parameter</title>
</head>
<body>
<form action="formdata" method="post">
<label>이름 : </label><input type="text" name="name">
<br>
<label>나이 : </label><input type="number" name="age">
<br>
<label>생일 : </label><input type="date" name="birthday">
<br>
<label>성별 : </label>
<input type="radio" name="gender" id="male2" value="M"><label for="male2">남자</label>
<input type="radio" name="gender" id="female2" value="F"><label for="female2">여자</label>
<br>
<label>국적 : </label>
<select name="national">
<option value="ko">한국</option>
<option value="ch">중국</option>
<option value="jp">일본</option>
<option value="etc">기타</option>
</select>
<br>
<label>취미 : </label>
<input type="checkbox" name="hobbies" id="movie2" value="movie"><label for="movie2">영화</label>
<input type="checkbox" name="hobbies" id="music2" value="music"><label for="music2">음악</label>
<input type="checkbox" name="hobbies" id="sleep2" value="sleep"><label for="sleep2">취침</label>
<br>
<input type="submit" value="POST 요청">
</form>
</body>
<html>
post 방식으로 전달 받은 데이터에 한글이 있는 경우 한글 값이 깨져서 보인다.
GET 방식의 데이터는 HTML charset에 기술 된 인코딩 방식으로 브라우저가 한글을 이해한 뒤
%문자로 URLEncoder를 이용하여 변환 후 url 요청으로 전송한다.
이 때 헤더의 내용은 알맞게 해석 되어 별도의 charset 설정이 필요 없다.
GET 요청은 보통 서버 쪽 리소스를 가져오는 용도의 행위를 요청하는 http 요청 방식이기 때문에 별도의 데이터가 필요 없어서 요청 본문-body-는 해석하지 않게 된다.
하지만 POST 요청은 서버쪽 리소스에 내용을 추가하는 용도의 요청이기 때문에
요청하는 데이터가 필요한 경우가 많다. 이러한 정보를 요청 본문에 key&value 방식으로 담아 전송하는데,
헤더와는 별개로 URLEncoder를 이용하지 않고 페이지 meta에 기술된 charset에 따라 UTF-8로 해석 된 데이터를 서버로 전송하게 된다.
request.getCharacterEncoding()을 호출해보면 null을 반환하는데,
인코딩 된 방식을 명시해주지 않으면 기본 ISO-8859-1로 해석하게 되어 값을 꺼내오면 글자가 깨지는 현상이 발생한다.
이 때, parameter를 꺼내오기 전에 parameter 값을 해석할 인코딩 방식이 UTF-8임을
setCharacterEncoding(String encType)으로 지정해주면 브라우저 요청 인코딩 방식과 일치하게 되어
한글 깨짐 현상을 막을 수 있다.
@WebServlet("/formdata")
public class FormDataTestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println(request.getCharacterEncoding());
/* 파라미터 값을 꺼내기 전에 디코딩할 인코딩 방식을 지정해주면
* 해당 방식으로 본문의 값을 해석한다. */
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
System.out.println("이름 : " + name);
/* 인코딩을 제외한 나머지 값들은 GET 방식에서 값을 꺼내온 것과 동일하다. */
/* 만약 클라이언트 쪽에서 요청한 데이터의 key와 value를 일일히 확인하기 힘들다면
* 모든 데이터의 key를 이용하여 전송 된 값들을 일괄 처리할 수도 있다.
* */
Map<String, String[]> requestMap = request.getParameterMap();
Set<String> keySet = requestMap.keySet();
Iterator<String> keyIter = keySet.iterator();
while(keyIter.hasNext()) {
String key = keyIter.next();
String[] value = requestMap.get(key);
System.out.println("key : " + key);
for(int i = 0; i < value.length; i++) {
System.out.println("value[" + i + "] : " + value[i]);
}
}
/* 파라미터로 전달 된 키 목록만도 확인할 수 있다.
* request.getParameterNames()를 이용한다.
* */
Enumeration<String> names = request.getParameterNames();
while(names.hasMoreElements()) {
System.out.println(names.nextElement());
}
}
}
'백엔드 과정 > Servlet' 카테고리의 다른 글
[Servlet] sendRedirect VS RequestDispatcher (0) | 2022.03.06 |
---|---|
[Servlet] Response 응답 확인하기 (0) | 2022.03.06 |
[Servlet] 서블릿 라이프 사이클 (0) | 2022.03.04 |
[Servlet] 서블릿 개요 (0) | 2022.03.04 |
[Servlet] tomcat 설치 및 개발환경 구축 (0) | 2022.03.04 |