매일 조금씩

01/06 - JSP(11) : eclipse로 서블릿클래스 만들기(annotation사용) => controller만들어서 Model2게시판 만들기(파라메터 방식) 본문

빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정

01/06 - JSP(11) : eclipse로 서블릿클래스 만들기(annotation사용) => controller만들어서 Model2게시판 만들기(파라메터 방식)

mezo 2021. 1. 16. 22:11
728x90
반응형

Java -> Web Program

              class -> Servlet(Java - html)

              Jsp (Java Server Page <- ASP : Active Server Page) (html - Java)

                        hard coding

                        model1

 

              => MVC model2

 

Servlet의 개념

1. HttpServlet 클래스 상속받아야함

        init

        destroy

        service

               doPost

               doGet

               => doProcess

2. web.xml (eclipse)   =>  annotation

        패키지.클래스명

        url - 맵핑

 

http://localhost:8081\localhost 까지 쳤을 때

url까지만 쳤을 때 찾는 순서 <welcom-file-list>이다.

 

 

servlet 만드는 개념

url       1:1 클래스   잘안씀            ex) <url-pattern>/servlet01</url-pattern>

url       여러개:1   클래스   많이씀   ex) <url-pattern>/servlet01/*</url-pattern>

<url-pattern>/servlet01/*</url-pattern>    : 디렉토리명
<url-pattern>*.do</url-pattern>  :  파일명

 

 

 

annotation

어제 했던 건 직접 web.xml을 조작하여 서블릿 클래스를 등록하여 사용할 수 있게 하는 것이였다면

annotation은 이 귀찮은 것을 보완한 방법이다.

1. annotation 사용

ServletEx02

web.xml에 쓰지 않고 @Override 와 같은 annotation을 써서 이게 servlet이다! 하고 표시해 주는게 있다.

클래스 위에 자동완성을 사용해서 다음과 같이 써준다. 그럼 위쪽에 import가 생긴다.

import javax.servlet.annotation.WebServlet;

@WebServlet(urlPatterns = {"/serlvet02"} )

web.xml에 쓰는 것보다 훨씬 편하다.

 

이 annotation 을  eclipse에선 자동화 시켜놨다. 

class만들때 new > class > servlet 으로 만들면 된다. 

 

주의할점!

서블릿은 url하나에 여러개의 servlet은 괜찮지만 servlet 여러개에 하나의 url은 안된다. 

즉, url은 겹치면 안된다. 

 

 

2. annotation으로 초기값 설정

annotation으로 값의 초기값을 설정할 수도 있다.

@WebServlet(
      urlPatterns = {"/serlvet04"},
      initParams = {
              @WebInitParam(name = "id", value="tester"),
              @WebInitParam(name = "password", value="123456")
      })

이렇게 한 후에 아래처럼 init()메서드를 사용해서 실행시 처음 한번 값을 가져올 수 있다.

private String id;
private String password;

@Override
public void init() throws ServletException {
    id = getInitParameter("id");
    id = getInitParameter("password");
}

 

이것 역시 eclipse에서 자동화 되어 있다.

serlvet05를 /serlvet05로 edit해야 함

 

 

ServletEx03

서블릿은 한번 '요청'이 들어오면 실행이 된다.

근데 '톰캣 실행과 동시'에 실행시키고 싶으면

loadOnStartup을 사용한다. 

만약 ,

ServletEx01.java

@WebServlet(urlPatterns = "/ServletEx01", loadOnStartup = 1)

ServletEx02.java

@WebServlet(urlPatterns = "/ServletEx02", loadOnStartup = 2)

하고 ServletEx02.java를 실행시키면

 

만약,

ServletEx01.java

@WebServlet(urlPatterns = "/ServletEx01", loadOnStartup = 2)

ServletEx02.java

@WebServlet(urlPatterns = "/ServletEx02", loadOnStartup = 1)

하고 ServletEx02.java를 실행시키면

 


 

 

 

 

 

 

 

 

 

 

MVC  model 2


1. MVC 패턴

▷P518 [그림18.3] MVC 패턴의 구조 

모든 요청은 Servlet이다. JSP로 부르면 안된다. 

 

 

2. model2 구조를 이용한 MVC 패턴 구현

컨트롤러 처리방식 : 하나의 서블릿에서 처리

요청을 받는 방법이 두가지이다.

1) 파라메터

     ex)    /controller?action=view1

                    view1에 해당하는 내용처리

                    view1.jsp

              /controller?action=view2

                    view2에 해당하는 내용처리

                    view2.jsp

2) url

     ex)   view1.do

                    view1에 해당하는 내용처리

               view2.do

                    view2에 해당하는 내용처리

 

 

 

[ 파라메터 방식 ]

ControllerEx01

실습1) model, view, controller 만들기

ControllerEx01.java

view1.jsp

view2.jsp

 

(1) controller로 jsp파일 집어 오기

주소창에 ?action= 를 어떻게 적느냐에 따라 바뀌게 파라미터에 따라 호출되는 jsp파일이 다르도록 구현

 

컨트롤러를 통해서 원하는 jsp를 집어 오는거 그게바로 model2이다!

 

url을 String으로 정의해서 jsp파일명을 넣어주고 RequestDispatcher를 사용한다. 

MVC model2의 핵심이다.

// jsp:forward 어떤걸 요청할때 url의 내용을 옮겨다 붙여 주는거 
RequestDispatcher dispatcher = request.getRequestDispatcher(url);
dispatcher.forward(request, response);

 

 

(2) jsp 파일 직접 실행 안되게 하기

jsp페이지를 직접 실행시킬수 있기 때문에 헷갈릴 수 있다.

그래서 직접 실행할수 없게 할거다.

이렇게 WEB-INF안에 views폴더 만들어서 그 안에 jsp파일들을 전부 넣어 버리면 직접 실행이 불가능하다.

(WEB-INF는 일종의 보안된 영역이기 때문에 직접 실행이 불가능)

무조건 Controller를 통해서 실행해야한다. url은 '/WEB-INF/view/jsp파일' 이된다.

String url = "";
if(action == null || action.equals("") || action.equals("view1")) {
    System.out.println("view1 호출");
    url = "/WEB-INF/views/view1.jsp";
}else if(action.equals("view2")) {
    System.out.println("view2 호출");
    url = "/WEB-INF/views/view2.jsp";
}

 

 

(3) model 만들어서 연결

if문 수정

String url = "";
if(action == null || action.equals("") || action.equals("view1")) {
    System.out.println("view1 호출");

    // 모델 생성, 호출
    View1Model model = new View1Model();
    model.execute();

    // url정의 
    url = "/WEB-INF/views/view1.jsp";
}else if(action.equals("view2")) {
    System.out.println("view2 호출");

    View2Model model = new View2Model();
    model.execute();

    url = "/WEB-INF/views/view2.jsp";
}

View1Model.java

package model1;

public class View1Model{
	public void execute() {
		System.out.println("View1Model");
	}
}

View2Model.java

package model1;

public class View2Model{
	public void execute() {
		System.out.println("View2Model");
	}
}

 

 

(4) Servlet의 데이터를 model로 넘기기

먼저 model의 execute메서드를 request와 response를 포함하도록 다음과 같이 바꿔준다. 

View1Model.java

public void execute(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("View1Model execute");
}

View2Model.java

public void execute(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("View2Model execute");
}

위와 같이 메서드를 추가한 후, ControllerEx01.java 의 if문에서 다음과 같이 execute를 수정한다.

 

if(action == null || action.equals("") || action.equals("view1")) {
    System.out.println("view1 호출");

    // 모델 생성, 호출
    View1Model model = new View1Model();
    model.execute(request, response);

    // url정의 
    url = "/WEB-INF/views/view1.jsp";
}else if(action.equals("view2")) {
    System.out.println("view2 호출");

    View2Model model = new View2Model();
    model.execute(request, response);

    url = "/WEB-INF/views/view2.jsp";
}

 

(5) model 인터페이스 만들기

인터페이스로 ViewModel.java를 아래와 같이 만든다. (인터페이스는 구현말고 선언만 해야함)

package model1;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface ViewModel {
	public void execute(HttpServletRequest request, HttpServletResponse response);
}

 

그리고 View1Model.java와 View2Model.java에 다음과 같이 execute메서드에 @Override를 붙여준다. 

@Override
public void execute(HttpServletRequest request, HttpServletResponse response) {
    System.out.println("View1Model");
}

 

   

 

실습2) mode1 주소검색을 model2로 바꾸기 (Servlet으로 Controller만들어서 annotation으로 적용)

ZipcodeModelEx01

 

(1) /WEB-INF/views에 jsp 파일 넣기

zipcode.jsp와 zipcode_ok.jsp를 /WEB-INF/views에 넣어준다.

 

 

(2)Controller 만들기

servlet파일로 ControllerEx01.java를 만든다.

package servlet;

import java.io.IOException;

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;

/**
 * Servlet implementation class ControllerEx01
 */
