프로젝트 생성
서블릿은 Java에서 HTTP 통신을 쉽게 처리할 수 있는 기술
회원가입 페이지를 만들 것이다 원래라면 외부와 통신하려면 서버소켓, 버퍼, 파싱 등등 직접 만들어넣어야 한다. (* 심지어 파싱은 내가 프로토콜을 다 알아야 함) 하지만 서블렛을 사용하면 http 통신을 쉽게할 수 있다! HttpServlet을 상속받고 식별자를 식별할 수 있는 @WebServlet을 어노테이션 하라
이것만 있으면 통신이 쉽게 딱! = 이게 서블렛 이제 실행해보자!
이렇게 나오네? 컨택스트 패스 지우고 다시 실행해보자
/join-form 으로 호출하면 (식별자가 오면) service 안에 있는 내용물이 출력된 것 확인! 서블렛은 이렇게, 소켓도 버퍼도 내가 안 달았는데 통신을 슝 해준다. 일단... 간단한 회원가입 디자인을 코딩해서 /join-form을 요청했을 때, 해당하는 페이지가 뜨게 만들어보자
form 태그와 name (HTML 코드 넣기)
* 자바 Language level 변경하기 원래는 이 문법을 자바 21이 지원하는데... 지금은 안된다. 그리고 이 안에 아래의 html 코드를 붙여넣자.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>회원가입 페이지</h1> <hr> <form action="/join" method="post"> <input type="text" placeholder="username" name="username"> <input type="text" placeholder="password" name="password"> <input type="text" placeholder="email" name="email"> <button>회원가입</button> </form> </body> </html>
[ 회원가입 페이지 HTML 코드를 넣었다 ]
지금 보면 input 태그가 모두 form 태그 안에 들어가있다. <form> 태그의 action 속성에는 데이터를 전송할 URL을 지정한다. 그럼 <input> 태그에 입력된 데이터를 함께 전송할 수 있다. (지금 이 상황에선 input 태그에 입력된 데이터가 /join 경로로 POST 메소드를 통해 전송 됨) (왜 /join이냐면, @WebServlet("/join") 이라고 입력해 놨으니까.)
때문에 /join-form 을 통해서 회원가입 버튼을 누르면, /join으로 날아감 근데 처리를 하기 위해선 'key-value' 값이 같이 날아와야한다. 그러나... 인풋태그의 정보는 사용자가 입력하기 때문에 key값이 없는 상태! 개발자가 따로 key값을 설정해줘야 한다. 그게 바로 HTML input 코드에서 'name' 란! (name = key값) <input type="text" placeholder="username" name="username">
form 태그
모든 input태그의 데이터를 특정 url로 한방에 전송하는 태그!
(웹 페이지에서 사용자 입력을 받고, 입력된 데이터를 서버로 전송하는 기능을 제공)
* form태그가 없으면 input 태그의 데이터를 하나하나 보내야 함
name
= 키 값 설정!! 이 키 값을 설정하지 않거나, 오타가 나면 정보가 들어오지 않는다!
HTML 코드를 원래는 이렇게 넣어주면 되는데... 지금 톰캣이랑 안맞아서 뭐가 안 됨.
String html = "<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + "<head>\n" + " <meta charset=\"UTF-8\">\n" + " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" + " <title>회원가입 페이지</title>\n" + "</head>\n" + "<body>\n" + " <h1>회원가입 페이지</h1>\n" + " <hr>\n" + " <form action=\"/join\" method=\"post\">\n" + " <input type=\"text\" placeholder=\"username\" name=\"username\">\n" + " <input type=\"text\" placeholder=\"password\" name=\"password\">\n" + " <input type=\"text\" placeholder=\"email\" name=\"email\">\n" + " <button>회원가입</button>\n" + " </form>\n" + "</body>\n" + "</html>"; resp.getWriter().println(html);
그래서 그냥 이렇게 ㄱㄱ ㅠㅠ
resp.getWriter().println(html);
이거 꼭 넣어줘야함. 출력문…쿼리 스트링 ✓
id, 비번을 넣고 회원가입 버튼을 눌렸더니 [ /join?username=ssar&password=1234 ] 라는 url 주소가 떴다. ?username=ssar&password=1234 이렇게 생긴 데이터를 쿼리 스트링이라고 함 (물음표 이후 부분!) 내가 필요한 데이터를 구체적으로 질의할때 쓰는게 바로 쿼리스트링! 여기에 실어보내는 데이터는 select할때 where을 걸기 위한 것! [ 논문.com? ] 하면.. 뭘 요청하는건지 아시나요? [ 논문.com?title=인간경제 ] 이렇게 하면 제목이 인간경제인 논문을 달라고 하는구나... 하고 알겠지. 즉, [논문.com?title=인간경제]는 결국 select * from where title = “인간경제” 라고 들어가는 것과 마찬가지다!
주소 뒤에 (내가 입력한/전송한) 데이터를 실어가는게 보인다. 지금 이 데이터가 바디에 담겨서 들어가야 하는데... url에 담겨있다! url은 담을 수 있는 총 바이트가 255 바이트임. (영어는 255자만 담을 수 있다. 한글 들어가면 더 준다) 그래서 여기에 실어보내면 안됨!!
key=value (username=ssar) 형식은 x-www-form-urlencoded
[ 지금 우리가 하는건 회원가입. 즉, INSERT라서 쿼리스트링 X ]
insert데... 이거 쿼리스트링으로 보내면 안돼? = 안 돼. 프로토콜임. 쿼리스트링으로 보낸단 말은 데이터베이스에 SELECT해서 WHERE 걸기 위해 쓰는건데… INSERT는.. 안 맞음 [ 쿼리 스트링 = GET / 회원가입(Insert) = POST ] 때문에 INSERT를 걸려면 <form action=”/join” method=”post”> 라고. method를 post라고 적어줘야 함
input의 method를 post라고 바꿔주고 /join 페이지를 브라우저에 입력해서 보면… 이번엔 주소창에 /join?username=ssar&password=1234 이렇게 안 뜬다! naver.com/join 라고 뜨고 끝!
데이터는 암호화 시켜야 한다!
회원가입 시에는 HTTPS를 사용하여 데이터 통신을 암호화하고,
서버 측에서는 암호화 알고리즘을 사용하여 데이터를 안전하게 저장하는 것이 좋다.
(지금은) 브라우저에 f12 눌러서 Payload(Body) 보잖아?
그럼… 내가 회원가입 할 때 작성한 아이디, 패스워드 다 나와있음.
서블릿은 Java 코드 안에 HTML 코드를 섞어 사용할 수 있는데, 이를 통해 동적인 HTML 페이지를 생성하거나 HTML 내에 동적 데이터를 삽입할 수 있다.
전체 코드
package com.example.userapp.user; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; @WebServlet("/join") public class JoinServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("Content-Type", "text/html; charset=utf-8"); // username=ssar&password=1234&email=ssar@nate.com 이 들어올 것이다 // BufferedReader br = req.getReader(); // // String requestBody = ""; // // while (true) { // String line = br.readLine(); // // if (line == null) break; // // requestBody = requestBody + line; // // } // System.out.println(requestBody); // 1. 파싱 String username = req.getParameter("username"); String password = req.getParameter("password"); String email = req.getParameter("email"); System.out.println("username : " + username); System.out.println("password : " + password); System.out.println("email : " + email); // 2. 유효성 검사 (username에 글자수 제한을 둘 것이다) if (username.length() < 3 || username.length() > 10) { resp.getWriter().println("<h1>username 글자수가 3 ~ 10 사이여야 합니다."); return; } // 3. DB 연결 // 4. DAO의 insert 메서드를 호출 // 5. 메인 페이지 그리기 String html = ""; } }
서블렛 /join-form 코드
[ user - JoinFormServlet ]
package com.example.userapp.user; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.time.LocalDateTime; @WebServlet("/join-form") public class JoinFormServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { LocalDateTime now = LocalDateTime.now(); String html = " <!DOCTYPE html>\n" + " <html lang=\"en\">\n" + " <head>\n" + " <meta charset=\"UTF-8\">\n" + " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" + " <title>Document</title>\n" + " </head>\n" + " <body>\n"; for (int i = 0; i < 5; i++) { html = html +" <h1>"+i+"회원가입 페이지"+now+"<h1>\n"; } html = html +" <hr>\n" + " <form action=\"/join\" method=\"post\">\n" + " <input type=\"text\" placeholder=\"username\" name=\"username\">\n" + " <input type=\"text\" placeholder=\"password\" name=\"password\">\n" + " <input type=\"text\" placeholder=\"email\" name=\"email\">\n" + " <button>회원가입</button>\n" + " </form>\n" + " </body>\n" + " </html>"; resp.getWriter().println(html); } }
Share article