---
title: "Java EE 정리 03"
date: "2019-02-27"
tags: ["Java EE","Servlet"]
status: archived
verified: false
---

---

## HttpServletRequest

![01](/md/legacy-assets/javaEe/03/01.webp)

* **요청에 대한 처리**
     * 접속자의 정보, 접속자가 입력하는 값들에 대한 처리
* **웹에서 옮겨다니는 데이터는 String 밖에 없다.**

```java
// 요청 URL :http://localhost:8080/servlet_prj/test?이름=값&이름=값...
// http - protocol
// localhost - domain
// 8080 - port
// ? 전까지가 URL, ?뒤는 Query String("이름=값" Parameter들로 이루어짐)
// servlet_prj/test 가 URI(Servlet Path)

// 요청 방식
String method = req.getMethod();

// 요청 URL
StringBuffer url = req.getRequestURL(); // http://localhost:8080/servlet_prj/test

// 요청 URI (ContextPath를 포함)
String uri = req.getRequestURI(); // servlet_prj/test

// 요청 protocol
String protocol = req.getProtocol(); // HTTP/1.1(요청 프로토콜) 

// 서버 이름 (도메인)
String serverName = req.getServerName(); // localhost(도메인)

// 서버 포트
int serverPort = req.getServerPort(); // 8080(서버 포트)

// 서블릿 경로 (ContextPath 제외한 하위 경로)
String servletPath = req.getServletPath(); // /test

// 요청한 접속자의 IP얻기
String clientIp = req.getRemoteAddr(); // 211...

// 요청한 접속자의 Port
int clientPort = req.getRemotePort(); // 클라이언트가 연 PORT

// QueryString 얻기 - GET방식만 사용가능, POST방식일 땐 null반환
String queryString = req.getQueryString(); // 이름=값&이름=값...

// Parameter 값 받기 - GET/POST 상관없이 받을 수 있음, 동명 Parameter가 존재해도 첫번째 값만 반환
String paramVal = req.getParameter("이름"); // 값

// 이름이 같은 Parameter 값 받기
String[] pramVals = req.getParameterValues("이름"); // [값, 값,...]

// Parameter의 이름받기
Enumeration<String> paramNames = req.getParameterNames(); 
```

* **HttpServletRequest 사용 예**

```java
...
out.println("\t\t<ul>");

out.print("\t\t\t<li><strong>요청 방식</strong> : ");
out.print(req.getMethod());
out.println("</li>");

out.print("\t\t\t<li><strong>요청 URL</strong> : ");
out.print(req.getRequestURL());
out.println("</li>");

out.print("\t\t\t<li><strong>요청 URI</strong> : ");
out.print(req.getRequestURI());
out.println("</li>");

out.print("\t\t\t<li><strong>요청 프로토콜</strong> : ");
out.print(req.getProtocol());
out.println("</li>");

out.print("\t\t\t<li><strong>요청 서버 이름</strong> : ");
out.print(req.getServerName());
out.println("</li>");

out.print("\t\t\t<li><strong>요청 서버 포트</strong> : ");
out.print(req.getServerPort());
out.println("</li>");

// Servlet Path는 Context Path를 제외한 하위 경로
out.print("\t\t\t<li><strong>요청 서블릿 경로</strong> : ");
out.print(req.getServletPath());
out.println("</li>");

out.print("\t\t\t<li><strong>접속자의 IP</strong> : ");
out.print(req.getRemoteAddr());
out.println("</li>");

out.print("\t\t\t<li><strong>접속자의 PORT</strong> : ");
out.print(req.getRemotePort());
out.println("</li>");

out.print("\t\t\t<li><strong>요청 Query String</strong> : ");
out.print(req.getQueryString());
out.println("</li>");

out.print("\t\t\t<li><strong>Parameter 값 받기</strong> : ");
out.print(req.getParameter("name"));
out.println("</li>");

out.print("\t\t\t<li><strong>이름이 같은 Parameter 값  받기</strong> : ");
String[] ages = req.getParameterValues("age");
if (ages != null) {
     for(String age : ages) {
           out.print(age+"살&nbsp;");
     }
} else {
     out.print("나이 없음.");
}
out.println("</li>");

out.print("\t\t\t<li><strong>Parameter의 이름받기</strong> :  ");
Enumeration<String> paramNames = req.getParameterNames();
while(paramNames.hasMoreElements()) { // 파라미터 이름이  있다면
     // 값을  가져오고 다음 요소로 포인터를 이동
     out.print(paramNames.nextElement()+"&nbsp;"); 
}
out.println("</li>");

out.println("\t\t</ul>");
...
```