@WebServlet("/controller")
public class ControllerEx01 extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doProcess(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doProcess(request, response);
	}
	
	protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		
		String action = request.getParameter("action");
		
		String url = "";
		if(action == null || action.equals("") || action.equals("zipcode")) {
			url = "/WEB-INF/views/zipcode.jsp";
		}else if(action.equals("zipcode_ok")) {
			url = "/WEB-INF/views/zipcode_ok.jsp";
		}
		
		RequestDispatcher dispatcher = request.getRequestDispatcher(url);
		dispatcher.forward(request, response);
	}

}

 

(3) view가 Controller로 값을 보내도록 view 코드를 수정하기 

여기서 view는 zipcode.jsp이므로 

zipcode.jsp에서 form의 action주소를 수정하고,

<form action="./controller" method="post" name="frm">

 

아래와 같이 form 태그 밑에 input태그를 추가한다.

<form action="./controller" method="post" name="frm">
<input type="hidden" name="action" value="zipcode_ok" />

 

 

(4) view에서 model을 부르게 되어 있는걸 controller에서 model을 부르도록 수정한다.

DAO로 부르는데 DAO로 바로 안부르고 controller와 DAO사이에 연결고리를 하나 만들어야한다.

model2패키지하나 만들어서 ActionModel.java로 인터페이스를 만든다.

