23.05.03

이준영·2023년 5월 2일
0
post-custom-banner

응용 - 구구단

gugudan.do

package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

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 GugudanServlet
 */
@WebServlet("/gugudan.do")
public class GugudanServlet 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) {
		// html 출력 생성
		
		try {
			request.setCharacterEncoding("utf-8");
			
			response.setContentType("text/html; charset=utf-8");
			
			StringBuilder sbHtml = new StringBuilder();
			
			
			sbHtml.append("<!doctype html>");
			sbHtml.append("<html>");
			sbHtml.append("<head>");
			sbHtml.append("<meta charset='utf-8'>");
			sbHtml.append("</head>");
			sbHtml.append("<body>");
			sbHtml.append("<form action='gugudan_ok.do' method='post' >");
			sbHtml.append("시작단 : " + "<input type='text' name='sDan' />");
			sbHtml.append("끝단 : " + "<input type='text' name='eDan' />");
			sbHtml.append("<input type='submit' value='구구단 전송'>");
			sbHtml.append("</form>");
			sbHtml.append("</body>");
			sbHtml.append("</html>");
			

			PrintWriter out = response.getWriter();

			
			out.println(sbHtml);
			out.close();
			
		} catch (UnsupportedEncodingException e) {
			System.out.println("[에러] : " + e.getMessage());
		} catch (IOException e) {
			System.out.println("[에러] : " + e.getMessage());
		}
	}

}



gugudan_do.ok

package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

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 GugudanOkServlet
 */
@WebServlet("/gugudan_ok.do")
public class GugudanOkServlet 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 {
		try {
			request.setCharacterEncoding("utf-8");
			
			response.setContentType("text/html; charset=utf-8");
			
			PrintWriter out = response.getWriter();
			
			String sDan = request.getParameter("sDan");
			String eDan = request.getParameter("eDan");
			
		int isDan = Integer.parseInt(sDan);
		int ieDan = Integer.parseInt(eDan);
			
			StringBuilder sbHtml = new StringBuilder();
			
			sbHtml.append("<!doctype html>");
			sbHtml.append("<html>");
			sbHtml.append("<head>");
			sbHtml.append("<meta charset='utf-8'>");
			sbHtml.append("</head>");
			sbHtml.append("<body>");
			sbHtml.append("<table>");
			for(int i = isDan; i <=ieDan; i++) {
				sbHtml.append("<tr>");
				for(int j =  1; j <=9; j++) {
					sbHtml.append("<td>" + i + " X " + j + " = " + (i * j)  + "</td>");
				}
				sbHtml.append("</tr>");
			}
			sbHtml.append("</table>");
			sbHtml.append("</body>");
			sbHtml.append("</html>");
			
			out.println(sbHtml);
			out.close();
			
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}



import시 나타나는 오류

프로젝트 파일에서 복사를 하고 이클립스에서 import하고 실행을 하면 오류가 나온다.(이클립스에서 복사해도 똑같음)


서버에서 클릭하고 모듈로 들어가면 이 화면이 나오는데,
이 경우 path가 같기 때문에 충돌하여 발생하는 오류인데, 패스를 수정해주면 된다!



또한 import하고 실행하기 전에 프로젝트 우클릭 -> properties -> web project settings 에 가서 root를 바꿔줘도 된다.




콜백 메서드와 서블릿 객체 생명주기

콜백 메서드 : 어떤 객체에서 어떤 상황이 발생하면 시스템이 자동으로 호출하여 실행되는 메서드

초기화 / 종료는 각각 한번이고, 서비스는 객체가 있는한 계속 사용 가능하다.


init은 최초 한번 실행되고, 그 이후 service만 호출되는 것을 볼 수 있음

init으로 초기 데이터를 지정하여 출력하기

id, password 변수를 각각 생성하고 init 메서드에서 초기화값을 가져오는 메서드를 사용한다. (getInitParameter)

web.xml에서 init-param을 추가하여 그 안에 param-name / param-value 써서 아이디와 비밀번호의 값을 지정한다. ( 이렇게 지정한 값을 init의 getInitParameter 통하여 가져와 줌 )

실행



load-on-startup

톰캣 시작되기 전에 init 실행시켜 주는 것( 실행 순서가 있어서 순서대로 실행된다)

web.xml에서 설정 가능하다.



필터

클라이언트로부터 서블릿이 요청되어 수행될 때 필터링 기능을 제공하기 위한 기술

서블릿(, jsp)이 수행되기 전이나 후에 추가 가능 수행 가능

필터 기능 활용하여 처리하는 기능 중 대표적인 것이 로그기록과 한글처리이다.
여기서 한글처리는 하나의 필터를 만들어 놓고 여러 개의 서블릿에서 사용하도록 하면 편하다.

필터 구현(인터페이스 통해) -> web.xml에 필터 태그 등록 -> 필터 매핑 태그 등록

필터 구현

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterEx01 implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("FilterEx01 init() 호출");
	}
	
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		//전처리 구간
		System.out.println("전처리");
		chain.doFilter(request, response);
		//후처리 구간
		System.out.println("후처리");
		
	}

}

