JSP 정리!!
웹 개발 어렵지 않아요
JSP(Web Application)에서는 두가지 객체를 활용할 수 있는데
첫 번째. JSP (서블릿) 객체
- request
- response
- session
요 세가지 메소드?는 JSP 내에서만 사용
그래서
- get / post 로 값을 전달??
- request.getParameter("name") 로 name값을 요청해서 받은 후 작업을 수행하고
- response.sendRedirect("path") 로 작업 수행 후 이동할 페이지의 경로를 설정해준다 (자바스크립트의 location.href="path"와 같은 역할)
**웹 - 서브릿(jsp)는 순수 웹의 영역. jsp나 servlet이나 역할을 같다. 그래서 jsp를 활용하나 servlet을 활용하나 문법은 동일. / 데이터를 사용자에게 입력받는 것은 웹의 영역, db연결&활용은 java의 영역
(1) JSP 만 사용하는 경우
- 스크립트릿 <% %> 안에 작업에 필요한 모든 내용을 기술한다. java 문법 활용
<% request.~ response.~ session.~ DB연결 %> |
(1-1)↓ login.jsp
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>login.jsp</title>
</head>
<body>
<form action="LogInOk" method="post"> //loginOk.jsp로 받은 값을 넘겨준다
아이디 : <input type="text" name="id"><br />
비밀번호 : <input type="text" name="pw"><br />
<input type="submit" value="로그인">
</form>
<hr>
<a href="join.html">[회원가입]</a>
</body>
</html>
(1-2)↓loginOk.jsp : request 객체를 이용 login.jsp 에서 값 받아온 뒤, <% %> 안에 java문법 기술
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 한글 처리
request.setCharacterEncoding("UTF-8");
String id, pw; //아래에서 받을 값에 대한 변수 선언
// 사용자가 입력한 값 받기
id = request.getParameter("id"); //jsp니까 request 객체 사용
pw = request.getParameter("pw");
// DB 연결
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet rs = null; //결과 창을 보여주는 역할
String sql = "select pw from member2 where id = ?"; //그냥 statement가 아니라 prepareStatement 객체 활용할 것이므로 미리 쿼리문 선언
// drive
try {
Class.forName("com.mysql.jdbc.Driver"); //JDBC 드라이브 로드
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jspdb" , "root" , "mysql"); // 데이터베이스 연결
pstmt = connection.prepareStatement(sql); //SQL문 실행 statment 객체 활용하는 것보다 prepareStatement 활용하는 것이 간편
pstmt.setString(1, id); // 컬럼명으로 확인
rs = pstmt.executeQuery(); // spl문 실행! executeUpdate아니고 excuteQuery니까 rs.next로 데이터 내부에 다음 값이 있는지 확인
if(rs.next()){ //데이터값이 있다면
String dbPw = rs.getString("pw"); //데이터에 저장된 pw값을 string으로 받아옴.
if(pw.equals(dbPw)){ //로그인 성공
session.setAttribute("id", id); //session에 id값을 담아주면 로그인 정보 전달할 때 id를 hidden 값으로 넘겨줄 필요가 없어진다.
response.sendRedirect("memberSelect.jsp");
}else{ //로그인 실패
response.sendRedirect("login.html");
}
} else { //데이터값이 없다면?
response.sendRedirect("login.html");
}
} catch (Exception e) { //try&catch로 예외처리
e.printStackTrace();
} finally { //DB연결 닫아주기
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(connection != null) connection.close();
} catch (Exception e) {}
}
%>
(2) 서브릿을 사용하는 경우
- .jsp 파일 외에 doPost / doGet을 사용한 .java클래스 별도 생성
→ 서브릿은 자바를 활용해 웹페이지를 동적으로 동작하기 위한 것이므로
→ 서브릿의 doGet / doPost의 자리가 <% %>자리와 같은 기능.(문법만 그대로 옮겨 적어주면 됨) 단지 get방식 혹은 post 방식으로 값을 보냈느냐의 차이
- HttpServlet 클래스를 상속받아서 사용
서블릿 doPost(HttpServletRequest request, HttpServletResponse response){ |
(2-1)↓loginOk.java (servlet) *연결된 다른 jsp는 생략했슴다
package com.javalec.ex;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/LoginOk") //servlet 주소. 연결할때 이 주소 값을 이용
public class LoginOk extends HttpServlet {
private static final long serialVersionUID = 1L;
public LoginOk() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost"); //확인용
request.setCharacterEncoding("UTF-8");
//값을 받아라
String id = request.getParameter("id");
String pw = request.getParameter("pw");
//값을 확인해라
System.out.println(id);
System.out.println(pw);
//DB연결 설정
Connection conn = null; //연결 역할
PreparedStatement pstmt = null; //쿼리 창 역할
ResultSet rs = null; //결과값 담는 역할
String driver = "com.mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/bigdata";
url += "?useSSL=false&serverTimezone=UTC";
String uid = "root";
String upw = "rootpass";
String sql = "select name from member where id=? and pw=? ";
try{
Class.forName(driver);
conn = DriverManager.getConnection(url, uid, upw);
pstmt = conn.prepareStatement(sql); //connection 객체에서 쿼리창을 꺼내 옴
pstmt.setString(1, id);
pstmt.setString(2, pw);
rs = pstmt.executeQuery(); //결과 값을 rs에 담음
if(rs.next()){ //로그인 성공시
HttpSession httpSession = request.getSession(); //servlet은 session을 바로 갖다 쓸 수 없다 Http~ getSession을 통해 가져올 수 있음 //로그인 값은 각각 다를테니 request로 받아옴
httpSession.setAttribute("userId", id);
response.sendRedirect("myPage.jsp");
}else{ //실패시
response.sendRedirect("login.jsp");
}
}catch(Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}finally{
}
}
}
두 번째. JAVA 객체 (자바문법 활용)
- DB 작업을 위해 java 객체를 활용
→ 데이터를 받는 것이 웹의 역할이었다면, DB연결 및 활용하는 것은 JAVA의 영역이기 때문
DB연결 객체 세 가지 (속성객체) 1. Connection 객체 2. PreparedStatement 객체 : 쿼리문 select, insert, update 모든 경우 사용 / PreparedStatement 객체를 사용하면 DB에서 받아오는 값을 ?로 처리할 수 있어서 그냥 Statement 객체를 사용하는 것 보다 간편 3. ResultSet 객체 : 쿼리문 select일 경우에만 사용
** hong1 1234 홍길동1 hong@ 제주 2020-04-28 14:21:11 -> int 1 insert나 update를 할 경우 excuteUpdate 사용. 이때, 위와 같이 쿼리창의 결과가 int값 1로 오기 때문에 int값을 리턴. 이와 달리 excuteQuery 는 select 일 때만 사용(int 값 리턴 X)
** 위 세가지 객체보다 먼저 DB의 연결 주소, 계정 정보 등을 위한 Drive 객체가 필요!! |
(1) DAO 만 사용하는 경우
- DAO : DB연결을 위한 메소드들을 따로 모아 놓은 java 객체
→ 순수 Java이므로 웹에서 쓰이는 response, request, session 사용 불가 / 대신 각 객체의 메소드를 통해 dao 작동
(1-1)↓ modify.jsp / 회원정보수정 예제
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%! //보통 변수선언은 html 윗 부분에서 선언해준다
//DB연결 변수 선언
Connection connection;
Statement statement;
ResultSet resultSet;
//변수 선언
String name, id, pw, phone1, phone2, phone3, gender;
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>modify.jsp</title>
</head>
<body>
<% // 원래는 dao에서 한번에 처리
id = (String)session.getAttribute("id"); //session에 담아줬던 id값 받아오기
String query = "select * from member2 where id = '" + id + "'"; //쿼리문 변수에 담아주기
Class.forName("com.mysql.jdbc.Driver"); //드라이브 연결
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jspdb" , "root" , "mysql");
statement = connection.createStatement();
resultSet = statement.executeQuery(query);
while(resultSet.next()) {
name = resultSet.getString("name");
pw = resultSet.getString("pw");
phone1 = resultSet.getString("phone1");
phone2 = resultSet.getString("phone2");
phone3 = resultSet.getString("phone3");
gender = resultSet.getString("gender");
}
%>
<form action="ModifyOk.jsp" method="post"> <!-- modifyOk.jsp로 연결 -->
<input type="hidden" name="id" value="<%=id %>"> <!-- 만약 session에 id값 담지 않을 거라면 보안을 위해 id 값은 hidden으로 넘겨준다! -->
이름 : <input type="text" name="name" size="10" value=<%=name %>><br />
아이디 : <%=id %><br />
비밀번호 : <input type="text" name="pw" size="10"><br />
전화번호 : <select name="phone1">
<option value="010">010</option>
<option value="016">016</option>
<option value="017">017</option>
<option value="018">018</option>
<option value="019">019</option>
<option value="011">011</option>
</select> -
<input type="text" name="phone2" size="5" value=<%=phone2 %>> - <input type="text" name="phone3" size="5" value=<%=phone3 %>> <br />
<%
if(gender.equals("man")) {
%>
성별구분 : <input type="radio" name="gender" value="man" checked="checked">남 <input type="radio" name="gender" value="woman">여 <br />
<%
} else {
%>
성별구분 : <input type="radio" name="gender" value="man" >남 <input type="radio" name="gender" value="woman" checked="checked">여 <br />
<%
}
%>
<input type="submit" value="정보수정"> <input type="reset" value="취소">
</form>
</body>
</html>
(1-2)↓ modifyOK.jsp
<%@page import="com.javalec.ex.MemberDao"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 한글 처리
request.setCharacterEncoding("UTF-8");
String name, id, pw, phone1, phone2, phone3, gender;
// 입력받은 값 받기 getParameter
name = request.getParameter("name");
id = request.getParameter("id");
pw = request.getParameter("pw");
phone1 = request.getParameter("phone1");
phone2 = request.getParameter("phone2");
phone3 = request.getParameter("phone3");
gender = request.getParameter("gender");
// db
MemberDao dao = new MemberDao(); //dao 연결
int ri = dao.memberUpdate( name, pw, phone1, phone2, phone3, gender, id);
// jsp
// response는 java가 아닌 jsp에서만 쓸 수 있으므로 dao에 넣지 않고 따로 빼서 처리
if(ri == 1){
response.sendRedirect("modifyResult.jsp");
}else{
response.sendRedirect("modify.jsp");
}
%>
(1-3)↓ MemberDao.java
package com.javalec.ex;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class MemberDao { //동작하게 할 것이다
// DB 연결
Connection connection = null; //데이터베이스 연결
PreparedStatement pstmt = null; //SQL문 실행
int ri = 0;
// 드라이버 로드
public MemberDao() { //필수적인 드라이브 연결을 담아줌. 드라이브 연결은 오류나면 안되니까 try&catch로!
try {
Class.forName("com.mysql.jdbc.Driver"); //class에 넣어 둔 jdbc의 mysql 쓸 거야!(driver 로드)
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jspdb" , "root" , "mysql"); // DriverManager 알아서 연결해줘
} catch (Exception e) { //오류 안 나게 그냥 Exception으로 처리
e.printStackTrace();
}
}
// DAO만 사용했을 경우 MemberUpdate
public int memberUpdate(String name, String pw, String phone1,String phone2,String phone3,String gender, String id) { // DTO를 사용하지 않았으므로 받아와야 할 값을 괄호 안에 각각 담아줘야 함
String sql = "update member2 set name = ?, pw = ?, phone1 = ?, phone2 = ?, phone3 = ?, gender = ? where id = ?"; //sql문 담아주는 변수
// drive
try {
pstmt = connection.prepareStatement(sql);
pstmt.setString(1, name); //name 값을 pstmt에 저장
pstmt.setString(2, pw); //pw 값을 pstmt에 저장
pstmt.setString(3, phone1);
pstmt.setString(4, phone2);
pstmt.setString(5, phone3);
pstmt.setString(6, gender);
pstmt.setString(7, id);
ri = pstmt.executeUpdate(); // pstmt값을 실행해서 ri에 저장 (여기서 excuteUpdate는 int 값만 리턴한다!! update되었다면, update된 값이 1로 돌아옴!
if(ri == 1){ // update 성공했다면 (1을 리턴했다면)
System.out.println("update success");
} else { //실패했다면
System.out.println("insert fail");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try { // 서버 연결 닫아주기 (이거 반복하는게 많아지면 아예 서버 연결 및 해제를 담당하는 메소드 JDBCUtil을 통해 해결한다)
if(pstmt != null) pstmt.close();
if(connection != null) connection.close();
} catch (Exception e) {}
}
return ri; // 최종으로 ri 값을 리턴해서 다시 jsp로 보내줌
}
(2) DTO와 DAO를 함께 사용하는 경우
- DTO : 연결한 DB의 정보들을 따로 담아두는 객체
→ dao 만으로는 DB에 담긴 여러명의 회원정보를 받아오기 불편(다차원 배열을 만들어 담줘야 하기 때문). 이때 dto를 활용해 연결한 DB에 담긴 여러명의 회원 정보를 담은 객체를 만들어 dao메소드 사용 시 활용.
→ dto를 통해 정보를 가져오는 건 jsp만 사용 할 때, while문을 통한 반복으로 각 회원들의 정보를 가져오는 것과 같은 역할을 수행함.
(1-1)↓ join.jsp / 회원등록 예제
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>join.jsp</title>
</head>
<body>
<form action="JoinOk.jsp" method="post">
이름 : <input type="text" name="name" size="10"><br />
아이디 : <input type="text" name="id" size="10"><br />
비밀번호 : <input type="text" name="pw" size="10"><br />
전화번호 : <select name="phone1">
<option value="010">010</option>
<option value="016">016</option>
<option value="017">017</option>
<option value="018">018</option>
<option value="019">019</option>
<option value="011">011</option>
</select> -
<input type="text" name="phone2" size="5"> - <input type="text" name="phone3" size="5"> <br />
성별구분 : <input type="radio" name="gender" value="man">남 <input type="radio" name="gender" value="woman">여 <br />
<input type="submit" value="회원가입"> <input type="reset" value="취소">
</form>
</body>
</html>
(1-2)↓ joinOk.jsp
<%@page import="com.javalec.ex.MemberDto"%>
<%@page import="com.javalec.ex.MemberDao"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.PreparedStatement"%>
<%@page import="java.sql.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 한글 처리
request.setCharacterEncoding("UTF-8");
String name, id, pw, phone1, phone2, phone3, gender;
// 값 받기
name = request.getParameter("name");
id = request.getParameter("id");
pw = request.getParameter("pw");
phone1 = request.getParameter("phone1");
phone2 = request.getParameter("phone2");
phone3 = request.getParameter("phone3");
gender = request.getParameter("gender");
// dto - vo
MemberDto member = new MemberDto(name, id, pw, phone1, phone2, phone3, gender); //member변수에 dto 매개변수 값을 담아준다
//db - dao
MemberDao dao = new MemberDao(); //dao생성자
int ri = dao.memberJoin(member); //담아둔 member정보 불러와서 ri 값에 저장
//jsp
if(ri == 1){
response.sendRedirect("joinResult.jsp");
}else{
response.sendRedirect("join.jsp");
}
%>
(1-3)↓ memberDao.java
package com.javalec.ex;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class MemberDao { //동작하게 할 것이다
// DB 연결
Connection connection = null; //데이터베이스 연결
PreparedStatement pstmt = null; //SQL문 실행
int ri = 0;
// 드라이버 로드
public MemberDao() { //필수적인 드라이브 연결을 담아줌. 드라이브 연결은 오류나면 안되니까 try&catch로!
try {
Class.forName("com.mysql.jdbc.Driver"); //class에 넣어 둔 jdbc의 mysql 쓸 거야!(driver 로드)
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jspdb" , "root" , "mysql"); // DriverManager 알아서 연결해줘
} catch (Exception e) { //오류 안 나게 그냥 Exception으로 처리
e.printStackTrace();
}
}
//DTO 활용. 회원 가입
public int memberJoin(MemberDto member) {
// DB
String sql = "insert into member2 (name, id, pw, phone1, phone2, phone3, gender) values(?,?,?,?,?,?,?)";
// drive
try {
pstmt = connection.prepareStatement(sql);
pstmt.setString(1, member.getName());
pstmt.setString(2, member.getId());
pstmt.setString(3, member.getPw());
pstmt.setString(4, member.getPhone1());
pstmt.setString(5, member.getPhone2());
pstmt.setString(6, member.getPhone3());
pstmt.setString(7, member.getGender());
int i = pstmt.executeUpdate();
if(i == 1){
System.out.println("insert success");
} else {
System.out.println("insert fail");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(pstmt != null) pstmt.close();
if(connection != null) connection.close();
} catch (Exception e) {}
}
return ri;
}
}
(1-4)↓ memberDto.java
package com.javalec.ex;
public class MemberDto { //정보를 담아줄 것이다
String name;
String id;
String pw;
String phone1;
String phone2;
String phone3;
String gender;
public MemberDto() { //위에 만든 MemberDto class 사용하기 위해 메소드 생성자 호출
}
public MemberDto(String name, String id, String pw, String phone1, String phone2, String phone3, String gender) { //dao에서 받은 정보를 담기 위해 변수 선언 메소드 생성자 호출
super();
this.name = name;
this.id = id;
this.pw = pw;
this.phone1 = phone1;
this.phone2 = phone2;
this.phone3 = phone3;
this.gender = gender;
}
//정보를 각각 꺼내 쓸 수 있도록 getter setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPw() {
return pw;
}
public void setPw(String pw) {
this.pw = pw;
}
public String getPhone1() {
return phone1;
}
public void setPhone1(String phone1) {
this.phone1 = phone1;
}
public String getPhone2() {
return phone2;
}
public void setPhone2(String phone2) {
this.phone2 = phone2;
}
public String getPhone3() {
return phone3;
}
public void setPhone3(String phone3) {
this.phone3 = phone3;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override //값이 잘 넘어왔는지 toString으로 확인
public String toString() {
return "MemberDto [name=" + name + ", id=" + id + ", pw=" + pw + ", phone1=" + phone1 + ", phone2=" + phone2
+ ", phone3=" + phone3 + ", gender=" + gender + "]";
}
}
**JDBCUtil.java
-반복적인 서버와의 연결&해제를 줄이기 위해 이 역할을 전담하는 메소드 생성
package com.bigdata.common;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class JDBCUtil {
//connection (open)
//close()
public static Connection getConnection(){
Context context = null;
DataSource dsSource = null;
Connection conn = null;
try {
context = new InitialContext();
dsSource = (DataSource)context.lookup("java:comp/env/jdbc/Mysql");
conn = dsSource.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void close(ResultSet rs, PreparedStatement pstmt, Connection conn) {
try {
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close(); // 서버와의 연결 끊기
} catch (Exception e) {
e.printStackTrace();
} finally {
rs = null;
pstmt = null;
conn = null;
}
}
public static void close(PreparedStatement pstmt, Connection conn) {
try {
if(pstmt != null) pstmt.close();
if(conn != null) conn.close(); // 서버와의 연결 끊기
} catch (Exception e) {
e.printStackTrace();
} finally {
pstmt = null;
conn = null;
}
}
public static void close(ResultSet rs, Statement stmt, Connection conn) {
try {
if(rs != null) rs.close();
if(stmt != null) stmt.close();
if(conn != null) conn.close(); // 서버와의 연결 끊기
} catch (Exception e) {
e.printStackTrace();
} finally {
rs = null;
stmt = null;
conn = null;
}
}
public static void close(Statement stmt, Connection conn) {
try {
if(stmt != null) stmt.close();
if(conn != null) conn.close(); // 서버와의 연결 끊기
} catch (Exception e) {
e.printStackTrace();
} finally {
stmt = null;
conn = null;
}
}
}