RequestDispatcher 클래스
url - pattern(디렉토리 패턴, 확장자 패턴)
전체 다 받는다
분산해서 할 수 있도록 커맨드 패턴 사용
FrontController 패턴
한곳에서 요청을 다 받고 다시 위임 하는 식
요청한 urL의 차이나는 부분 발췌 다시 요청하는 방식이다.
확장자 패턴, FrontController 패턴 예제
확장자 패턴이 모이는 프론트 컨트롤러
pattern.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>확장자 패턴이 모이는 프론트 컨트롤러</title>
</head>
<body>
<h2>*.do 끝나는 확장자들</h2>
<a href="insert.do">데이터 입력</a><br/>
<hr/>
<a href="http://localhost:8080<%=request.getContextPath() %>/update.do">데이터 수정</a><br/>
<hr/>
<a href="<%=request.getContextPath() %>/select.do">데이터 조회</a>
<hr/>
<a href="delete.do">데이터 삭제</a>
<hr/>
</body>
</html>
처리를 컨트롤러에서 한다.
프론트컨트롤러를 만들어 보자
FrontController.java
package kr.gov.frontcontroller;
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;
// *.do확장자를 여기서 FrontController가 다 도맡아서 처리하겠다고 명시함.
@WebServlet("*.do")
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
public FrontController() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet() 호출");
actionDo(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost() 호출");
actionDo(request, response);
}
private void actionDo(HttpServletRequest request, HttpServletResponse response) {
System.out.println("actionDo() 호출");
String uri = request.getRequestURI();
System.out.println("URI : "+ uri);
}
}
url -> full path
http://localhost:8080/Chap18_Useful_Patterns/insert.do
uri -> contextpath ~end
/Chap18_Useful_Patterns/insert.do
pattern.jsp 실행
콘솔 출력
Command 패턴
요청을 받아서 인터페이스 상속받은 클래스가 해당된 요청을 해당된 클래스가 구현하는 것이다.
Command 예제
FrontController.java
package kr.gov.frontcontroller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// *.do확장자를 여기서 FrontController가 다 도맡아서 처리하겠다고 명시함.
@WebServlet("*.do")
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
public FrontController() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet() 호출");
actionDo(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost() 호출");
actionDo(request, response);
}
private void actionDo(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("actionDo() 호출");
String uri = request.getRequestURI();
System.out.println("URI : "+ uri);
//getContextPath()는 프로젝트명이 리턴됨.
String contextPath = request.getContextPath();
System.out.println("contextPath : "+ contextPath);
//직접 실행되어야할 파일의 이름을 얻어냄
String command = uri.substring(contextPath.length());
System.out.println("command : " +command);
if(command.equals("/insert.do")) {
System.out.println("----------------------");
System.out.println("/insert.do 페이지 호출");
System.out.println("----------------------");
}
else if(command.equals("/update.do")) {
System.out.println("----------------------");
System.out.println("/update.do 페이지 호출");
System.out.println("----------------------");
}
else if(command.equals("/select.do")) {
System.out.println("/select.do 페이지 호출");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html><head></head><body>");
out.println("</body></html>");
}
else if(command.equals("/delete.do")) {
System.out.println("----------------------");
System.out.println("/delete.do 페이지 호출");
System.out.println("----------------------");
}
}
}
pattern.jsp 실행
MVC 패턴 예제 ▽
MVC패턴 작동 순서 (단순히 호출만 본다.) 단순 select
먼저 패턴.jsp 실행 ->
프론트 컨트롤러(servlet) select,do 찾는다. 호출
커맨드로 select를 발췌 잘라냄(command 패턴) =>
프론트 컨트롤러가 execute작업(get)하나씩 변수에 저장 후 비즈니스 계층에 모델(서비스 호출) 요청 =>
------------------------------------------------------------------------------------------------------------
//이부분으로 서비스를 호출한다 프론트 컨트롤러가 호출
Service service = new PersonListService(); //인터페이스의 다형성 적용해서 객체를 만든 것
ArrayList<PersonDto> dtos = service.execute(request, response);
//service 인터페이스를 상속한 PersonListService.java가 호출이 된다.
@Override
public ArrayList<PersonDto> execute(HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
return null;
}
-----------------------------------------------------------------------------------------------------------
=>
서비스는 바로 받을 수 없기떄문에 상속을 받은 해당 클래스를 오버라이드(PersonList.java) 한다.
필요한 메서드가 생기면 추가 해서 오버라이드 해준다.
서비스는 DAO 호출 요청 (유지보수를 위해서 계층별로 나누어 놓은 것이다.)=>
=>
-----------------------------------------------------------------------------------------------------------
PersonList.java
personsAll() 메서드로 요청한다
dao.personsAll();
dao
public ArrayList<PersonDto> personsAll(){} 요청 받음
-----------------------------------------------------------------------------------------------------------
=>
DAO(싱글톤 패턴적용 자기자신의 객체를 참조변수로 가지고 있다.)는 DB에 요청
DBCP 사용해서 DB연결 DTO set을 했던것을 get한다. =>
마지막으로 patern.jsp를 실행해서 조회선택 후 결과를 확인한다.
jsp model2
servlet이 컨트롤러 역할을 한다. (이미지 참고)
model쪽에 service 영역이 포함이 된다.
모델1 << 적용중
모델2
mvc패턴으로 값 출력하기
DB 만들기 - DBeaver
JSP_connection_query.sql
drop database if exists persondb;
create database persondb;
use persondb;
drop table if exists person;
create table person(
id varchar(10) primary key,
pw varchar(20),
name varchar(20),
email varchar(20),
address varchar(50)
);
select *
from person;
insert into person values ("1", "0217", "이성계", "lee@ggamil.com", "서울시 영등포구");
insert into person values ("2", "0217", "정도전", "jung@ggamil.com", "부산시 서면");
insert into person values ("3", "0217", "이방원", "lee2@ggamil.com", "대구시 중구");
insert into person values ("4", "0217", "하륜", "ha@ggamil.com", "구미시 원평동");
insert into person values ("5", "0217", "이도", "lee3@ggamil.com", "서울시 마포구");
PersonDto.java -> DTO 만들기
package kr.gov.dto;
public class PersonDto {
private String id;
private String pw;
private String name;
private String email;
private String address;
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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Service추가
interface => 추상메서드만 포함되어 오버라이드를 반드시 해줘야 한다.
Service.java (interface)
package kr.gov.command;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.gov.dto.PersonDto;
public interface Service {
//공통적으로 Service 인터페이스를 기능별로 구현할 클래스들을 만들어주면 됨.
public ArrayList<PersonDto> execute(HttpServletRequest request, HttpServletResponse response);
}
server context.xml 커넥션풀 변경
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--><!-- The contents of this file will be loaded for each web application --><Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<!-- 서버에서 DBCP를 사용하겠다라고 기재하는 코드 -->
<Resource
name = "jdbc/dbconn"
auth = "Container"
driverClassName = "com.mysql.cj.jdbc.Driver"
url = "jdbc:mysql://localhost:3306/persondb?serverTimezone=UTC"
username = "root"
password = "7496"
type = "javax.sql.DataSource"
maxActive = "50"
maxIdle = "10"
maxWait = "5000"
/>
</Context>
FrontController.java select 부분 추가
package kr.gov.frontcontroller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// *.do확장자를 여기서 FrontController가 다 도맡아서 처리하겠다고 명시함.
@WebServlet("*.do")
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
public FrontController() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet() 호출");
actionDo(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost() 호출");
actionDo(request, response);
}
private void actionDo(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("actionDo() 호출");
String uri = request.getRequestURI();
System.out.println("URI : "+ uri);
//getContextPath()는 프로젝트명이 리턴됨.
String contextPath = request.getContextPath();
System.out.println("contextPath : "+ contextPath);
//직접 실행되어야할 파일의 이름을 얻어냄
String command = uri.substring(contextPath.length());
System.out.println("command : " +command);
if(command.equals("/insert.do")) {
System.out.println("----------------------");
System.out.println("/insert.do 페이지 호출");
System.out.println("----------------------");
}
if(command.equals("/update.do")) {
System.out.println("----------------------");
System.out.println("/update.do 페이지 호출");
System.out.println("----------------------");
}
if(command.equals("/select.do")) {
System.out.println("/select.do 페이지 호출");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html><head></head><body>");
out.println("</body></html>");
}
if(command.equals("/delete.do")) {
System.out.println("----------------------");
System.out.println("/delete.do 페이지 호출");
System.out.println("----------------------");
}
}
}
DAO 추가 DB와 관련된 기능처리 - 싱글톤 패턴 적용 -DB접속 커넥션 사용 - dbcp사용시 커넥션풀 찾아갈때 jndi 사용
PersonDao.java => Service에서 받음 => FrontControlle에서 요청
package kr.gov.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import kr.gov.dto.PersonDto;
public class PersonDao {
private static PersonDao instance = new PersonDao();
public PersonDao() {
}
//PersonDao생성해서 리턴해주는 정적메서드(싱글톤패턴)
public static PersonDao getInstance() {
return instance;
}
//DB접속
private Connection getConnection() throws Exception {
Context context = new InitialContext();
DataSource dataSource = (DataSource)context.lookup("java:comp/env/" + "jdbc/dbconn");
Connection conn = dataSource.getConnection();
System.out.println("DBCP 연동완료");
return conn;
}
//DB에 접속해서 회원리스트를 가져오는 메서드
public ArrayList<PersonDto> personsAll() {
ArrayList<PersonDto> dtos = new ArrayList<>();
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet resultSet = null;
String sql = "select * from person";
try {
connection = this.getConnection();
pstmt = connection.prepareStatement(sql);
resultSet = pstmt.executeQuery();
System.out.println("personAll()");
while(resultSet.next()) {
PersonDto dto = new PersonDto();
dto.setId(resultSet.getString("id"));
dto.setPw(resultSet.getString("pw"));
dto.setName(resultSet.getString("name"));
dto.setEmail(resultSet.getString("email"));
dto.setAddress(resultSet.getString("address"));
//루프를 실행하면서 생성된 PersonDto객체를 ArrayList인 dtos에 추가함.
dtos.add(dto);
}
} catch(Exception e) {
} finally {
}
return dtos;
}
}
Service를 상속받는 클래스 추가 -> DAO를 호출
PersonListService.java
package kr.gov.command;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.gov.dto.PersonDto;
public class PersonListService implements Service{
@Override
public ArrayList<PersonDto> execute(HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
return null;
}
}
프론트 컨트롤러에서 서비스를 객체로 만들어준다. 서비스가 가지고 있는 메서드 호출해서 실행
인터페이스의 다형성 적용해서 객체를 만든 것
dtos는 이미 결과를 받은것을 화면에 그려줌
FrontController.java -> 수정끝
package kr.gov.frontcontroller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
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 kr.gov.command.PersonListService;
import kr.gov.command.Service;
import kr.gov.dto.PersonDto;
// *.do확장자를 여기서 FrontController가 다 도맡아서 처리하겠다고 명시함.
@WebServlet("*.do")
public class FrontController extends HttpServlet {
private static final long serialVersionUID = 1L;
public FrontController() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet() 호출");
actionDo(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost() 호출");
actionDo(request, response);
}
private void actionDo(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("actionDo() 호출");
String uri = request.getRequestURI();
System.out.println("URI : "+ uri);
//getContextPath()는 프로젝트명이 리턴됨.
String contextPath = request.getContextPath();
System.out.println("contextPath : "+ contextPath);
//직접 실행되어야할 파일의 이름을 얻어냄
String command = uri.substring(contextPath.length());
System.out.println("command : " +command);
if(command.equals("/insert.do")) {
System.out.println("----------------------");
System.out.println("/insert.do 페이지 호출");
System.out.println("----------------------");
}
else if(command.equals("/update.do")) {
System.out.println("----------------------");
System.out.println("/update.do 페이지 호출");
System.out.println("----------------------");
}
else if(command.equals("/select.do")) {
System.out.println("/select.do 페이지 호출");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html><head></head><body>");
Service service = new PersonListService(); //인터페이스의 다형성 적용해서 객체를 만든 것
ArrayList<PersonDto> dtos = service.execute(request, response);
for(int i=0; i<dtos.size(); i++) {
PersonDto dto = dtos.get(i);
String id = dto.getId();
String pw = dto.getPw();
String name = dto.getName();
String email = dto.getEmail();
String address = dto.getAddress();
out.println(id +","+ pw +","+ name +","+ email +","+ address + "<br/><hr>");
}
out.println("</body></html>");
out.close();
}
else if(command.equals("/delete.do")) {
System.out.println("----------------------");
System.out.println("/delete.do 페이지 호출");
System.out.println("----------------------");
}
}
}
서비스 쪽에 dto를 전달
PersonDao.java
package kr.gov.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import kr.gov.dto.PersonDto;
public class PersonDao {
private static PersonDao instance = new PersonDao();
public PersonDao() {
}
//PersonDao생성해서 리턴해주는 정적메서드(싱글톤패턴)
public static PersonDao getInstance() {
return instance;
}
//DB접속
private Connection getConnection() throws Exception {
Context context = new InitialContext();
DataSource dataSource = (DataSource)context.lookup("java:comp/env/" + "jdbc/dbconn");
Connection conn = dataSource.getConnection();
System.out.println("DBCP 연동완료");
return conn;
}
//DB에 접속해서 회원리스트를 가져오는 메서드
public ArrayList<PersonDto> personsAll() {
ArrayList<PersonDto> dtos = new ArrayList<>();
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet resultSet = null;
String sql = "select * from person";
try {
connection = this.getConnection();
pstmt = connection.prepareStatement(sql);
resultSet = pstmt.executeQuery();
System.out.println("personAll()");
while(resultSet.next()) {
PersonDto dto = new PersonDto();
dto.setId(resultSet.getString("id"));
dto.setPw(resultSet.getString("pw"));
dto.setName(resultSet.getString("name"));
dto.setEmail(resultSet.getString("email"));
dto.setAddress(resultSet.getString("address"));
//루프를 실행하면서 생성된 PersonDto객체를 ArrayList인 dtos에 추가함.
dtos.add(dto);
}
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
if(resultSet != null) resultSet.close();
if(pstmt != null) pstmt.close();
if(connection != null) connection.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
return dtos;
}
}
프론트 컨트롤러에서
서비스 excute를 호출
resultset에 있던것을 get해서 ArrayList안에 넣어서 dtos리턴
PersonListService.java => 수정끝
package kr.gov.command;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kr.gov.dao.PersonDao;
import kr.gov.dto.PersonDto;
public class PersonListService implements Service{
@Override
public ArrayList<PersonDto> execute(HttpServletRequest request, HttpServletResponse response) {
PersonDao dao = PersonDao.getInstance(); //Dao 객체 생성
//DB에 있는 person테이블에 있는 데이터를 다 ArrayList<PersonDto>에 저장을해서 리턴을 해준 상태
ArrayList<PersonDto> dtos = dao.personsAll();
return dtos;
}
}
마지막으로
patern.jsp 실행
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>확장자 패턴이 모이는 프론트 컨트롤러</title>
</head>
<body>
<h2>*.do 끝나는 확장자들</h2>
<a href="insert.do">데이터 입력</a><br/>
<hr/>
<a href="http://localhost:8080<%=request.getContextPath() %>/update.do">데이터 수정</a><br/>
<hr/>
<a href="<%=request.getContextPath() %>/select.do">데이터 조회</a>
<hr/>
<a href="delete.do">데이터 삭제</a>
<hr/>
</body>
</html>