web.xml에 태그 등록

.jsp 파일 하나 생성

실행

필터를 하나 더 생성(filterex02) 후 실행


순서 잘 보기



필터로 한글 처리

form.jsp / form_ok.jsp 만들어서 get / post 방식으로 전송하는 것 생성

한글 처리 필터로 만들기 위해 필터 하나 구현

package filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class EncodingFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 전처리 부분, 인코딩 정해져있지 않으면 utf-8로 설정해라
		if(request.getCharacterEncoding() == null) {
			request.setCharacterEncoding("utf-8");
		}
		chain.doFilter(request, response);
		
		
	}

}


실행 시 필터로 인하여 다국어 처리가 되었기 때문에 post방식도 한글이 잘 나온다.


filter 직접 생성

이클립스에서는 filter도 직접 제공해준다.

servlet과 비슷한 구성이다. 매핑만 설정해주고 finish



위에 어노테이션으로 뜨고 아까와 똑같이 코드 써준다.



xml filter 태그를 주석하고 실행해도 결과는 똑같이 나온다(어노테이션으로 해줬기 때문)




Front Controller 요청 방식

(하나의 서블릿 기준)

1.parameter : 서블릿이름?키=값1 /서블릿이름?키=값2 서로 다른 jsp

ex> controller?action=view1 => view1.jsp
	controller?action=view2 => view2.jsp
    
    controller?action=view1 => View1Action => view1.jsp
	controller?action=view2 => View2Action => view2.jsp

응용

controller

package controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

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 ControllerEx1
 */
@WebServlet("/controller")
public class ControllerEx1 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 {
		// TODO Auto-generated method stub
		this.doProcess(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doProcess(request, response);
	}
	