![02](/md/legacy-assets/javaEe/03/02.webp)


* **print와 println의 차이**
     * **브라우저 "소스보기"에선 줄이 바뀌고 안바뀌고의 차이**
     * **소스코드를 잘 보여주기 위해 print와 println을 구분해서 사용해야 한다.**

```java
out.print("aaaaa");
out.println("aaaaa");
out.println("bbbbb");
```

![03](/md/legacy-assets/javaEe/03/03.webp)

```java
out.print("<a href='");
out.print("test.jsp'>클릭");
out.println("</a>");
out.println("<br/>");
```

![04](/md/legacy-assets/javaEe/03/04.webp)

* **접속자 IP를 얻는 메소드(getRemoteAddr)를 이용해서 접속자를 막을 수 있다.**

```java
String clientIp = req.getRemoteAddr();
String[] blockIp = { "133","141","149","157","144","152" };

boolean moveFlag = false;

for(String ip : blockIp) {
     if (clientIp.endsWith(ip)) {
           moveFlag = true;
     }
}

if(moveFlag) {
     resp.sendRedirect("http://www.police.go.kr/main.html"); // 경찰청으로~
}
```

## HTML Form Control의 입력값 받기

* **Parameter로 처리**
     * **데이터형은 모두 String으로 전달된다.**
* **name 속성이 중요**
     * name이 틀리면 값을 못 받아온다.
     * **id 속성은 CSS 디자인 변경 또는 JS, jQuery에서 DOM접근시에 중요**

```html
<input name="ooo" ... >
<select name="ooo" ... >
<textarea name="ooo" ... >
```

* **name을 기반으로 QueryString이 만들어진다.**

```
서블릿명?a=입력한값&b=사용자가선택한값&c=입력한값... 
```

* **Parameter명이 유일할 때**
     * input태그 type이 text, password, hidden, checkbox(1개 선택), radio 등
     * select태그, textarea태그 

```java
String val = req.getParameter("이름");
```


* **Parameter명이 중복될 때**
     * input 태그 type이 checkbox

```java
String[] vals = req.getParameterValues("이름");
```

* **HTML Form Control 입력값 받기 예**

