1. ReadMe.md
#### JSP 모델2 블로그 프로젝트
## 오라클 사용자 생성
```sql
alter session set "_oracle_script"=true;
CREATE USER cos IDENTIFIED BY bitc5600;
GRANT CREATE SESSION TO cos;
GRANT CREATE TABLESPACE TO cos;
GRANT CREATE TABLE TO cos;
GRANT select, insert, delete, update on cos.player TO cos;
alter user cos default tablespace users quota unlimited on users;
관련주소 :
https://ondolroom.tistory.com/162
```
## 테이블
```sql
CREATE TABLE users(
id number primary key,
username varchar2(100) not null unique,
password varchar2(100) not null,
email varchar2(100) not null,
address varchar2(100) not null,
userProfile varchar2(200),
userRole VARCHAR2(20),
createDate timestamp
) ;
CREATE TABLE board(
id number primary key,
userId number,
title varchar2(100) not null,
content clob,
readCount number default 0,
createDate timestamp,
foreign key (userId) references users (id)
);
CREATE TABLE reply(
id number primary key,
userId number,
boardId number,
content varchar2(300) not null,
createDate timestamp,
foreign key (userId) references users (id) on delete set null,
foreign key (boardId) references board (id) on delete cascade
);
```
## 시퀀스
```sql
CREATE SEQUENCE USERS_SEQ
START WITH 1
INCREMENT BY 1;
CREATE SEQUENCE BOARD_SEQ
START WITH 1
INCREMENT BY 1;
CREATE SEQUENCE REPLY_SEQ
START WITH 1
INCREMENT BY 1;
```
utf-8 깨질 때 web.xml에 넣기
<filter>
<filter-name>setCharacterEncodingFilter</filter-name>
<filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>setCharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
톰캣 홈페이지 - 톰캣 8.5 - 10. JDBC DataSource 에 예시가 있음
http://tomcat.apache.org/tomcat-8.5-doc/jndi-datasource-examples-howto.html
2. META-INF에 context.xml 만들고 데이터 넣기(server에 있는 context.xml 복사해오면 됨)
DB클래스를 가져오고 DB에 연결한다.
톰캣이 요청을 받으면 Catalina 가 요청에 맞는 Context 를 찾고, Context 는 자신이 설정된 어플리케이션의 deployment descriptor file(web.xml) 을 기반으로 전달받은 요청을 서블릿에게 전달하여 처리되도록 한다.
3. WEB-INF에 web.xml 만들고 데이터 넣기(server에 있는 web.xml 복사해오면 됨)
4. DBConn 만들고 내용 넣기
package com.cos.blog.db;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class DBConn {
public static Connection getConnection() {
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/myoracle");
Connection conn = ds.getConnection();
return conn;
} catch (Exception e) {
e.printStackTrace();
System.out.println("DBConn : 데이터베이스 연결 실패");
System.out.println("DBConn : Message" + e.getMessage());
}
return null;
}
public static void close(Connection conn, PreparedStatement pstmt) {
try {
if(conn != null) {
conn.close();
}
if(pstmt != null) {
pstmt.close();
}
} catch (Exception e) {
System.out.println("DB종료시 오류가 발생 : " +e.getMessage());
}
}
public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
try {
if(conn != null) {
conn.close();
}
if(pstmt != null) {
pstmt.close();
}
if(rs != null) {
rs.close();
}
} catch (Exception e) {
System.out.println("DB종료시 오류가 발생 : " +e.getMessage());
}
}
}
5. enum과 model들 만들기
enum RoleType
package com.cos.blog.model;
public enum RoleType {
USER, ADMIN;
}
Users
package com.cos.blog.model;
import java.sql.Timestamp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Users {
private int id;
private String username;
private String password;
private String email;
private String address;
private String userProfile;
private String userRole;
private Timestamp createDate;
}
Board
package com.cos.blog.model;
import java.sql.Timestamp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Board {
private int id;
private int userId;
private String title;
private String content;
private int readCount;
private Timestamp createDate;
}
Reply
package com.cos.blog.model;
import java.sql.Timestamp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Reply {
private int id;
private int userId;
private int boardId;
private String content;
private Timestamp createDate;
}
6. Repository (DAO) 만들기
UsersRepository
package com.cos.blog.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.cos.blog.db.DBConn;
import com.cos.blog.model.Users;
public class UsersRepository {
private static final String TAG = "UsersRepository : ";
// 싱글톤
private static UsersRepository instance = new UsersRepository();
private UsersRepository() {
}
public static UsersRepository getInstance() {
return instance;
}
private Connection conn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
public int save(Users user) {
final String SQL = "INSERT INTO USERS(id, username, password, email, address, userRole, createDate)"+
"VALUES(USERS_SEQ.nextval,?,?,?,?,?,sysdate)";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
pstmt.setString(1, user.getUsername());
pstmt.setString(2, user.getPassword());
pstmt.setString(3, user.getEmail());
pstmt.setString(4, user.getAddress());
pstmt.setString(5, user.getUserRole());
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "save : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public int update(Users user) {
final String SQL = "";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "update : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public int deleteById(int id) {
final String SQL = "";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "deleteById : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public List<Users> findAll() {
final String SQL = "";
List<Users> users = new ArrayList<>();
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
// while 돌려서 rs -> java 오브젝트에 집어넣기
return users;
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "findAll : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt, rs);
}
return null;
}
public Users findById(int id) {
final String SQL = "";
Users user = new Users();
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
// if 해서 rs -> java 오브젝트에 집어넣기
return user;
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "findById : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt, rs);
}
return null;
}
}
BoardRepository
package com.cos.blog.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.cos.blog.db.DBConn;
import com.cos.blog.model.Board;
import com.cos.blog.model.Users;
public class BoardRepository {
private static final String TAG = "BoardRepository : ";
// 싱글톤
private static BoardRepository instance = new BoardRepository();
private BoardRepository() {
}
public static BoardRepository getInstance() {
return instance;
}
private Connection conn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
public int save(Board board) {
final String SQL = "";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "save : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public int update(Board board) {
final String SQL = "";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "update : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public int deleteById(int id) {
final String SQL = "";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "deleteById : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public List<Board> findAll() {
final String SQL = "";
List<Board> boards = new ArrayList<>();
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
// while 돌려서 rs -> java 오브젝트에 집어넣기
return boards;
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "findAll : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt, rs);
}
return null;
}
public Board findById(int id) {
final String SQL = "";
Board board = new Board();
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
// if 해서 rs -> java 오브젝트에 집어넣기
return board;
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "findById : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt, rs);
}
return null;
}
}
ReplyRepository
package com.cos.blog.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.cos.blog.db.DBConn;
import com.cos.blog.model.Board;
import com.cos.blog.model.Reply;
import com.cos.blog.model.Users;
public class ReplyRepository {
private static final String TAG = "BoardRepository : ";
// 싱글톤
private static ReplyRepository instance = new ReplyRepository();
private ReplyRepository() {
}
public static ReplyRepository getInstance() {
return instance;
}
private Connection conn = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
public int save(Reply reply) {
final String SQL = "";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "save : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public int update(Reply reply) {
final String SQL = "";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "update : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public int deleteById(int id) {
final String SQL = "";
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
return pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "deleteById : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt);
}
return -1;
}
public List<Reply> findAll() {
final String SQL = "";
List<Reply> replies = new ArrayList<>();
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
// while 돌려서 rs -> java 오브젝트에 집어넣기
return replies;
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "findAll : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt, rs);
}
return null;
}
public Reply findById(int id) {
final String SQL = "";
Reply reply = new Reply();
try {
conn = DBConn.getConnection();
pstmt = conn.prepareStatement(SQL);
// 여기에 물음표 완성하기
// if 해서 rs -> java 오브젝트에 집어넣기
return reply;
} catch (Exception e) {
e.printStackTrace();
System.out.println(TAG + "findById : " + e.getMessage());
} finally {
DBConn.close(conn, pstmt, rs);
}
return null;
}
}
7. interface Action과 action 들 만들기
Action
package com.cos.blog.action;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface Action {
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
UsersJoinAction
package com.cos.blog.action.user;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.cos.blog.action.Action;
public class UsersJoinAction implements Action {
// 컨트롤러가 해야될 일들을 위임해서 다른 클래스가 일을 하게 하는 것을 팩토리패턴이라고 한다
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher dis = request.getRequestDispatcher("user/join.jsp");
dis.forward(request, response);
}
}
UsersJoinProcAction
package com.cos.blog.action.user;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.cos.blog.action.Action;
import com.cos.blog.model.RoleType;
import com.cos.blog.model.Users;
import com.cos.blog.repository.UsersRepository;
import com.cos.blog.util.Script;
public class UsersJoinProcAction implements Action {
// 컨트롤러가 해야될 일들을 위임해서 다른 클래스가 일을 하게 하는 것을 팩토리패턴이라고 한다
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 0. // 페이지 오류를 막기위해(공격 등) 유효성 검사부터 해야한다
if(request.getParameter("username").equals("") ||
request.getParameter("username") == null ||
request.getParameter("password").equals("") ||
request.getParameter("password") == null ||
request.getParameter("email").equals("") ||
request.getParameter("email") == null ||
request.getParameter("address").equals("") ||
request.getParameter("address") == null) {
// 로그하나 남겨야함
return;
}
// 1. 파라메터 받기 (x-www-form-urlencoded)라는 MIME타입 key=value
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email"); // postman등으로 공격하면 형식에 맞지않게 보낼수 있기 때문에 유효성체크 해줘야한다(지금은 안함)
String address = request.getParameter("address");
String userRole = RoleType.USER.toString();
// 2. User 오브젝트 변환
Users user = Users.builder()
.username(username)
.password(password)
.email(email)
.address(address)
.userRole(userRole)
.build();
// 3. DB 연결 - UserRepository의 save() 호출
UsersRepository usersRepository = UsersRepository.getInstance();
int result = usersRepository.save(user);
// 4. index.jsp 페이지로 이동
if(result == 1) {
RequestDispatcher dis = request.getRequestDispatcher("index.jsp");
dis.forward(request, response);
} else {
Script.back("회원가입에 실패하였습니다.", response);
}
}
}
8. UsersController 만들기
package com.cos.blog.controller;
import java.io.IOException;
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 com.cos.blog.action.Action;
import com.cos.blog.action.user.UsersJoinAction;
import com.cos.blog.action.user.UsersJoinProcAction;
@WebServlet("/user")
public class UsersController extends HttpServlet {
private static final String TAG = "UsersController : ";
private static final long serialVersionUID = 1L;
public UsersController() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doProcess(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doProcess(request, response);
}
// 어떠한 형식의 요청이 오든 여기서 처리
protected void doProcess(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String cmd = request.getParameter("cmd");
System.out.println(TAG + "doProcess : " + cmd);
Action action = router(cmd);
action.execute(request, response);
}
public Action router(String cmd) {
if (cmd.equals("join")) {
// 회원가입 페이지로 이동
// http://localhost:8000/blog/user?cmd=join
// 컨트롤러가 해야될 일들을 위임해서 다른 클래스(UsersJoinAction)가 일을 하게 하는 것을 !팩토리패턴!이라고 한다
return new UsersJoinAction();
} else if (cmd.equals("joinProc")) {
// 회원가입을 진행 한 후 -> index.jsp로 이동
return new UsersJoinProcAction();
} else if (cmd.equals("update")) {
// 회원 수정 페이지로 이동 (세션에 User 오브젝트를 가지고 있을 예정)
} else if (cmd.equals("updateProc")) {
// 회원 수정을 진행 한 후 -> index.jsp로 이동
} else if (cmd.equals("delete")) {
// 회원 수정페이지에서 삭제할 예정 - 회원 삭제를 진행 한 후 -> 로그아웃을 하고 -> index.jsp로 이동
} else if (cmd.equals("login")) {
// 회원 로그인 페이지로 이동
} else if (cmd.equals("loginProc")) {
// 회원 로그인을 수행한 후 -> 세션에 등록을 하고 -> index.jsp로 이동
}
return null;
}
}
9. 자바스크립트를 이용하는 Script 만들기
package com.cos.blog.util;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
public class Script {
public static void back(String msg, HttpServletResponse response) {
try {
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8"); // 받는 쪽에서 해석하도록
PrintWriter out = response.getWriter();
out.println(
"<script>\r\n" +
"alert(\"" + msg + "\");\r\n" +
"history.back();\r\n" +
"</script>");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
다음에 계속
참고
context.xml // web.xml
https://parkcheolu.tistory.com/130
'Web > Jsp' 카테고리의 다른 글
include 하는 두가지 방법 // include jsp // include file (0) | 2020.05.29 |
---|---|
200529 // blog 블로그 만들기 2 (0) | 2020.05.29 |
200528 MVC2 / context.xml / Repository / historyback (0) | 2020.05.28 |
JSP MVC 패턴 (0) | 2020.05.27 |
JSP 리눅스 에디터 vi nano (0) | 2020.05.27 |