모델1기법
- 개발 속도가 빠름. 하나의 파일 안에 다 적는 것
- 자바코드 + 웹코드
- 개발 시간 줄어들지만 유지보수가 어려워지고 확장하기도 어려다.
모델2기법 (MVC)
두 개를 나눠놓은 거
요청 ---> JSP로 하는건 막혀있다.
http://localhost:8080/projectMyBatis/member/writeForm.jsp
이렇게 바로 jsp로 요청하는건 막힌다.
모든 요청을 Servlet이 받아라 하는 것
jsp로 바로가게 하는 건 막음.
회원가입해주세요 로그인해주세요 요청을 하게되면 Servlet이던 jsp던 request, response를 가지고 있다. (특징임)
request와 response를 Servlet과 JSP가 각각 쥐고있는 것
Servlet은 받아주는 Control C역할
JAVA가 M역할 - 일을 한다.
Servlt은 forward로 돌려버리면서 Servlet과 JSP가 하나로 합쳐지면서
JSP가 V역할 보이는 역할을 하게된다.
회원가입해주세요 로그인해주세요 요청을 해서 들어온다. ---> Servlet 여기서 if문을 돌린다. (요청 == 회원가입) --> write라는 자바파일로 연결해줘야한다. (요청 == 로그인) 이면 login 자바파일로 가야되는데
이렇게 되면 if문이 너무 많이 생기게된다. 그럼 나중에 과부하가 일어나게 된다.
if문을 안 쓰면 properties의 도움을 받는다 (환경설정 파일)
요청이 회원가입이 들어오면 write라는 자바파일로 가라 연결해준다.
요청이 로그인이 들어오면 login 이라는 자바파일로 가라 연결해준다.
회원가입해도 Servlet한테 가고 로그인해도 Servlet으로 간다.
각자 wrtie클래스, login클래스로 가야되는데 모르니까 *.properties로 간다.
properties에서 어느 자바파일로 갈지를 얻어오는 것이다.
properties는 반드시 web.xml에 등록해서 이런 환경설정 파일이 있는지를 알려줘야한다.
Servlet은 request, response에 의해서 받아서 properties를 통해서 얻어오는 것
class write {
}
class login {
}
데이터를 받아서 DB에가서 일처리를 하고 돌아와야하는데
뭘 만들어줘야 명령어들을 쓸 수 있을까?
데이터 받아오세요
request.getParameter( ~~~ ) 이런 명령어를 쓰기 위해서는 함수(메서드)를 만들어줘야 한다.
class write {
void write( ) {
}
}
class login{
void login ( ) {
}
}
클래스가 10개인데 그 때마다 함수 이름이 다 다르면 다 외워야한다.
그러므로 하나로 통일시켜야한다.
추상메서드를 만들어야한다.
1. abstract ---- 추상클래스를 선호하지 않는다. 자바는 다중상속을 허용하지 않기 때문에
2. interface ---- 그러므로 얘로 해야한다.
interface로
Parent {
추상메소드( ) {
}
}
class write {
추상메소드( ) { -- 오버라이드
request..getParameter("~~~"); --- 이렇게만 쓰면 명령이 틀린다. error뜬다 왜??
}
}
얘는 일반 자바파일인데 request가 없다.
request를 가지고 있는건 Servlet과 JSP밖에 없다.
Servlet이 추상메서드를 호출할 때 request와 response를 실어서 보내야한다.
그래야 JAVA에서 오버라이드해서 쓸 수가 있게 되는 것이다.
request.setAtrribute("apple") 이렇게 보낼 떄
servlet에 데이터를 실어서 보내면 jsp 로 간다.
하지만 jsp는 모르니까 forward를 시켜버린다. 그러면 jsp의 request는 죽어버리므로
request가 다 통일되게 된다.
메모리에서 실행하게 되면 JSP Servlet Java 세 개가 한 번에 움직이는 것이므로 무거워진다고 보면된다.
class login{
추상메소드( ) { -- 오버라이드
}
}
확장하게 되면 Servlet은 안 바뀐다.
Servlet은 요청 받고 java에 일을하라고 던지고 java가 db갔다와서 일하면
그 데이터를 받아서 화면에 뿌리라고 jsp한테 말한다.
Servlet은 전달역할만 하고 일을 안한다.
나중에보면 Servlet은 하나도 안 바뀐다.
확장을 하게되면 properties, java, jsp만 확장되는 것이다.
Servlet은 하나도 안 바뀐다.
요청을 하게되면 Servlet으로 향한다. 처리를 properties에서 한다.
properties에서는 요청 == 자바파일 (이런식으로 요청 들어오면 어느 자바파일로 가겠다)
자바파일을 가지고 다시 Servlet으로 가서 부모한테 접근한다.
JAVA파일로 가는데 Parent에는 추상메서드가 준비되어있다.
이 때 반드시 Servlet은 request와 response를 같이 보내줘야한다.
request와 response를 가지고 Parent 추상메서드를 오버라이드해서 일을 처리하게 된다.
자바파일에서 처리하게 되면 Servlet으로 갈 때
어떤 JSP 파일로 갈 건지(어떤 jsp파일을 띄우고싶어요)를 return 해야한다.
Servlet ----> jsp forward 되어있는데 주소는 Servlet으로 머물러 있고 화면은 JSP를 띄워주는게
error는 어디서 터질지를 모른다. Servlet에서만 error를 찾으려고 하면 안된다.
Dynamic Web Project : memberMVC ( 회원가입 / 로그인 )
Folder: member, image, js, sql (복사)
Package: member.dao (복사)
member.bean (복사)
mapper, db.properties, mybatis-config.xml (복사)
jar파일
(projectMyBatis에 있는거)
Package : com.control
ControlServlet.java ( 서블릿 파일 )
execute(request, response);
요청이 get방식으로 와도 execute로 넘어가고 / post방식으로 와도 execute로 넘어온다.
추가 처리해줘야하는 것 : post방식일 때 한글처리 해주기
ControlServlet.java
package com.control;
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;
public class ControlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println();
if(request.getMethod().equals("POST"))
request.setCharacterEncoding("UTF-8");
}
}
서블릿을 작성하면 반드시 web.xml에 등록해야한다.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>memberMVC</display-name>
<servlet>
<servlet-name>ControlServlet</servlet-name>
<servlet-class>com.control.ControlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ControlServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
</web-app>
<url-pattern>*.do</url-pattern>
앞에 아무글씨가 와도 상관없는데 끝에 .do로 끝나는 것만 !
폴더 안에 jsp파일 호출
http://localhost:8080/memberMVC/member/writeForm.jsp --- X
이름구분자
http://localhost:8080/ memberMVC /namespace/*.do --- 무조건 Servlet으로 요청해야한다. (do로 끝나기만 하면)
writeForm부를 때 폴더x 이름구분자
http://localhost:8080/ memberMVC /member/writeForm.do
↓
do로 끝났으므로 자연스럽게 com.control.ControlServlet으로 넘어간다.
요청할 때 *.do로 하면 Servlet을 넘어간다 (execute로 넘어간다.) properties로 넘어가서 환경설정파일 읽어온다.
properties 만들어아햔다.
WEB-INF
web.xml
command.properties
command.properties - 한글처리 해주기
#요청=클래스명
/member/writeForm.do=member.service.WriteFormService
http://localhost:8080/memberMVC /member/writeForm.do
클래스의 첫 글자는 대문자 !! WriteFormService.class (뒤에 class가 생략)
공백 조심 !!!!
추상메소드는 서블릿이 호출해서 넘어갈 것
HttpServletRequest request, HttpServletResponse response 와 같이 넘어가줘야한다.
로그인 성공했는지 실패했는지 문자열을 보내줘야한다 !!
CommandProcess.java ( 추상메소드)
package com.control;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public interface CommandProcess {
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable;
}
WriteFormService.java
package member.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.control.CommandProcess;
public class WriteFormService implements CommandProcess{
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
return "/member/memberWriteForm.jsp";
}
}
//http://localhost:8080/memberMVC/member/writeForm.do
//요청한 URL에서 "/member/writeForm.do' 뜯어오기
이래야만 properties에서
#요청=클래스명
/member/writeForm.do=member.service.WriteFormService
이 작업을 할 수 있다.
요청한 내용 중에서 Servlet이 잘라내야 properties에서 똑같은 걸 찾아야 java 파일 가져올 수 있다.
request.getServletPath(); 이렇게 하면 프로젝트명 뒤에 있는 "/member/writeForm.do" 이것만 뜯어온다.
ControlServlet.java
package com.control;
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;
public class ControlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println();
if(request.getMethod().equals("POST"))
request.setCharacterEncoding("UTF-8");
//http://localhost:8080/memberMVC/member/writeForm.do
//요청한 URL에서 "/member/writeForm.do" 뜯어오기
String category = request.getServletPath();
System.out.println("category = " + category);
}
}
서버켜고 http://localhost:8080/memberMVC/member/writeForm.do 이거 찍으면
콘솔 창에 category가 찍힌다.
/member/writeForm.do 이걸 잘라내줘야 properties에서 같은거 가져온다.
command.properties는 한 번밖에 안 읽는다.회원가입하려고 command.properties를 가는데 다음 로그인하게 되면 command.properties 읽지 않는다.환경설정 파일이므로 command.properties 한 번밖에 안 읽으므로수시로 읽을 수 있도록 Map에 저장을 해놓는다.
Servlet이 부르는 건 Map에 있는 걸 부르는 것이다.
/member/writeForm.do 이렇게 요청하면 member.service.WriteFormService을 꺼내온다.
WriteFormService 얘의 부모가 CommandProcess 얘 이므로
CommandProcess com = map.get(category); CommandProcess 가 받아야한다.
부모는 자식한테 못가니까 캐스팅까지 하기
CommandProcess com = (CommandProcess)map.get(category);
받아온 jsp 파일로 마지막에 forward 시키기
//forward
RequestDispatcher dispatcher = request.getRequestDispatcher(view); //상대번지
dispatcher.forward(request, response); //제어권 넘기기
ControlServlet.java
package com.control;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ControlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Map<String, Object> map = new HashMap<String, Object>();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println();
if(request.getMethod().equals("POST"))
request.setCharacterEncoding("UTF-8");
//http://localhost:8080/memberMVC/member/writeForm.do
//요청한 URL에서 "/member/writeForm.do" 뜯어오기
String category = request.getServletPath();
System.out.println("category = " + category);
// Map을 이용하여 Key에 해당하는 값을 꺼내온다. member.service.WriteFormService
CommandProcess com = (CommandProcess)map.get(category); // 자식 = (자식)부모
String view = null;
try {
view = com.requestPro(request, response);
} catch (Throwable e) {
e.printStackTrace();
}
//forward
RequestDispatcher dispatcher = request.getRequestDispatcher(view); //상대번지
dispatcher.forward(request, response); //제어권 넘기기
}
}
command.properties가 있는 걸 servlet이 모르므로 web.xml에 등록해야한다.
파일 경로
\n \t가 있기 때문에 \를 쓰게되면 파일경로로 인식을 못한다.
c언어를 따라해서 java도 \\ 두번씩 써야한다.
\\ 이렇게 하는게 너무 복잡하므로 / 이렇게 쓴다.
<param-value>D:/Web/workspace/memberMVC/src/main/webapp/WEB-INF/command.properties</param-value>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>memberMVC</display-name>
<servlet>
<servlet-name>ControlServlet</servlet-name>
<servlet-class>com.control.ControlServlet</servlet-class>
<init-param>
<param-name>propertyConfig</param-name>
<param-value>D:/Web/workspace/memberMVC/src/main/webapp/WEB-INF/command.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ControlServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
</web-app>
command.properties를 한 번만 불러주기 위해서 ControlServlet.java init( )를 통해 한 번 부른다.
ControlServlet.java
@Override
public void init(ServletConfig config) throws ServletException {
String propertyConfig = config.getInitParameter("propertyConfig");
System.out.println("propertyConfig = " + propertyConfig);
}
서버끄고 http://localhost:8080/memberMVC/member/writeForm.do 다시 실행하면 콘솔창에 밑에처럼 뜬다
ControlServlet.java
package com.control;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
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;
public class ControlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Map<String, Object> map = new HashMap<String, Object>();
@Override
public void init(ServletConfig config) throws ServletException {
String propertyConfig = config.getInitParameter("propertyConfig");
System.out.println("propertyConfig = " + propertyConfig);
//command.properties의 파일의 내용을 읽어서 Map에 보관
FileInputStream fin = null;
Properties properties = new Properties();
try {
fin = new FileInputStream(propertyConfig);
properties.load(fin);
System.out.println("properties = "+properties);
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println();
Iterator<Object> it = properties.keySet().iterator();
while(it.hasNext()) {
String key = (String)it.next();
System.out.println("key = "+key);
String className = properties.getProperty(key);
System.out.println("className = "+className);
try {
Class<?> classType = Class.forName(className);
Object ob = classType.getConstructor().newInstance();
System.out.println("ob = "+ob);
map.put(key, ob);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
System.out.println();
}//while
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
execute(request, response);
}
protected void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println();
if(request.getMethod().equals("POST"))
request.setCharacterEncoding("UTF-8");
//http://localhost:8080/memberMVC/member/writeForm.do
//요청한 URL에서 "/member/writeForm.do" 뜯어오기
String category = request.getServletPath();
System.out.println("category = " + category);
// Map을 이용하여 Key에 해당하는 값을 꺼내온다. member.service.WriteFormService
CommandProcess com = (CommandProcess)map.get(category); // 자식 = (자식)부모
String view = null;
try {
view = com.requestPro(request, response);
} catch (Throwable e) {
e.printStackTrace();
}
//forward
RequestDispatcher dispatcher = request.getRequestDispatcher(view); //상대번지
dispatcher.forward(request, response); //제어권 넘기기
}
}
http://localhost:8080/memberMVC/member/LoginForm.do
command.properties
#요청=클래스명
/member/writeForm.do=member.service.WriteFormService
/member/loginForm.do=member.service.LoginFormService
LoginFormService.java
package member.service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.control.CommandProcess;
public class LoginFormService implements CommandProcess{
@Override
public String requestPro(HttpServletRequest request, HttpServletResponse response) throws Throwable {
return "/member/memberLoginForm.jsp";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>memberMVC</display-name>
<servlet>
<servlet-name>ControlServlet</servlet-name>
<servlet-class>com.control.ControlServlet</servlet-class>
<init-param>
<param-name>propertyConfig</param-name>
<param-value>D:/Web/workspace/memberMVC/src/main/webapp/WEB-INF/command.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ControlServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
<welcome-file>default.htm</welcome-file>
</welcome-file-list>
</web-app>
여기 서블릿 부분을 어노테이션으로 바꾸기
<!--
<servlet>
<servlet-name>ControlServlet</servlet-name>
<servlet-class>com.control.ControlServlet</servlet-class>
<init-param>
<param-name>propertyConfig</param-name>
<param-value>D:/Web/workspace/memberMVC/src/main/webapp/WEB-INF/command.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ControlServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
-->
이 부분 주석걸기
ControlServlet.java
@WebServlet(
urlPatterns = {"*.do"},
initParams = {
@WebInitParam(name="propertyConfig", value = "command.properties")
}
)
public class ControlServlet extends HttpServlet {
command.properties의 위치를 모르므로
밑에서 물어보는 것이다. WEB-INF의 위치를 가져오기
@Override
public void init(ServletConfig config) throws ServletException {
String propertyConfig = config.getInitParameter("propertyConfig");
System.out.println("propertyConfig = " + propertyConfig);
//@WebServlet로 서블릿을 등록했을 때
String realFolder = config.getServletContext().getRealPath("/WEB-INF");
String realPath = realFolder + "/" + propertyConfig;
System.out.println("realPath = " + realPath);
ControlServlet.java
@WebServlet(
urlPatterns = {"*.do"},
initParams = {
@WebInitParam(name="propertyConfig", value = "command.properties")
}
)
public class ControlServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private Map<String, Object> map = new HashMap<String, Object>();
@Override
public void init(ServletConfig config) throws ServletException {
String propertyConfig = config.getInitParameter("propertyConfig");
System.out.println("propertyConfig = " + propertyConfig);
//@WebServlet로 서블릿을 등록했을 때
String realFolder = config.getServletContext().getRealPath("/WEB-INF");
String realPath = realFolder + "/" + propertyConfig;
System.out.println("realPath = " + realPath);
//---------------------------------------
//command.properties의 파일의 내용을 읽어서 Map에 보관
FileInputStream fin = null;
Properties properties = new Properties();
try {
//web.xml를 사용했을 때
//fin = new FileInputStream(propertyConfig);
//@WebServlet을 사용했을 때
fin = new FileInputStream(realPath);
properties.load(fin);
System.out.println("properties = "+properties);
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println();
'JSP & Servlet' 카테고리의 다른 글
DAY 52 - MVC ( 2024.09.13 ) (0) | 2024.09.13 |
---|---|
DAY 51 - EL_JSTL ( 2024.09.12 ) (0) | 2024.09.12 |
DAY 50 - EL_JSTL ( 2024.09.11 ) (4) | 2024.09.11 |
DAY 49 - MyBatis (2024.09.10) (0) | 2024.09.10 |
DAY 48 - MyBatis ( 2024.09.09) (0) | 2024.09.09 |