```html
...
<!-- jQuery CDN -->
<script  src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript">
     $(document).ready(function() {
           $("#btnGet").click(function() {
                // HTML Form Control의 유효성 검증 후
                $("#getFrm").submit();
           });
           $("#btnPost").click(function() {
                // HTML Form Control의 유효성 검증 후
                $("#postFrm").submit();
           })
     });
</script>
...
<!-- test_param.html -->
<body>
<div id="getDiv">
     <h2>이름이 유일한 HTML Form Control 값 전송</h2>
     <form method="get" action="../param_value" id="getFrm">
           <table>
                <tr>
                     <td><label>이름</label></td>
                     <td><input type="text" name="name"  class="inputBox"></td>
                </tr>
                <tr>
                     <td><label>나이</label></td>
                     <td><input type="password" name="age"  class="inputBox"></td>
                </tr>
                <tr>
                     <td><label>메일링여부</label></td>
                     <!-- checkbox가 하나라면 배열로 처리되지  않는다. -->
                <td><input type="checkbox"  name="mailing">수신</td>
           </tr>
           <tr>
                <td><label>성별</label></td>
                <td>
                     <input type="radio" name="gender"  value="남자" checked="checked">남자
                     <input type="radio" name="gender"  value="여자">여자
                </td>
           </tr>
           <tr>
                <td><label>숨김값</label></td>
                <td>
                     <input type="hidden" name="addr"  value="서울시 강남구 역삼동 한독빌딩">
                </td>
           </tr>
           <tr>
                <td><label>사용메일</label></td>
                <td>
                     <select name="email" class="inputBox">
                           <option  value="gmail.com">---지메일---</option>
                           <option  value="naver.com">---네이버메일---</option>
                           <option  value="daum.com">---다음메일---</option>
                           <option  value="korea.com">---코리아메일---</option>
                           <option  value="hotmail.com">---핫메일---</option>
                     </select>
                </td>
           </tr>
           <tr>
                <td><label>가입인사</label></td>
                <td><textarea style="width:300px; height:100px;  name=""></textarea></td>
                </tr>
                <tr>
                     <td colspans="2">
                           <input type="button" value="전송"  class="btn" id="btnGet">
                     </td>
                </tr>
           </table>
     </form>
</div>
<div id="postDiv">
     <h2>이름이 유일한 HTML Form Control 값 전송 POST</h2>
     <form method="post" action="../param_value" id="postFrm">
           <table>
                <tr>
                     <td><label>이름</label></td>
                     <td><input type="text" name="name"  class="inputBox"></td>
                </tr>
                <tr>
                     <td><label>나이</label></td>
                     <td><input type="password" name="age"  class="inputBox"></td>
                </tr>
                <tr>
                     <td><label>메일링여부</label></td>
                     <!-- checkbox가 하나라면 배열로 처리되지  않는다. -->
                <td><input type="checkbox"  name="mailing">수신</td>
           </tr>
           <tr>
                <td><label>성별</label></td>
                <td>
                     <input type="radio" name="gender"  value="남자" checked="checked">남자
                     <input type="radio" name="gender"  value="여자">여자
                </td>
           </tr>
           <tr>
                <td><label>숨김값</label></td>
                <td>
                     <input type="hidden" name="addr"  value="서울시 강남구 역삼동 한독빌딩">
                </td>
           </tr>
           <tr>
                <td><label>사용메일</label></td>
                <td>
                     <select name="email" class="inputBox">
                           <option  value="gmail.com">---지메일---</option>
                           <option  value="naver.com">---네이버메일---</option>
                           <option  value="daum.com">---다음메일---</option>
                           <option  value="korea.com">---코리아메일---</option>
                           <option  value="hotmail.com">---핫메일---</option>
                     </select>
                </td>
           </tr>
           <tr>
                <td><label>가입인사</label></td>
                <td><textarea style="width:300px; height:100px;  name=""></textarea></td>
                </tr>
                <tr>
                     <td colspans="2">
                           <input type="button" value="전송"  class="btn" id="btnPost">
                     </td>
                </tr>
           </table>
     </form>
</div>
```

![05](/md/legacy-assets/javaEe/03/05.webp)

![06](/md/legacy-assets/javaEe/03/06.webp)

```java
/**
* HTML Form Control의 값 받기
* UseWebParameter.java
*/
@SuppressWarnings("serial")
public class UseWebParameter extends HttpServlet {
    
     @Override
     protected void doGet(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
          resp.setContentType("text/html;charset=utf-8");
          PrintWriter out = resp.getWriter();
          
          ...

          // Parameter 값 받기 : Tomcat 8.0부터는 GET방식의  Parameter는 한글이 깨지지 않는다.
          String name = req.getParameter("name"); // text
          String age = req.getParameter("age"); // password
          String mailing = req.getParameter("mailing"); //  checkbox
          String gender = req.getParameter("gender"); // radio
          String addr = req.getParameter("addr"); // hidden
          String email = req.getParameter("email"); // select
          String greeting = req.getParameter("greeting"); //  textarea
          
          out.println("\t<div>");
          out.println("\t<h2>GET방식으로 요청한 파라미터 값  처리</h2>");
          out.println("\t<div>");
          out.println("\t\t<ul>");
          
          out.print("\t\t\t<li> 이름 : <strong>");
          out.print(name);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 나이 : <strong>");
          out.print(age);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 메일링 여부 : <strong>");
          out.print(mailing); // value 속성이 없는 checkbox는 check되면 on, check되지 않으면 null
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 성별 : <strong>");
          out.print(gender);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 주소 : <strong>");
          out.print(addr);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 이메일 : <strong>");
          out.print(email);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 가입인사 : <strong>");
          out.print(greeting);
          out.println("<strong></li>");
          
          out.println("\t\t</ul>");
          out.println("\t</div>");
          out.println("\t<a  href='date0227/test_param.html'>뒤로</a>");
          out.println("\t</div>");
          
          ...
     }
     
     @Override
     protected void doPost(HttpServletRequest req,  HttpServletResponse resp) throws ServletException, IOException {
          resp.setContentType("text/html;charset=utf-8");
          PrintWriter out = resp.getWriter();
          
          ...

          // Parameter 값 받기 : GET, POST 동일
          String name = req.getParameter("name"); // text
          String age = req.getParameter("age"); // password
          String mailing = req.getParameter("mailing"); //  checkbox
          String gender = req.getParameter("gender"); // radio
          String addr = req.getParameter("addr"); // hidden
          String email = req.getParameter("email"); // select
          String greeting = req.getParameter("greeting"); //  textarea
          
          out.println("\t<div>");
          out.println("\t<h2 style='color:blue;'>POST방식으로  요청한 파라미터 값 처리</h2>");
          out.println("\t<div>");
          out.println("\t\t<ul>");
          
          out.print("\t\t\t<li> 이름 : <strong>");
          out.print(name);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 나이 : <strong>");
          out.print(age);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 메일링 여부 : <strong>");
          out.print(mailing); 
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 성별 : <strong>");
          out.print(gender);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 주소 : <strong>");
          out.print(addr);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 이메일 : <strong>");
          out.print(email);
          out.println("<strong></li>");
          
          out.print("\t\t\t<li> 가입인사 : <strong>");
          out.print(greeting);
          out.println("<strong></li>");
          
          out.println("\t\t</ul>");
          out.println("\t</div>");
          out.println("\t<a  href='date0227/test_param.html'>뒤로</a>");
          out.println("\t</div>");
          
          ...
     }
}
```

