728x90
반응형
#JSP properties 파일 로드
1.dao클래스 만들 때
-cmd에서 dao객체를 사용하기 때문에 상위 타입을 가지고 다형성을 활용해야합니다.
-CMDFactory 클래스들을 -> properties로 관리합니다.
#사이드 이펙트
-의존성을 최소화합니다.
#요즘 DTO추세
-자바 빈을 안 만들고 map을 사용합니다.
-List<Map<String, Object>
#DBCP
-데이터베이스 커넥션 풀입니다.
1. GuestBook
package org.smart.bean;
import java.text.SimpleDateFormat;
import java.util.Date;
public class GuestBook {
private String gid;
private String content;
private String reg;
public GuestBook() {
SimpleDateFormat sdf =
new SimpleDateFormat("yyyy.MM.dd(kk:mm)");
reg = sdf.format(new Date());
}
public GuestBook(String content) {
this();
setContent(content);
}
public GuestBook(String gid, String content, String reg) {
this.gid = gid;
this.content = content;
this.reg = reg;
}
public String getGid() {
return gid;
}
public void setGid(String gid) {
this.gid = gid;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getReg() {
return reg;
}
public void setReg(String reg) {
this.reg = reg;
}
}
2. ICMD
package org.smart.cmd;
import javax.servlet.http.HttpServletRequest;
public interface ICMD {
String action(HttpServletRequest request);
}
3. ReadCmd
package org.smart.cmd;
import java.sql.Connection;
import javax.servlet.http.HttpServletRequest;
import org.smart.bean.GuestBook;
import org.smart.dao.DAOFactory;
import org.smart.dao.IDAO;
public class ReadCmd implements ICMD{
@Override
public String action(HttpServletRequest request) {
// dao가 Oracle일수도 있고 MySQL일수도 있다.
IDAO dao = DAOFactory.getDao();
Connection con = dao.connect();
GuestBook[] books = dao.readBook(con);
dao.disconnect(con);
request.setAttribute("books", books);
return "main.jsp";
}
}
4. WriteCmd
package org.smart.cmd;
import java.sql.Connection;
import javax.servlet.http.HttpServletRequest;
import org.smart.bean.GuestBook;
import org.smart.dao.DAOFactory;
import org.smart.dao.IDAO;
public class WriteCmd implements ICMD{
// 리턴타입이 void에서 String으로 바뀜(돌아 갈 경로)
@Override
public String action(HttpServletRequest request) {
String content = request.getParameter("content");
GuestBook book = new GuestBook(content);
IDAO dao = DAOFactory.getDao();
Connection con = dao.connect();
dao.write(con, book);
dao.disconnect(con);
request.setAttribute("isRedirect", true);
return request.getContextPath();
}
}
5. CMDFactory
package org.smart.control;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.smart.cmd.ICMD;import com.sun.xml.internal.ws.resources.HttpserverMessages;
public class CMDFactory {
private static Hashtable<String, ICMD> cmds = new Hashtable<String, ICMD>();
public static void initCmds(Properties prop) {
try {
// cmdsInfo.properties의 키값 *.do 를 가져옴
// ? <- 아무값이나 다 받을 수 있다.
Set<?> keys = prop.keySet();
// Object타입 = ?사용,
for (Object keyObj : keys) {
//
String key = keyObj.toString();
// 키 값 에서 value값 가져옴 (org.smart.cmd.ReadCmd)
String className = prop.getProperty(key);
// org.smart.cmd.ReadCmd 읽어서 클래스의 정보를 읽어옴
// newInstance() -> 해당 클래스(불러온 className)의 객체를 생성 할 수있다.
// (new className)과 같은 의미 (class이름이 문자열이라 new로는 할 수가 없다.)
// 이렇게 생성시 Object타입으로 넘어와서 ICMD로 받는다.
// 문제점 : 리플렉션를 하면 private도 다 접근되어서 객체지향의 본질을 파괴 할 수도 있다.
// private 사용이 class명.setAccessible(true)를 하면 사용가능
ICMD cmdObj = (ICMD)Class.forName(className).newInstance();
cmds.put(key, cmdObj);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static String doAction(HttpServletRequest request, String key){
return cmds.get(key).action(request);
}
}
6. MainServlet
package org.smart.control;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.smart.dao.DAOFactory;
public class MainServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private void loadProp(String path, Properties prop) {
FileInputStream fis = null;
try {
fis = new FileInputStream(path);
prop.load(fis);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
// 어플리케이션을 얻어옴
ServletContext application =
config.getServletContext();
// web.xml에 경로만 따로 빼서 처리
String path =
config.getInitParameter("cmdsInfoPath");
String realPath = application.getRealPath(path);
Properties prop = new Properties();
loadProp(realPath, prop);
CMDFactory.initCmds(prop);
path = config.getInitParameter("dbTypePath");
realPath =
application.getRealPath(path);
prop = new Properties();
loadProp(realPath, prop);
DAOFactory.initDaos(prop.getProperty("dbms"));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doAction(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doAction(request, response);
}
private void doAction(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("euc_kr");
// uri마다 다르게 반응
String uri = request.getRequestURI();
System.out.println("uri: " +uri);
String contextPath = request.getContextPath();
System.out.println("contextPath: " + contextPath);
// uri
String what = uri.substring(request.getContextPath().length());
System.out.println("what: " + what);
String nextPage = CMDFactory.doAction(request, what);
if(request.getAttribute("isRedirect") == null){
RequestDispatcher rd = request.getRequestDispatcher(nextPage);
rd.forward(request, response);
}else{
response.sendRedirect(nextPage);
}
}
}
7. DAOFactory
package org.smart.dao;
import java.util.Hashtable;
public class DAOFactory {
private static Hashtable<String, IDAO> daos =
new Hashtable<String, IDAO>();
private static String dbms;
// mysql, oracle 선택
// dao가 바뀌어도 관련된 cmd들을 바꿀 필요가 없다.
// 목적 : 둘 중 뭐가 선택되든 앞에 cmd클래스들이 바뀌면 안된다.
public static void initDaos(String inputDbms){
dbms = inputDbms;
daos.put("mysql", MySQLGuestBookDAO.getInstance());
daos.put("oracle", new OracleGuestBookDAO());
}
public static IDAO getDao(){
return daos.get(dbms);
}
}
8. IDAO
package org.smart.dao;
import java.sql.Connection;
import org.smart.bean.GuestBook;
public interface IDAO {
// DAO의 규칙
Connection connect();
int write(Connection con, GuestBook book);
GuestBook[] readBook(Connection con);
void disconnect(Connection con);
}
9. MySQLConstant
package org.smart.dao;
public interface MySQLConstant {
String DRIVER = "com.mysql.jdbc.Driver";
String DB_URL = "jdbc:mysql://localhost:3306/test";
String UID = "root";
String UPW = "1234";
String WRITE = "INSERT INTO guest_book (content, reg) " +
"VALUES(?,?)";
String READ_BOOK =
"SELECT * FROM guest_book ORDER BY gid DESC";
}
10. MySQLGuestBookDAO
package org.smart.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;
import org.smart.bean.GuestBook;
public class MySQLGuestBookDAO implements IDAO, MySQLConstant{
private static MySQLGuestBookDAO instance = new MySQLGuestBookDAO();
private MySQLGuestBookDAO(){
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static MySQLGuestBookDAO getInstance(){
return instance;
}
@Override
public Connection connect() {
Connection con = null;
try {
con = DriverManager.getConnection(DB_URL, UID, UPW);
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
@Override
public int write(Connection con, GuestBook book) {
int result = 0;
PreparedStatement pStmt = null;
try {
pStmt = con.prepareStatement(WRITE);
pStmt.setString(1, book.getContent());
pStmt.setString(2, book.getReg());
result = pStmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally{
closeAll(pStmt);
}
return result;
}
@Override
public GuestBook[] readBook(Connection con) {
GuestBook[] books = null;
PreparedStatement pStmt = null;
ResultSet rs = null;
try {
pStmt = con.prepareStatement(READ_BOOK);
rs = pStmt.executeQuery();
Vector<GuestBook> vector = new Vector<GuestBook>();
while(rs.next()){
GuestBook book = new GuestBook(
rs.getString("gid"),
rs.getString("content"),
rs.getString("reg")
);
vector.add(book);
}
books = vector.toArray(new GuestBook[0]);
} catch (Exception e) {
e.printStackTrace();
} finally{
closeAll(rs);
closeAll(pStmt);
}
return books;
}
@Override
public void disconnect(Connection con) {
try {
if(con != null)con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void closeAll(PreparedStatement pStmt){
try {
if(pStmt != null)pStmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void closeAll(ResultSet rs){
try {
if(rs != null)rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
11. OracleGuestBookDAO
package org.smart.dao;
import java.sql.Connection;
import org.smart.bean.GuestBook;
public class OracleGuestBookDAO implements IDAO{
@Override
public Connection connect() {
return null;
}
@Override
public int write(Connection con, GuestBook book) {
return 0;
}
@Override
public GuestBook[] readBook(Connection con) {
return null;
}
@Override
public void disconnect(Connection con) {
}
}
12. cmdsInfo.properties
/start.do=org.smart.cmd.ReadCmd
/write.do=org.smart.cmd.WriteCmd
13. dbtype.properties
dbms=mysql
14. web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>guestBook_prop</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<display-name>MainServlet</display-name>
<servlet-name>MainServlet</servlet-name>
<servlet-class>org.smart.control.MainServlet</servlet-class>
<init-param>
<param-name>dbTypePath</param-name>
<param-value>/WEB-INF/dbtype.properties</param-value>
</init-param>
<init-param>
<param-name>cmdsInfoPath</param-name>
<param-value>/WEB-INF/cmdsInfo.properties</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
15. index.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<jsp:forward page="start.do" />
16. main.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ page import="org.smart.bean.GuestBook" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>main.jsp</title>
</head>
<body>
<form action="write.do" method="post">
<input type="text" name="content" />
<input type="submit" value="글쓰기" />
<input type="reset" value="취소" />
</form>
<hr/>
<table>
<tr>
<th>번호</th>
<th>내용</th>
<th>작성일</th>
</tr>
<%
GuestBook[] books = (GuestBook[])request.getAttribute("books");
if(books.length == 0){
%>
<tr>
<td colspan="3">Empty</td>
</tr>
<%
}else{
for(GuestBook book : books){
%>
<tr>
<td><%=book.getGid() %></td>
<td><%=book.getContent() %></td>
<td><%=book.getReg() %></td>
</tr>
<%
}
}
%>
</table>
</body>
</html>
728x90
반응형
'IT > JSP Practice' 카테고리의 다른 글
[JSP Practice] - JSP MODEL 2 PreparedStatement (0) | 2020.08.04 |
---|---|
[JSP Practice] - JSP Model 2 Statement (0) | 2020.08.04 |
[JSP Practice] - JSP 로그인, 회원가입(CRUD) Model1 방식 (0) | 2020.07.30 |
[JSP Practice] - JSP 게시판 CRUD + 페이징(Paging)처리 Model 1 방식 (0) | 2020.07.27 |
[JSP Practice] - JSP 게시판 CRUD(글쓰기, 읽기, 수정, 삭제) Model 1 방식 (0) | 2020.07.24 |
댓글