package model2;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface ActionModel {
	public void execute(HttpServletRequest request, HttpServletResponse response);
}

jsp페이지와 비슷한 action페이지를 jsp페이지별로 만들고 그 action 페이지에서 DAO를 부른다.

 

 

(5) controller에서 action페이지 호출하는 코드 추가

ControllerEx01.java

protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("utf-8");

    String action = request.getParameter("action");

    String url = "";

    ActionModel model = null;
    if(action == null || action.equals("") || action.equals("zipcode")) {
        // 특별한 일이 없음
        model = new ZipcodeAction();
        model.execute(request, response);

        url = "/WEB-INF/views/zipcode.jsp";
    }else if(action.equals("zipcode_ok")) {
        // 데이터베이스 선택
        model = new ZipcodeOkAction();
        model.execute(request, response);

        url = "/WEB-INF/views/zipcode_ok.jsp";
    }

    RequestDispatcher dispatcher = request.getRequestDispatcher(url);
    dispatcher.forward(request, response);
}

 

 

(6) jsp파일의 DAO 호출 부분을 action 페이지에 넣기

ZipcodeOkAction.java

package model2;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model1.ZipcodeDAO;
import model1.ZipcodeTO;

public class ZipcodeOkAction implements ActionModel {

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		
		try {
			request.setCharacterEncoding( "utf-8" );
			
			String strDong = request.getParameter("dong");

			ZipcodeDAO dao = new ZipcodeDAO();
			ArrayList<ZipcodeTO> lists = dao.searchLists( strDong );
			
			System.out.println(lists.size());
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
				
	}

}

이렇게 하고 ControllerEx01.java실행시키면 주소 갯수가 콘솔창에 출력된다.

 

 

요청을 받으면 서블릿이 jsp를 보여주는데 그때 데이터가 필요하면 dao로 데이터에 접근한다.

그때 jsp와 1:1인 어댑터를 하나 만들어서 그걸 사용해서 서블릿이 dao에 접근하고 그 dao가 데이터게 접근한다.

가져온 데이터는 어댑터를 통해서 jsp로 전달 되고 그 jsp는 서블릿을 통해 보여진다.

 

 

(7) 가져온 데이터를 jsp에 보내기 

request.setAttribute를 사용한다.

ZipcodeOkAction.java 에 아래 코드를 추가하면 

request.setAttribute("lists",lists);

전체코드는 아래와 같다.

package model2;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import model1.ZipcodeDAO;
import model1.ZipcodeTO;

public class ZipcodeOkAction implements ActionModel {

	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		
		try {
			request.setCharacterEncoding( "utf-8" );
			
			String strDong = request.getParameter("dong");

			ZipcodeDAO dao = new ZipcodeDAO();
			ArrayList<ZipcodeTO> lists = dao.searchLists( strDong );
			
			//System.out.println(lists.size());
			request.setAttribute("lists",lists);
		
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
				
	}

}

 

zipcode_ok.jsp에서 dao 부분을 지우고

dao에 접근해서 결과를 담아오는데에 쓰였던 lists 변수를 request.getAttribute로 수정한다.

ArrayList<ZipcodeTO> lists = (ArrayList)request.getAttribute("lists");

전체 zipcode_ok.jsp는 다음과 같다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>

<%@ page import="model1.ZipcodeTO"%>
<%@ page import="java.util.ArrayList"%>