![08](/md/legacy-assets/javaEe/03/08.webp)

* **요청방식이 잘못 됐을 때 떨어지는 에러는 405**
     * doGet메소드 주석처리하고 URL로 호출하면 처리할 method를 찾지 못해 에러가 떨어진다.
     * **보통 에러페이지를 따로 만들어서 에러가 발생하면 그 페이지를 보여주도록 처리한다.**

![07](/md/legacy-assets/javaEe/03/07.webp)

## Tomcat 한글처리

* **세팅되는 Tomcat 버전에 따라 다르게 코딩 해야 한다.**
     * **POST 방식 톰캣 어떤 버전을 사용하든 한글이 깨진다.**
     * **Tomcat 8 이전 버전은 GET방식의 Parameter 값 받으면 한글이 깨진다.**
     *** Tomcat 8 버전부터는 GET방식의 Parameter는 한글이 깨지지 않는다.**
* **Dynamic Web Project의 장점**
     * 다양한 서버환경에서 실행해볼 수 있다.
     * Tomcat 7, 8 등 등록하고 테스트가 가능

![09](/md/legacy-assets/javaEe/03/09.webp)

![10](/md/legacy-assets/javaEe/03/10.webp)

![11](/md/legacy-assets/javaEe/03/11.webp)


* **한글이 깨지는 이유는 값을 패킷단위로 전송(1byte, 8bit) 하기 때문**
  * **UTF-8에서 한글 한 글자는 3byte**
  	* 한글을 패킷단위 3개로 분리해서 전달(**인코딩**)
  	* **한글자 -> %값%값%값**
     * **인코딩된 글자를 서버가 전달받고 인코딩된 내용을 그대로 화면에 찍기 때문에 깨져서 보이는 것**
* **UTF-8**
	* 한글 한 글자당 3byte
	* 한글 한글자를 3개의 byte로 인코딩 후 전송
* **EUC-KR**
	* 한글 한 글자당 2byte
	* 한글 한글자를 2개의 byte로 인코딩 후 전송
* **name값으로 "홍길동" 입력 후 GET방식으로 전달했을 때**

![12](/md/legacy-assets/javaEe/03/12.webp)

* **인코딩한 charset에 따라 받는 쪽에서 재조합(인코딩)을 해야 한글이 깨지지 않는다.**
  * 전체 흐름으로 보면 클라이언트측 인코딩 후 서버측 디코딩
  * 개별로 보면 클라이언트는 클라이언트 대로 서버는 서버대로 인코딩을 수행한 것
* **재조합(인코딩)**
  * 전달받은 값을 byte배열로 만들고 새로운 charset으로 인코딩하여 새로운 문자열을 생성

```java
String s = req.getParameter("name"); 
// s엔 %값%값... 클라이언트에서 인코딩된 한글이 저장되어 있음

// 1. String클래스 getBytes메소드로 s를 바이트 배열로 바꾼다. 
// (8859_1은 영어,숫자, 특수문자를 나타내는 charset)
// 2. String 클래스의 생성자로 바이트배열을 UTF-8로 서버측 인코딩을 수행(3바이트를 1글자로)
new String(s.getBytes("8859_1"), "UTF-8");
```

![13](/md/legacy-assets/javaEe/03/13.webp)

