현 블로그는 모바일 환경이 아닌 PC환경에 최적화 되어있습니다.

 Mir의 운영환경

자 이전 Chapter3에서 서블릿의 기본개념과 문자를 출력해보는 방법을 배워보았다.

이번엔 서블릿을 이용하여 Data를 받고 난뒤 charset까지 맞추는 방법을 해워보자.

 우선 간단히 이름과 아이디를 전송하는 html 파일을 만들어 보자.

<html>

<body>

<h3>서블릿을 이용한 파라미터 전달...</h3>

<form method="post,get" action="">

<table>

   <tr>

     <td>이름</td>

     <td><input type="text" name="name"></td>

   </tr>

   <tr>

     <td>아이디</td>

     <td><input type="text" name="id"></td>

   </tr>

   <tr>

     <td colspan="2" align="center">
             <
input type="submit" value="전송">

     <input type="reset" value="초기화"></td>

   </tr>

</table>

        </form>

</body>

</html>

이정도 간단한 html은 할줄 알아야 한다.
(필자가 예전에 정리해둔 텍스트 파일이 사라져서 다시 정리할려면 조금 오래 걸릴듯 하다 ㅠㅠ)

아무튼 위 HTML에서 제일 중요한것이 전송방식(method)의 두종류 post와 get이다.

이번파트에서는 get방식을 기본으로 진행하겠다.



자 그럼 method를 get방식으로 하고 action을 servlet/paratest 으로 지정해주자.

action은 이 from을 전송할곳을 가르키는 곳인데 servlet/paratest라고 지정해주면
form에 입력된 값을 가지고 servlet/paratest 페이지로 이동하게 된다.
(말로 설명하는거 보다 조금있다 한번 해보게 되면 확실하게 이해할것이다.)

자 그럼 ParaTest.java파일을 만들어 보자.

자 이전파트에서 서블릿의 제약조건에 대해서 꼭 Servlet을 implements해줘야 된다고 말했었다.
하지만 Servlet를 참조할때 구현해야 될 추상메소드가 5개나 되기때문에
미리 Servlet를 참조한 GenericServlet를 상속받으면 service( ) 메소드 하나만 구현해도 된다고 말했엇다.

service( )메소드에서도 물론 data를 받고 logic을 구하고 모두다 할수 있지만
우리가 data를 받을때에 http:// 즉 웹상에서 data를 받기때문에 따로 HTTP의 처리에 관한 설정을 해줘야 한다.

하지만 여기서 GenericServlet를 상속받은 하위 클래스 HttpServlet란 클래스가 있는데
이 클래스는 HTTP에 관련된 처리와 부가기능까지 추가된 클래스이다.

즉 웹상에서 Data를 주고 받을때에는 HttpServlet을 상속받는게 훨씬더 편하다는 뜻이다.

물론 이전파트에서도 HttpServlet를 사용할수도 있었지만 GenericServlet란 클래스도 있다는 점과
Servlet 인터페이스의 구현, 상속과정을 알아두는것이 도움이 된다는 생각에 GenericServlet 클래스를 상속받았엇다.

그럼 이번엔 HttpServlet를 상속받아보자.

import javax.servlet.http.*;


public class ParaTest extends HttpServlet{ }

자 HttpServlet을 상속받고 난뒤 HttpServlet클래스의 api를 한번 보면 
HttpServlet도 추상클래스로 정의 되어있는데  이상하게 추상메소드가 없다.

이러한 클래스를 의미상의 추상클래스라고 부르는데
의미상의 추상클래스는 추상메소드가 없는대신에 그 클래스에 속한 메소드를 하나이상은 꼭 구현해주어야 한다.

HttpServlet에도 service( )메소드가 있지만 그것 보다 더욱 편하게 값을 가져올수 있는
doPost( )와 doGet( )이란 메소드가 존재한다.

메소드 이름그대로 전송방식을  post방식을 사용한다 아니면 get방식을 사용한다라고 해석하면 될것이다.

자 그럼 우리는 get방식으로 전송하기로 했으니 doGet( )메소드를 사용해보자.

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;