<%
	StringBuffer html = new StringBuffer();	
	ArrayList<ZipcodeTO> lists = (ArrayList)request.getAttribute("lists");
			
	html.append( "<table width='600' border='1'>" );
	for(ZipcodeTO to : lists) {
		html.append( "<tr>" );
		html.append( "	<td>" + to.getZipcode() + "</td>" );
		html.append( "	<td>" + to.getSido() + "</td>" );
		html.append( "	<td>" + to.getGugun() + "</td>" );
		html.append( "	<td>" + to.getDong() + "</td>" );
		html.append( "	<td>" + to.getRi() + "</td>" );
		html.append( "	<td>" + to.getBunji() + "</td>" );
		html.append( "</tr>" );
	}
	html.append( "</table>" );
	
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<%= html %>

</body>
</html>

 

 

다음은 수정전, dao로 구현되어 있던 zipcode_ok.jsp의 전체 코드이다.

위에서 db에 접근하는 역할을 했던 dao가 action페이지에서 구현되도록 바뀌었는데

그렇게 바뀌기 전의 코드이다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import="model1.ZipcodeTO" %>
<%@ page import="model1.ZipcodeDAO" %>
<%@ page import="java.util.ArrayList" %>


<%
	request.setCharacterEncoding( "utf-8" );
	
	String strDong = request.getParameter("dong");

	StringBuffer html = new StringBuffer();	
	if( strDong != null ) {
		ZipcodeDAO dao = new ZipcodeDAO();
		ArrayList<ZipcodeTO> lists = dao.searchLists( strDong );
			
		html.append( "<table width='600' border='1'>" );
		for(ZipcodeTO to : lists) {
			html.append( "<tr>" );
			html.append( "	<td>" + to.getZipcode() + "</td>" );
			html.append( "	<td>" + to.getSido() + "</td>" );
			html.append( "	<td>" + to.getGugun() + "</td>" );
			html.append( "	<td>" + to.getDong() + "</td>" );
			html.append( "	<td>" + to.getRi() + "</td>" );
			html.append( "	<td>" + to.getBunji() + "</td>" );
			html.append( "</tr>" );
		}
		html.append( "</table>" );
	}
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<%= html %>

</body>
</html>

 

 

 

 

 

 

 

실습3) model1 으로 만들어진 게시판을 model2로 만들기

 

Model2Ex01

 

controller?action=

                            BoardAction

                                       execute

                                                    DAO

         list

                            ListAction

                            board_list1.jsp

         view

                            ViewAction

                            board_view1.jsp

         write

                            WriteAction

                            board_write1.jsp

         write_ok

                            WriteOkAction

                            board_write1_ok.jsp

         modify

                            ModifyAction

                            board_modify1.jsp

         modify_ok

                            ModifyOkAction

                            board_modify1_ok.jsp

         delete

                            DeleteAction

                            board_delete1.jsp

         delete_ok

                            DeleteOkAction

                            board_delete1_ok.jsp

 

 

(1) /WEB-INF/views 에 jsp 파일 넣기

Java Resources에 model2, servlet패키지 만들기

 

(2) 어댑터 인터페이스 BoardAction 만들기

 

(3) jsp파일 별 어댑터 action 파일 만들기

 

(4) controller만들기

if ~ else if 문으로 request.getParameter("action") 값에 따라 각각의 jsp페이지로 url을 정의한다.

마지막 else에선 경로가 잘못표시 됐을때 처리하고자 하는 것을 넣는다.

 

그리고 실행시키면 나오긴 나오는데 페이지들이 디자인이 깨져보인다.

 

(5) jsp 파일에서 경로 수정 해주기(action, input ..)

모든 controller의 경로는 항상 './controlloer' 가 되며 css와 image 폴더의 경로또한 './css' , './image' 가 된다.

이때 action값을 전달하기 위한 input 태그를 추가해야한다.

board_write1.jsp 의 경우 아래와 같이 form을 수정,  input을 추가한다.

<form action="./controller" method="post" name="wfrm">
	<input type="hidden" name="action" value="write_ok" />

model1의 경우엔 form의 action이 ok.jsp의 경로였겠지만 model2에선 controller를 거쳐야하므로 controller의 경로가 된다. 

 

(6) ok.jsp 페이지에서 dao호출하는 부분을 action페이지에 넘긴다.

action페이지에서 넘겨받은 코드는 실행결과를 flag변수에 담에서 ok.jsp에 넘겨야 하므로..

action페이지에 dao호출부분을 붙여넣은 다음 마지막줄에 

request.setAttribute("flag", flag);

위 코드를 추가한다. 

 

ok.jsp에서 dao를 호출해서 썻던 자리는 실행결과인 flag값을 넘겨받기 위해 다음 코드를 넣는다.

int flag = (Integer)request.getAttribute("flag");

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형