* **입력값을 한글로 인코딩하는 클래스**

```java
public class HangulConv {
     public static String toUTF(String kor) { // UTF-8로 인코딩
          // empty를 물어 볼 때 kor.equals("")하면 kor이  null일 경우 NullPointException이 발생
          // 따라서 이제 엠티를 비교할 땐 "".equals(kor)로  처리를 한다.
          try {
               if (kor != null || !"".equals(kor)) { //  null이나 empty가 아니면 변환
                    kor = new String(kor.getBytes("8859_1"),"UTF-8");
               }
          } catch (UnsupportedEncodingException e) {
               e.printStackTrace();
          }
          
          return kor;
     }

     public static String toEUC(String kor) { // EUC-KR로 인코딩
          try {
               if (kor != null || !"".equals(kor)) { 
                    kor = new  String(kor.getBytes("8859_1"),"EUC-KR");
               }
          } catch (UnsupportedEncodingException e) {
               e.printStackTrace();
          }
          
          return kor;
     }
}
```

* **GET방식일 경우 항목마다 한글처리를 해줘야 한다.**

```java
String name = req.getParameter("name"); 

...

out.print("\t\t\t<li> 이름 : <strong>");
out.print(HangulConv.toUTF(name)); // 이런식으로 필요할 때 한글처리를 해준다.
out.println("<strong></li>");
```

```java
// Tomcat 8.5로 실행시킨 코드, 자동으로 인코딩해주기 때문에 한글처리 필요가 없다.
// doGet method
...
out.print("\t\t\t<li> 이름 : <strong>");
// out.print(HangulConv.toUTF(name)); Tomcat 8.x 이하 일때는  한글 처리를 해야한다.
out.print(name);
out.println("<strong></li>");

out.print("\t\t\t<li> 나이 : <strong>");
out.print(age);
out.println("<strong></li>");

out.print("\t\t\t<li> 메일링 여부 : <strong>");
out.print(mailing); 
out.println("<strong></li>");

out.print("\t\t\t<li> 성별 : <strong>");
// out.print(HangulConv.toUTF(gender));
out.print(gender);
out.println("<strong></li>");

out.print("\t\t\t<li> 주소 : <strong>");
// out.print(HangulConv.toUTF(addr));
out.print(addr);
out.println("<strong></li>");

out.print("\t\t\t<li> 이메일 : <strong>");
out.print(email);
out.println("<strong></li>");
out.print("\t\t\t<li> 가입인사 : <strong>");
// out.print(HangulConv.toUTF(greeting));
out.print(greeting);
out.println("<strong></li>");
...
```

![14](/md/legacy-assets/javaEe/03/14.webp)

* **인코딩이 두번되면 모든 문자가 ?가 되버린다.**

```java
out.print(HangulConv.toUTF(HangulConv.toUTF(name))); // 두번 인코딩
```

![15](/md/legacy-assets/javaEe/03/15.webp)


* **Tomcat 8.5는 GET방식일 경우 자동으로 인코딩을 수행한다.**
     * **때문에 또 인코딩을 시키면 인코딩이 두번 되어 글자가 ?가 되어버린다.**
       * Tomcat 8.5에서는 인코딩을 또 수행할 필요가 없다.

![16](/md/legacy-assets/javaEe/03/16.webp)

## POST 방식의 한글처리

* **request객체가 제공하는 method를 사용하기 전에 코딩해야 한다.**
     * **Tomcat 모든 버전에서 동일하게 적용**
     * 보통 첫줄에 코딩해줌

```java
request.setCharacterEncoding("인코딩할 chatset");
```

![17](/md/legacy-assets/javaEe/03/17.webp)


* **주의**
     * **요청처리 객체가 미리 사용되면 setCharacterEncoding메소드 내용은 수행되지 않는다.**
     * setCharacterEncoding은 요청처리 객체 request가 사용되기 전에 미리 작업해야 된다.

```java
String name = req.getParameter("name"); 
String age = req.getParameter("age"); 
req.setCharacterEncoding("UTF-8"); // req가 사용되고 설정하면 적용되지 않음. 
String mailing = req.getParameter("mailing"); 
String gender = req.getParameter("gender"); 
String addr = req.getParameter("addr"); 
String email = req.getParameter("email"); 
String greeting = req.getParameter("greeting"); 
```

![18](/md/legacy-assets/javaEe/03/18.webp)