public class ParaTest extends HttpServlet{



public void doGet(HttpServletRequest req, HttpServletResponse res)

throws IOException, ServletException{

}

자 그럼 제약조건은 모두 클리어 했다. 이제 할일을 한번 생각해보자.
1.data get
2.logic 구현
3.repose

사용자가 전송하는 Data는 즉 사용자가 요청 request하는 값이라고 생각하면 더 편하다.
왜냐면 전송한 데이터를 받는 메소드가 ServletRequest에 속해있기때문이다.

자 그럼 데이터를 받아보자. 데이터를 받는 메소드는 getParameter( )이란 메소드로 받으면 된다.
위 html에서 데이터를 전송할때 이름은 name 아이디는 id라는 변수에 넣어서 보낸다고 되어있다.
(Html파일의 input 부분을 보면 name이 보이는데 여기에 적힌 이름이 변수의 이름이 된다.)

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

String id = req.getParameter("id");

그럼 위와 같이 보내는 변수의 이름을 메소드에 인자로 넣어주면 String형 변수 name에 전송된 Data값이 저장된다.
(굳이 보내는 변수의 이름과 받는 변수의 이름을 꼭 일치시켜야 될 필요는 없다.)

자 그다음 Logic을 구현해보자.

뭐 그렇게 크게 구현할 필요는 없고 간단하게
String msg = name + "님 의 아이디는 "+ id +" 입니다.";
정도로만 구현하도록 하자.

출력문은 이전 HelloServlet에 사용한 문장 그대로 사용해도 상관없을듯 하다.

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;


public class ParaTest extends HttpServlet{



public void doGet(HttpServletRequest req, HttpServletResponse res)

throws IOException, ServletException{

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

String id = req.getParameter("id");

        String msg = name + "님의 아이디는" + id + "입니다."; 

        PrintWriter out = res.getWriter();

 

        out.println("<html>");

out.println("<body>");

out.println(msg);

out.println("</body>");

out.println("</html>");

        }


 }


자 그럼 서블릿을 한번 실행해보자.

이전과 똑같이 ParaTest.class파일을 톰켓설치 폴더의 webapps/ ROOT / WEB-INF / classes에 넣고 
위에서 작성한 paratest.html파일을 webapps/ROOT 폴더에 넣어주자.
그리고 주소창에 http://localhost:8080/paratest.html을 치게되면 우리가 만든 html페이지가 보일것이다.
(이클립스와 톰켓을 벌써 연동한 사람들은 아무 다이나믹 웹프로젝트의 test패키지를 생성 자바파일을 넣어두고
 html파일은 프로젝트의 WebContent폴더에 가져다 놓고 html을 바로 실행시키면 된다.
아 그리고 html에서 action을 servlet/프로젝트이름/test.paratest 로 수정해주어야 한다.)


혹시 html이 필자처럼 한글이 깨진다면 ;;; 

html파일안에 <html>과 <body>사이에

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

</head>

위 소스를 입력한후에 실행해 보자.

자 이름과 아이디를 적은후에 확인키를 눌러보자!! 다들 글자가 깨져서 나올것이다.
만약 글자가 깨져서 안나오는 사람이 있으면.... 신기한거다 ;;

필자는 誘몃Ⅴ?? ????jomousejo???. 로 출력되었다.

자 이것은 바로 위의 html페이지의 글이 깨지는것과 같은 증상인데
html에서 한글을 인식하지 못하는 것이다.

위 html소스에서는 필자가 준 소스를 추가를 시켜줌으로 간단히 해결할수 있다.
물론 Servlet에서도 출력문을 작성할때 위 소스와 똑같이 작성해줘도 되지만
좀더 간단한 방법이 있다.

바로 reponse클래스의 setContentType( )란 메소드를 사용하면 된다.
그럼 모두 서블릿에 아래 소스를 추가해보도록 하자.

res.setContentType("text/html; charset=UTF-8");

 
위 소스를 잘못 추가시키면 적용이 되지 않는데 어느부분에 추가시켜줘야 되는지는 한번 스스로 알아보도록 해보자 ;ㅁ;


import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;


public class ParaTest extends HttpServlet{



public void doGet(HttpServletRequest req, HttpServletResponse res)

throws IOException, ServletException{

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

    String id = req.getParameter("id");


    String msg = name + "님의 아이디는" + id + "입니다."

    

    res.setContentType("text/html; charset=utf-8");

        

    PrintWriter out = res.getWriter();

 

    out.println("<html>");

out.println("<body>");

out.println(msg);

out.println("</body>");

out.println("</html>");

        }


 }


자 위와 같이 getWriter( )메소드를 사용하기 전에 추가를 시켜줘야 한다.
그 아래에 추가를 시키면 이미 모든 값을 출력할려고 트럭에 모든 짐을 싫어놓았는데
갑자기 언어를 바꿔서 출력하라고 명령이 떨어진것이다. 

짐을 다 내려놓고 바꿔도 되겠지만 getWriter( )메소드는 게을러서 그런지 그냥 그대로 내보내게 된다.
꼭 getWriter( )메소드 전에 넣어야 된다는거 까먹지 말도록 하자.

자 그렇게 한글을 인식하게 만들어 놨지만 아직도 깨지는 부분이 있다.
바로 한글로 이름을 적은 부분인데

필자는 
미르님의 아이디는mirwebma입니다.처럼 출력된다. 
자! 여기서 주소창을 한번 보도록 하자.
흠 ;; 필자는 사파리를 사용해서 그런지 아래와 같이 주소창이 적어진다.
http://localhost:8080/servlettest/servlet/ParaTest2?name=미르&id=mirwebma
보통 익스플로러에서는 미르라는 한글부분이 %B9%CC%B8%A3 이런 형태의 모습으로 보일것이다.
뭐 한글로 보여도 별반 상관은 없다.

자 한글이 깨지는 이유는 보통 Browser에서 기본적으로 사용하는 언어팩은 ISO-8859-1이란 언어를 사용한다.
이 언어는 2byte표현의 언어이며 한글같은 경우는 %B9%CC%B8%A3 형태로 표현이 된다.
(요 부분 확실하지 않다 ;; )

영어같은 경우는 원래 1byte단위의 언어라 이리번역되거나 저리번역되거나 거의 그대로이지만
한글 같은경우에는 언어팩 마다 표현방식이 다르게 된다.

그래서 우리는 ISO-8859-1의 언어팩을 byte단위의 언어로 다시 변환 시켰다가
그 byte단위의 언어를 재조립 하여 4byte의 euc-kr언어팩이나 8byte의 utf-8의 언어로 조립해줘야 한다.

자 그럼 ISO-8859-1을 byte단위로 한번 나눠보자.

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

byte b[] = name.getBytes("ISO-8859-1");

getParameter( )로 name에 있는 ISO-8859-1의 Data값을 받은 후에
getBytes( )메소드로 Data를 byte단위로 나누면 된다.
여기서 원래 어떤 언어인지 표시를 해줘야 하기 때문에 getBytes( )메소드에 인자로 ISO-8859-1을 넣어주면 된다.
(byte단위로 여러개 나눠지기때문에 배열로 받아줘야 한다. )

자 byte단위로 모두다 나눴으면 이제 조립을 해줘야 한다.
조립을 할때에는 new String( )라는 메소드를 사용하게 된다.

name = new String(b, "UTF-8");

new String( )메소드는 두개의 인자를 받게 되는데 
하나는 조립할 부품이 있는 배열의 참조변수와 
나머지 하나는 어떤 언어팩으로 조립할지 인자로 주어야 한다.
필자는 utf-8의 언어팩으로 조립을 하기로 했다. 
(위의 html 언어 설정에 보면 charset이 utf-8로 설정해주었기때문에 euc-kr로 조립하면 다시 깨지게 된다.)

자 그럼 완성된 소스코드를 보자.

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;


public class ParaTest2 extends HttpServlet{



public void doGet(HttpServletRequest req, HttpServletResponse res)

throws IOException, ServletException{

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

    byte b[] = name.getBytes("ISO-8859-1");

    name = new String(b, "UTF-8");

    String id = req.getParameter("id");


    String msg = name + "님의 아이디는" + id + "입니다."

    

    res.setContentType("text/html; charset=utf-8");

        

    PrintWriter out = res.getWriter();

 

    out.println("<html>");

out.println("<body>");

out.println(msg);

out.println("</body>");

out.println("</html>");

        }


 }


다시 우리가 만든 웹페이지를 실행시키면 이젠 한글이 깨지지 않는것을 확인할수 있다.


자 이번챕터에서 get방식으로 전송하였을때 Data를 얻는 방법과 한글 설정하는 방법에 대해 알아보았다.
다음 챕터에서는 post방식으로 전송을 해보고 또 다른 한글 설정방법을 알아보도록 하자.

마지막으로 이 챕터를 다본사람들은 

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

byte b[] = name.getBytes("ISO-8859-1");

name = new String(b, "UTF-8");

이 한글로 바꾸는 소스를 한줄로 줄여보기 바란다. (숙제다 ;;)

 




 

+ Recent posts