	protected void doProcess(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		try {
			request.setCharacterEncoding("utf-8");
			
			String action = request.getParameter("action");
			
			//페이지 설정 소스 코드들
			String url = "/error.jsp";
			if(action == null || action.equals("") || action.equals("view1")) {
				url = "/view1.jsp";
			}
			else if ( action.equals("view2")) {
				url = "/view2.jsp";

			}
			
			//페이지 보여주는 코드들
			RequestDispatcher dispatcher = request.getRequestDispatcher(url);
			dispatcher.forward(request, response);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServletException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

view1 / 2 .jsp 만들기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Hello view1.jsp;
</body>
</html>

----

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Hello view2.jsp;
</body>
</html>

실행하면 뷰1이 나오는데, 뒤에 액션값이 없어서 그런 것이고 액션값을 넣어주면 해당 값에 따른 브라우저가 나온다.

view1 / view2를 WEB-INF 안에 폴더 생성하여 안에 넣어주면 경로를 변경해줘야 한다.

//페이지 설정 소스 코드들
			String url = "/WEB-INF/views/error.jsp";   <--- WEB-INF 폴더에 있으므로
			if(action == null || action.equals("") || action.equals("view1")) {
				url = "/WEB-INF/views/view1.jsp";
			}
			else if ( action.equals("view2")) {
				url = "/WEB-INF/views/view2.jsp";

			}

위 코드에 form / form_ok 넣어줘서 컨트롤러 통하여 데이터 전송

밑에 form 브라우저 호출 코드 추가

else if (action.equals("form")) {
				url = "/WEB-INF/views/form.jsp";
			}
			else if (action.equals("form_ok")) {
				url = "/WEB-INF/views/form_ok.jsp";
			}

form을 만드는데 form에서 전송을 하려면 따로 hidden이 필요하다. ( controller?action=form_ok 로 보내주기 위해서, 그냥 action에다가 다 쓰면 해당 주소로 전송이 안된다.)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="controller" method="get">
<input type="hidden" name="action" value="form_ok" />
 data : <input type="text" name="data" />
 <input type="submit" value="get 전송" />
</form>

<form action="controller" method="post">
<input type="hidden" name="action" value="form_ok" />
 data : <input type="text" name="data" />
 <input type="submit" value="post 전송" />
</form>
</body>
</html>

form_ok

Hello form_ok.jsp;<br><br>
<%
	String data = request.getParameter("data");
	out.println("data : " + data);
%>

get / post 보내진 모습



mvc 구조

    controller?action=view1 => View1Action => view1.jsp
	controller?action=view2 => View2Action => view2.jsp

View1Action / View2Action 클래스 생성
( 이때 매개변수는 HttpServletRequest와 HttpServletResponse 받기)

controller에서 url 선언 전에 모델 호출

if(action == null || action.equals("") || action.equals("view1")) {
				// model 호출
				View1Action model = new View1Action();
				model.execute(request, response);
				
				url = "/WEB-INF/views/view1.jsp";
			}
            
            view2도 똑같이 해주기

실행하면 view1일때 액션이 먼저 호출되고 view2 실행하면 먼저 액션이 호출된다.


tip : action에서 메서드를 편리하게 사용하기 위하여 미리 인터페이스를 해둬서 그때그때 재정의 하는 게 좋다. (다형성을 통하여 바꾸기!)

ViewAction 인터페이스 생성


View1Action / View2Action 재정의 (직접 쓰는 것보다 간편하다)


controller 다형성 통하여 써주기




2.URL(1보다 많이 씀) : 값1.do / 값2.do 서로 다른 jsp

view1.do -> view1.jsp
view2.do -> view2.jsp



model2로 우편번호 검색기 만들기

실행 순서
zipcode.jsp -> zipcodecontroller -> zipcodeOkAction -> to, dao 처리 연동 -> 받아서 zipcode_ok.jsp로 넘김 -> zipcode_ok.jsp에서 받아서 html 형식으로 보여준다.

zipcode.jsp

검색 형식 만들어 준다.

<form action="controller" method="post" >
	<input type="hidden" name="action" value="zipcode_ok" />
	동이름 <input type="text" name="dong" />
	<input type="submit" value="전송" />
</form>


ZipcodeController

doProcess부분만 따옴 -> 요청받은 브라우저를 받아서 화면에 보여줄 수 있도록 코드 작업
( @WebServlet("/controller") )

protected void doProcess(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		try {
			request.setCharacterEncoding("utf-8");
			
			String action = request.getParameter("action");
				
			String url = "/WEB-INF/zipcode/error.jsp";
			
			Action model =  null;

			if(action == null || action.equals("") || action.equals("zipcode")) {
				model = new ZipcodeAction();
				
				model.execute(request, response);
				
				url = "/WEB-INF/zipcode/zipcode.jsp";
			}
			else if(action.equals("zipcode_ok")) {
				model = new ZipcodeOkAction();
				
				model.execute(request, response);
				
				url = "/WEB-INF/zipcode/zipcode_ok.jsp";
			}
			
			RequestDispatcher dispatcher = request.getRequestDispatcher(url);
			dispatcher.forward(request, response);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ServletException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

ZipcodeOkAction

zipcode.jsp에서 전송을 누르면 controller에 따라서 zipcode_ok로 넘어가고, 넘어가기 전에 ZipcodeoOkAction가 호출된다. 이 곳에서 to, dao를 연동하고 arraylist에 넣은 값을 리턴받아서
request.setAttribute로 zipcode_ok.jsp로 넘긴다.

package model2;

import java.util.ArrayList;

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

import model1.ZipcodeDAO;
import model1.ZipcodeTO;

public class ZipcodeOkAction implements Action {
	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		System.out.println("zipcodeOkAction 호출");
		
		String strDong = request.getParameter("dong");
		System.out.println(strDong);
		
		// to , dao 처리
		ZipcodeDAO dao = new ZipcodeDAO();
		ArrayList<ZipcodeTO> datas = dao.listZipcode(strDong);
		
		//System.out.println("개수 : " + datas.size());
		
		request.setAttribute("datas", datas);
	}
}

zipcode_ok.jsp

request.setAttribute 넘긴 것을 request.getAttribute로 받아서 html 기능에 맞게 화면에 보여준다!

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

	StringBuilder sbHtml = new StringBuilder();
	
	sbHtml.append("<table width='800' border='1'>");
	for(ZipcodeTO to : datas) {
		sbHtml.append("<tr>");
		sbHtml.append("		<td>" + to.getZipcode() + "</td>");
		sbHtml.append("		<td>" + to.getSido() + "</td>");
		sbHtml.append("		<td>" + to.getGugun() + "</td>");
		sbHtml.append("		<td>" + to.getDong() + "</td>");
		sbHtml.append("		<td>" + to.getRi() + "</td>");
		sbHtml.append("		<td>" + to.getBunji() + "</td>");
		sbHtml.append("</tr>");
	}
	sbHtml.append("</table>");

	out.println(sbHtml);
%>



게시판 mode1 -> model2 구조로 만들기

controller만들기 -> (만들기 전 BoardAction 인터페이스를 통해 각 action 만들기 총 8개)
-> 각 보드 액션들 요소에 dao를 넣기

board_list1 작업

model1은 board_list1.jsp에 dao를 넣었었다.
-> model2에서는 ListAction에 dao를 넣고 request.setAttribute으로 넘겨서 request.getAttribute 받는 것

실행 후 데이터 이미지가 깨지는데, 이는 model1과 model2가 경로가 달라서 그런 것이다.
ctrl + f 누르고 ../../를 ./로 모두 replaceAll 해주면 된다.

(이 경로는 똑같은 게 아님! 다른 것도 이렇게 똑같이 하면 안되고 경로를 보고 바꿔줘야 한다.)

그 후 jsp 경로들 다 controller 경로로 바꿔줘야 한다!! 보이는 거 전부 바꿔줘야 함!


이런식으로

board_write1 작업

write에서도 ctrl + f 누르고 ./로 교체해주고 jsp경로 찾아서 controller로 바꿔준다!

board_write1_ok 작업

마찬가지로 경로 바꿔주고, to, dao를 전부 writeokaction 으로 옮긴다(flag 까지)
이후 flag를 넘겨주고 flag를 받아서 처리한다.

WriteOkAction

package model2;

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

import model1.BoardDAO;
import model1.BoardTO;


public class WriteOkAction implements BoardAction {
	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		System.out.println("WriteAction 호출");

		BoardTO to = new BoardTO();
		to.setSubject(request.getParameter("subject"));
		to.setWriter(request.getParameter("writer"));

		to.setMail("");
		if (!request.getParameter("mail1").equals("") && !request.getParameter("mail2").equals("")) {
			to.setMail(request.getParameter("mail1") + "@" + request.getParameter("mail2"));
		}

		to.setPassword(request.getParameter("password"));
		to.setContent(request.getParameter("content"));
		to.setWip(request.getRemoteAddr());

		BoardDAO dao = new BoardDAO();
		
		int flag = dao.boardWriteOk(to);
		
		request.setAttribute("flag", flag); //autobox 된 것 (int -> 오브젝트인 integer)
	}
}

board_write1_ok.jsp

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

<%
	request.setCharacterEncoding("utf-8");
	
	int flag = (Integer)request.getAttribute("flag");
	
	out.println("<script type='text/javascript'>");
	if(flag == 0) {
		out.println("alert('글 쓰기 성공');");
		out.println("location.href='./controller?path=list'");
	} else {
		out.println("alert('글 쓰기 실패');");
		out.println("history.back();");
	}
	out.println("</script>");
%>

view 작업

view부터는 seq에 따라서 화면이 보여서 write나 list같이 action만 주는 것이 아니라 seq도 줘서 같이 넘겨줘야한다.

따라서 list에서 view로 이동하는 부분에서 action + seq를 넘겨준다!

후에 서브컨트롤러에서 BoardTO 넘겨서 board_view.jsp 에서 받으면 끝

		sbHtml.append("<a href='./controller?path=list + &seq=" + seq + "'>" + subject + "</a>");

delete / modify 작업

view와 마찬가지로 링크부분은 seq추가, BoardTO 넘겨서 받으면 끝 (form action 부분에서 확인해서 링크 잘 적어주기)

delete_ok / modify_ok 작업

write_ok와 마찬가지로 flag까지 넘겨서 flag를 받아주면 된다.
다른 점 modify_ok는 뷰로 돌아가기 때문에 seq가 필요하여 변수를 남겨둬야 하는데 to.setSeq를 사용하기 때문에 BoardTO가 필요하다.

profile
끄적끄적
post-custom-banner

0개의 댓글