MVC(2)
이제 TYPE 어노테이션뿐만 아니라 METHOD 어노테이션까지 추가해서,
DAO 까지 만들어보자.
예시로 Model은 하나만 만들 것이기 때문에 xml이나 Interface 등은 사용하지 않는다.
우선 어노테이션을 만들어 준다!
메모리를 할당할 클래스는 @Controller 로 구분하고,
메서드는 @RequestMapping으로 구분할 것이다.
Controller.java (Annotation)
package controller;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
//Controller 어노테이션이 들어간다 = Model이다.
@Retention(RUNTIME)
@Target(TYPE)
public @interface Controller {}
RequestMapping.java (Annotation)
package controller;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
//@ReuqestMapping("list.do");
@Retention(RUNTIME)
@Target(METHOD)
//메서드를 찾아준다.
public @interface RequestMapping {
//이 안에 들어가는 문자열로 구분할 것이다.
public String value();
}
RequestMapping의 경우 메모리를 할당할 지 말지 구분하는 것이 아니라,
손쉽게 원하는 메서드를 찾아주는 인덱스 역할을 한다.
→ 원하는 메서드의 위에 @RequestMapping("값") 을 붙이면,
그 값으로 해당 메서드를 찾을 수 있도록 해 준다.
FoodDAO.java (Class) - DBCP
server.xml에 등록해준 대로 데이터베이스에 연결하고 값을 가져온다.
package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class FoodDAO {
private Connection conn;
private PreparedStatement ps;
public void getConnection() {
try {
Context init = new InitialContext(); //탐색기를 열고
Context c = (Context) init.lookup("java://comp/env");
//Connection이 저장돼 있는 곳으로!
DataSource ds = (DataSource) c.lookup("jdbc/oracle");
conn = ds.getConnection();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void disConnection() {
try {
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (Exception ex) {
System.out.println("disConnection() Error");
ex.printStackTrace();
}
}
public List < CategoryVO > categoryListData(int no) {
List < CategoryVO > list = new ArrayList < CategoryVO > ();
try {
int start = 0, end = 0;
if (no == 1) { //믿고 보는 맛집 리스트
start = 1;
end = 12;
}
if (no == 2) { //지역별 인기 맛집
start = 13;
end = 18;
}
if (no == 3) { //메뉴별 인기 맛집
start = 19;
end = 30;
}
getConnection();
String sql = "SELECT cno, title, subject, poster " +
"FROM food_category " +
"WHERE cno BETWEEN ? AND ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, start);
ps.setInt(2, end);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
CategoryVO vo = new CategoryVO();
vo.setCno(rs.getInt(1));
vo.setTitle(rs.getString(2));
vo.setSubject(rs.getString(3));
vo.setPoster(rs.getString(4));
list.add(vo);
}
rs.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
disConnection(); //재사용을 위한 반환
}
return list;
}
public List < FoodVO > food_list(int cno) {
List < FoodVO > list = new ArrayList < FoodVO > ();
try {
getConnection();
String sql = "SELECT fno, name, tel, type, poster, address " +
"FROM food_house " +
"WHERE cno=?";
ps = conn.prepareStatement(sql);
ps.setInt(1, cno);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
FoodVO vo = new FoodVO();
vo.setFno(rs.getInt(1));
vo.setName(rs.getString(2));
vo.setTel(rs.getString(3));
vo.setType(rs.getString(4));
vo.setPoster(rs.getString(5));
vo.setAddress(rs.getString(6));
list.add(vo);
}
rs.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
disConnection();
}
return list;
}
}
FoodModel.java (Class)
@Controller로 FoodModel 클래스에 메모리를 할당한다.
그리고 @RequestMapping으로 각 메서드를 찾을 값을 지정하고, request에 값을 담아 전송하는 기능을 구현한다.
리턴값은 결과 화면을 출력할 jsp페이지의 이름으로 지정한다.
package model;
import controller.Controller;
import controller.RequestMapping;
import dao.*;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
@Controller
public class FoodModel {
@RequestMapping("food/category.do")
public String food_category(HttpServletRequest request) {
String no = request.getParameter("no");
if (no == null)
no = "1";
FoodDAO dao = new FoodDAO();
List < CategoryVO > list = dao.categoryListData(Integer.parseInt(no));
request.setAttribute("list", list);
System.out.println("food_category() call~");
// request.setAttribute("msg", "카테고리 출력합니다.");
return "../food/category.jsp";
}
@RequestMapping("food/food_list.do")
public String food_list(HttpServletRequest request) {
String cno = request.getParameter("cno");
FoodDAO dao = new FoodDAO();
List < FoodVO > list = dao.food_list(Integer.parseInt(cno));
request.setAttribute("list", list);
System.out.println("food_list() call~");
// request.setAttribute("msg", "카테고리별 맛집 출력합니다.");
return "../food/food_list.jsp";
}
}
이제 DispatcherServlet.java (Servlet)에서 clsList에 모델을 등록하고,
@RequestMapping으로 지정해준 값을 이용해 그에 맞는 메서드를 호출한다.
//사용자가 요청한 URL을 읽어 온다. (맨 뒤에 .do)
String uri = request.getRequestURI();
uri = uri.substring(request.getContextPath().length() + 1);
System.out.println(uri); //food/category.do
우선 사용자가 요청한 URI를 읽어 온다.
request.getRequestURI()로, 전체 URL에서 URI부분만 읽는다.
URL = http:localhost:8080/0727MVCProject5/food/category.do
URI = /0727MVCProject5/food/category.do 부분만.
그리고 getContextPath()로 "/0727MVCProject"을 불러와 해당 위치 이후의 값을 읽어 온다.
결과적으로, food/category.do 부분만 읽어 uri 라는 변수에 저장하는 것이다.
이 URI와 RequestMapping에 등록된 값이 같은 메서드를 호출하라! 고 시키는 것이다.
단, ?no=1과 같은 파라미터들은 request에 따로 담겨 오는것이기 때문에 request.getRequestURI()에서 제외된다.
Model을 등록한 클래스 리스트(clsList)에서
리스트에 있는 모든 클래스를 가져와 메모리를 할당하고 그 안의 모든 메서드를 가져 온다.
RequestMapping 객체를 생성하여 methods 중 @RequestMapping을 가진 메서드를 불러 온다.
그리고 그 안에서 rm.value()와 동일한 URI를 가진 메서드를 불러와 호출하고,
그 메서드가 적절한 처리 후 결과에 request에 담아 보내 준다!
for (String cls: clsList) {
Class clsName = Class.forName(cls);
if (clsName.isAnnotationPresent(Controller.class) == false)
continue;
Object obj = clsName.getDeclaredConstructor().newInstance();
Method[] methods = clsName.getDeclaredMethods();
for (Method m: methods) {
RequestMapping rm = m.getAnnotation(RequestMapping.class);
if (uri.equals(rm.value())) {
//rm이 갖고있는 값
String jsp = (String) m.invoke(obj, request);
//obj가 가진 메서드를 찾아서 호출한다.
RequestDispatcher rd = request.getRequestDispatcher(jsp);
rd.forward(request, response);
return;
}
}
}
위 과정의 전체를 나타내면 아래와 같다.
DispatcherServlet.java (Servlet)
package controller;
//Dispatcher이 컨트롤러 이름임
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
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 java.util.*;
import model.*;
@WebServlet("*.do")
/*
내가 마음대로 둬도된다.
*은 그 자리에 어떤 단어가 들어와도 이 서블릿(DispatcherServelt)을 찾아줄 수 있다는 뜻
list.do, find.do 등.. 다 DispatcherServelt을 찾아줄 수 있게 된다.
URI가 do로 끝나지 않으면 "요청된 리소스 [/0727MVCProject5/food/category.ex]은(는) 가용하지 않습니다." 뜸 */
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1 L;
List < String > clsList = new ArrayList < String > ();
public void init(ServletConfig config) throws ServletException {
clsList.add("model.FoodModel");
}
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
//사용자가 요청한 URL을 읽어 온다. (맨 뒤에 .do)
String uri = request.getRequestURI();
uri = uri.substring(request.getContextPath().length() + 1);
//http://localhost:8080/0727MVCProject5/food/category.do 이 전체는 URL
//URI는 /0727MVCProject5/category.do 부분만.
//ContextPath는 0727MVCProject
//?no=1 이런거는 request에 담겨 오는것임. request.getRequestURI()에서 제외됨
System.out.println(uri); //food/category.do
//이 URI와 RequestMapping 이름이랑 같으면 호출하라! 고 시키는 것임
for (String cls: clsList) {
Class clsName = Class.forName(cls);
//Controller도 꼭 붙여줘야함
if (clsName.isAnnotationPresent(Controller.class) == false)
continue;
Object obj = clsName.getDeclaredConstructor().newInstance();
//생성자를 가져와서 메모리 할당을 하겠다~
//메서드 찾기
Method[] methods = clsName.getDeclaredMethods();
//이 안에 있는 메서드를 모두 가져와라.
for (Method m: methods) {
//메서드에 있는 어노테이션을 가져온다.
//(어노테이션은 한 번에 여러 개도 올라갈 수 있음)
RequestMapping rm = m.getAnnotation(RequestMapping.class);
if (uri.equals(rm.value())) {
//rm이 갖고있는 값
String jsp = (String) m.invoke(obj, request);
//obj가 가진 메서드를 찾아서 호출한다.
RequestDispatcher rd = request.getRequestDispatcher(jsp);
rd.forward(request, response);
return;
}
}
}
} catch (Exception ex) {}
}
}
받은 결과값들을 화면에 적절하게 뿌려주면 끝!
category.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
.container{
margin-top: 50px;
}
.row{
margin: 0px auto;
width: 960px;
}
</style>
</head>
<body>
<%-- <h1>${msg }</h1> --%>
<div class="container">
<div class="row">
<div class="text-center">
<a href="category.do?no=1" class="btn btn-sm btn-success">믿고 보는 맛집 리스트</a>
<a href="category.do?no=2" class="btn btn-sm btn-danger">지역별 맛집 리스트</a>
<a href="category.do?no=3" class="btn btn-sm btn-primary">메뉴별 맛집 리스트</a>
</div>
</div>
<div style="height: 20px"></div>
<div class="row">
<c:forEach var="vo" items="${list }">
<div class="col-md-4">
<div class="thumbnail">
<a href="food_list.do?cno=${vo.cno }">
<img src="${vo.poster }" alt="Lights" style="width:250px; height:200px;">
<div class="caption">
<p>${vo.title }</p>
</div>
</a>
</div>
</div>
</c:forEach>
</div>
</div>
</body>
</html>
food_list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<style type="text/css">
.container{
margin-top: 50px;
}
.row{
margin: 0px auto;
width: 700px;
}
</style>
</head>
<body>
<%-- <h1>${msg }</h1> --%>
<div class="container">
<div class="row">
<c:forEach var="vo" items="${list }">
<table class="table">
<tr>
<th width="30%" class="text-center" rowspan="4">
<img src="${vo.poster }" style="width:200px; height:150px">
</th>
<td width="70%"><h3>${vo.name }</h3></td>
</tr>
<tr>
<td width="70%">${vo.address }</td>
</tr>
<tr>
<td width="70%">${vo.tel }</td>
</tr>
<tr>
<td width="70%">${vo.type }</td>
</tr>
</table>
</c:forEach>
</div>
</div>
</body>
</html>
완성~
Mac과 Windows 공동 작업을 위한 XML 읽기
지금까지는 패키지 단위로 클래스를 읽어올 때 수동으로 경로를 입력하거나,
xml에 등록하거나, 직접 클래스명을 지정하여 등록해 왔다!
이번에는...
⑴ xml파일에 패키지를 등록하고,
⑵ 현재 위치를 인식하여 해당 xml파일의 경로를 자동으로 지정하고,
⑶ xml을 읽어 그 패키지 안에 있는 클래스도 자동으로! 읽어오도록 해 볼 것이다.
application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<component-scan base-package="model"/>
</beans>
*경로 구분자를 사용할 때 직접 입력하지 않고, File.separator 을 사용해 주면
Mac와 Windows 운영체제의 공동 작업에 유용하다.
DispatcherServlet.java (Servlet)
package controller;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
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.xml.parsers.*;
import org.w3c.dom.*;
import java.net.*;
import java.util.*;
//Mac과 Windows를 호환할 수 있는 XML 읽기
/*
* XML 파싱방법
* - JAXP : DOM / SAX (MyBatis, Spring)
* DOM : 메모리에 트리 형태로 저장 후 처리한다 (수정, 삭제, 추가)
* SAX : 한 줄씩 태그의 값을 읽어 온다 (읽기 전용)
* => XML
* 데이터 저장 위치 -> <태그>데이터</태그> <태그 속성="데이터">
* - JAXB : 빅데이터 (클래스 변수 == 태그명) ==> 1.8까지 지원
*/
@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1 L;
private List < String > pkgList = new ArrayList < String > (); //XML에서 패키지를 읽어 옴
private List < String > clsList = new ArrayList < String > (); //패키지 안의 클래스를 모은다
public void init(ServletConfig config) throws ServletException {
try {
URL url = this.getClass().getClassLoader().getResource("."); //resource에 .을 주면 현재 폴더를 의미한다.
File file = new File(url.toURI());
System.out.println(file.getPath());
//C:\webDev\webStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\0727SpringMVCProject\WEB-INF\classes
//현재 경로명을 읽어 오는 것.. 그래야 경로명 지금처럼 읽어 올 필요가 없음.
String path = file.getPath();
path = path.replace("\\", File.separator); //Mac은 /로 Windows는 \\로 바꿔준다!!!(공동작업용)
System.out.println(path);
//C:\webDev\webStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\0727SpringMVCProject\WEB-INF\classes
path = path.substring(0, path.lastIndexOf(File.separator));
System.out.println(path);
//C:\webDev\webStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\0727SpringMVCProject\WEB-INF
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(path + File.separator + "application.xml")); //윈도우면 \\, 맥이면 /
Element rootTag = doc.getDocumentElement();
System.out.println(rootTag.getTagName());
//beans -> XML을 읽었다~
NodeList list = rootTag.getElementsByTagName("component-scan");
for (int i = 0; i < list.getLength(); i++) {
Element cs = (Element) list.item(i); //cs:component-scan
String value = cs.getAttribute("base-package");
pkgList.add(value);
}
for (String s: pkgList) {
System.out.println(s); //패키지명이 출력됨
path = path.substring(0, path.lastIndexOf(File.separator));
System.out.println(path);
//C:\webDev\webStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\0727SpringMVCProject
String ss = path + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + s.replace(".", File.separator);
File dir = new File(ss);
File[] files = dir.listFiles();
for (File f: files) {
// System.out.println(f.getName());
String sss = s + "." + f.getName().substring(0, f.getName().lastIndexOf("."));
//model.ListModel.class에서 .class를 떼려구
System.out.println(sss);
}
}
} catch (Exception ex) {}
}
//Model 등록
//Model을 찾아서 요청 수행 => JSP찾기 => request, session으로 전송
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// 사용자 URL - http://localhost:8080/SpringMVCProject/main/main.do
String uri = request.getRequestURI(); // /SpringMVCProject/main/main.do
uri = uri.substring(request.getContextPath().length() + 1); // main/main.do
//Model 클래스 찾기
for (String strCls: clsList) {
Class clsName = Class.forName(strCls);
if (clsName.isAnnotationPresent(Controller.class) == false)
continue; //클래스 위에 @Controller 있는지 확인하고 없으면 제외
//메모리 할당
Object obj = clsName.getDeclaredConstructor().newInstance();
//요청 처리
Method[] methods = clsName.getDeclaredMethods(); //Model클래스에 선언된 모든 메서드를 가져 온다.
for (Method m: methods) {
RequestMapping rm = m.getAnnotation(RequestMapping.class);
//메서드 위에 @RequestMapping 이 있는지 확인
if (uri.equals(rm.value())) { //처리 메서드를 찾아서 수행
String jsp = (String) m.invoke(obj, request, response);
/*
* Model 메서드는 앞으로 이렇게 만들것임
* @RequestMapping("uri")
* public String main_main(HttpServletRequest request, HttpServletResponse response){
* return "출력할 JSP";
* request : 요청값을 받아 처리해서 setAttribute()로 넘겨줌
* response : Cookie, 파일 업로드 등의 응답
* }
*/
//이동은 sendRedirect, forward로 진행
//sendRedirect : 기존에 만들어진 파일로 이동/재호출 , request를 초기화
//forward : 화면 출력, request 보존해서 전송
if (jsp.startsWith("redirect")) {
//return "redirect:../main/main.do" 이렇게 보내주고
response.sendRedirect(jsp.substring(jsp.indexOf(":") + 1)); //../main/main.do
} else {
// return "../main/main.jsp" 이렇게 보내주기로 약속합시다(사유:스프링에서 이렇게 함)
RequestDispatcher rd = request.getRequestDispatcher(jsp);
rd.forward(request, response); //jsp 한테 request와 response를 보내라~
}
return;
}
}
}
} catch (Exception ex) {}
}
}
⑴아래 DispatcherServlet.java, RequestMapping.java, Controller.java를 하나의 패키지에 넣고
⑵해당 패키지를 jar 파일로 export해서
⑶다른 프로젝트에서 lib에 추가해 주면
→ 간단하게 MVC 구조를 사용할 수 있게 된다.
같은 내용의 코드를 일일이 작성하지 않아도 되어 굉장히 편리하다!
***물론 import한 jar을 구성하는 코드들에서 지정한 양식을 지켜 프로그래밍해야 한다.
Controller.java (Annotation)
package controller;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
//Controller 어노테이션이 들어간다 = Model이다.
@Retention(RUNTIME)
@Target(TYPE)
public @interface Controller {}
RequestMapping.java (Annotation)
package controller;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
//@ReuqestMapping("list.do");
@Retention(RUNTIME)
@Target(METHOD)
//메서드를 찾아준다.
public @interface RequestMapping {
//이 안에 들어가는 문자열로 구분할 것이다.
public String value();
}
DispatcherServlet.java (Servlet)
package controller;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
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.xml.parsers.*;
import org.w3c.dom.*;
import java.net.*;
import java.util.*;
//Mac과 Windows를 호환할 수 있는 XML 읽기
/*
* XML 파싱방법
* - JAXP : DOM / SAX (MyBatis, Spring)
* DOM : 메모리에 트리 형태로 저장 후 처리한다 (수정, 삭제, 추가)
* SAX : 한 줄씩 태그의 값을 읽어 온다 (읽기 전용)
* => XML
* 데이터 저장 위치 -> <태그>데이터</태그> <태그 속성="데이터">
* - JAXB : 빅데이터 (클래스 변수 == 태그명) ==> 1.8까지 지원
*/
@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1 L;
private List < String > pkgList = new ArrayList < String > (); //XML에서 패키지를 읽어 옴
private List < String > clsList = new ArrayList < String > (); //패키지 안의 클래스를 모은다
public void init(ServletConfig config) throws ServletException {
try {
URL url = this.getClass().getClassLoader().getResource("."); //resource에 .을 주면 현재 폴더를 의미한다.
File file = new File(url.toURI());
System.out.println(file.getPath());
//C:\webDev\webStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\0727SpringMVCProject\WEB-INF\classes
//현재 경로명을 읽어 오는 것.. 그래야 경로명 지금처럼 읽어 올 필요가 없음.
String path = file.getPath();
path = path.replace("\\", File.separator); //Mac은 /로 Windows는 \\로 바꿔준다!!!(공동작업용)
System.out.println(path);
//C:\webDev\webStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\0727SpringMVCProject\WEB-INF\classes
path = path.substring(0, path.lastIndexOf(File.separator));
System.out.println(path);
//C:\webDev\webStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\0727SpringMVCProject\WEB-INF
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File(path + File.separator + "application.xml")); //윈도우면 \\, 맥이면 /
Element rootTag = doc.getDocumentElement();
System.out.println(rootTag.getTagName());
//beans -> XML을 읽었다~
NodeList list = rootTag.getElementsByTagName("component-scan");
for (int i = 0; i < list.getLength(); i++) {
Element cs = (Element) list.item(i); //cs:component-scan
String value = cs.getAttribute("base-package");
pkgList.add(value);
}
for (String s: pkgList) {
System.out.println(s); //패키지명이 출력됨
path = path.substring(0, path.lastIndexOf(File.separator));
System.out.println(path);
//C:\webDev\webStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\wtpwebapps\0727SpringMVCProject
String ss = path + File.separator + "WEB-INF" + File.separator + "classes" + File.separator + s.replace(".", File.separator);
File dir = new File(ss);
File[] files = dir.listFiles();
for (File f: files) {
// System.out.println(f.getName());
String sss = s + "." + f.getName().substring(0, f.getName().lastIndexOf("."));
//model.ListModel.class에서 .class를 떼려구
System.out.println(sss);
}
}
} catch (Exception ex) {}
}
//Model 등록
//Model을 찾아서 요청 수행 => JSP찾기 => request, session으로 전송
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
// 사용자 URL - http://localhost:8080/SpringMVCProject/main/main.do
String uri = request.getRequestURI(); // /SpringMVCProject/main/main.do
uri = uri.substring(request.getContextPath().length() + 1); // main/main.do
//Model 클래스 찾기
for (String strCls: clsList) {
Class clsName = Class.forName(strCls);
if (clsName.isAnnotationPresent(Controller.class) == false)
continue; //클래스 위에 @Controller 있는지 확인하고 없으면 제외
//메모리 할당
Object obj = clsName.getDeclaredConstructor().newInstance();
//요청 처리
Method[] methods = clsName.getDeclaredMethods(); //Model클래스에 선언된 모든 메서드를 가져 온다.
for (Method m: methods) {
RequestMapping rm = m.getAnnotation(RequestMapping.class);
//메서드 위에 @RequestMapping 이 있는지 확인
if (uri.equals(rm.value())) { //처리 메서드를 찾아서 수행
String jsp = (String) m.invoke(obj, request, response);
/*
* Model 메서드는 앞으로 이렇게 만들것임
* @RequestMapping("uri")
* public String main_main(HttpServletRequest request, HttpServletResponse response){
* return "출력할 JSP";
* request : 요청값을 받아 처리해서 setAttribute()로 넘겨줌
* response : Cookie, 파일 업로드 등의 응답
* }
*/
//이동은 sendRedirect, forward로 진행
//sendRedirect : 기존에 만들어진 파일로 이동/재호출 , request를 초기화
//forward : 화면 출력, request 보존해서 전송
if (jsp.startsWith("redirect")) {
//return "redirect:../main/main.do" 이렇게 보내주고
response.sendRedirect(jsp.substring(jsp.indexOf(":") + 1)); //../main/main.do
} else {
// return "../main/main.jsp" 이렇게 보내주기로 약속합시다(사유:스프링에서 이렇게 함)
RequestDispatcher rd = request.getRequestDispatcher(jsp);
rd.forward(request, response); //jsp 한테 request와 response를 보내라~
}
return;
}
}
}
} catch (Exception ex) {}
}
}
'부트캠프(END) > Web' 카테고리의 다른 글
MyBatis : 기초 (0) | 2022.07.29 |
---|---|
MVC (1) (0) | 2022.07.27 |
EL/JSTL (0) | 2022.07.25 |