KOSTA 38일차) DispatcherServlet / 다운로드 / handler

해버니·2023년 4월 11일
0

KOSTA

목록 보기
31/32
post-thumbnail

DispatcherServlet


지금까지는 각 패키지마다 controller를 만들어줘서 servlet을 만들어줬는데 오늘은 하나의 파일에서 관리하는 법을 배웠다.

.do 로 끝나는 모든 파일이 dispatcherServlet으로 들어간다.










DispatcherServlet.java

package req;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
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.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import handler.Handler;
import handler.member.JoinHandler;
import handler.member.LoginHandler;

/**
 * Servlet implementation class DispatcherServlet
 */
@WebServlet("*.do")

public class DispatcherServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	private Map<String, Handler> map = new HashMap<>();
	// commands.properties 파일의 url과 명령어를 읽어서 저장할 map

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public DispatcherServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	// 서블릿 생성시 딱 한 번 실행되는 메서드.
	@Override
	public void init() throws ServletException {
		// TODO Auto-generated method stub
		Properties prop = new Properties();

		String path = this.getServletContext().getRealPath("/WEB-INF/commands.properties");
		try {
			prop.load(new FileReader(path));
			Iterator iter = prop.keySet().iterator();
			while (iter.hasNext()) {
				String url = (String) iter.next(); // member/join.do
				try {
					String className = prop.getProperty(url); // handler.member.JoinHandler
			
					Class<?> handlerClass = Class.forName(className);
					Constructor<?> cons = handlerClass.getConstructor(null);
					Handler handler = (Handler) cons.newInstance();
					map.put(url, handler);
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String url = request.getServletPath(); // 요청 url 반환 join.do

		String view = null;
		Handler handler = map.get(url); // 업캐스팅

		if (handler != null) {
			view = handler.process(request, response);

			if (view.startsWith("redirect")) {
				String[] path = view.split(":");
				response.sendRedirect(request.getContextPath() + path[1]);
			} else {
				RequestDispatcher dis = request.getRequestDispatcher(view);
				dis.forward(request, response);
			}
		} else {
			response.getWriter().append("404 not found url");
		}
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}














map 만들기

private Map<String, Handler> map = new HashMap<>();

commands.properties 파일의 url과 명령어를 읽어서 저장할 map을 만들어준다.






public void init() throws ServletException

init 메소드는 경로를 가져와서(load) prop에 저장을 한다.
그래서 로드한 데이터의 키를 하나씩 꺼내서 String urlString className에 값을 넣어준다.


public void init() throws ServletException {
		// TODO Auto-generated method stub
		Properties prop = new Properties();
        // Properties 생성자 생성

		String path = this.getServletContext().getRealPath("/WEB-INF/commands.properties");
        // commands.properties에 있는 실제 경로를 가져온다.
        
		try {
			prop.load(new FileReader(path));
			Iterator iter = prop.keySet().iterator();
            // 키만 가져온다.
            
			while (iter.hasNext()) {
				String url = (String) iter.next(); 
                // "member/join.do" 이런 식으로 url을 가져온다.
				try {
					String className = prop.getProperty(url); 
                    // handler.member.JoinHandler
			
					Class<?> handlerClass = Class.forName(className);
					// 클래스에 대한 정보를 알아야하기 때문에 
					// 해당 클래스에 대한 정보를 수집한다. 
                    
                    Constructor<?> cons = handlerClass.getConstructor(null);
					Handler handler = (Handler) cons.newInstance();
                    // => "JoinHandler h = new JoinHandler();" (얜 하드코딩)
                    // 생성을 해주기
                    
					map.put(url, handler);
                    // url과 만든 handler을 map에 저장
                    // 맵에는 "url"과 "url이 왔을 때 실행될 친구"를 넣기 위해서 생성 Handler에는 객체를 생성해서 넣어주는 것이다. 
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				} catch (SecurityException e) {
					e.printStackTrace();
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}






protected void doGet()

/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String url = request.getServletPath(); 
        // 요청 url 반환 "join.do"

		String view = null;
		Handler handler = map.get(url); // 업캐스팅
        // map.put(url, handler); 여기서 넣은 걸 가져오는 것

		if (handler != null) {
			view = handler.process(request, response);

			if (view.startsWith("redirect")) { // redirect로 시작한다면
				String[] path = view.split(":");
				response.sendRedirect(request.getContextPath() + path[1]);
			} else {
				RequestDispatcher dis = request.getRequestDispatcher(view);
				dis.forward(request, response);
			}
		} else { 
			response.getWriter().append("404 not found url");
		}
	}











handler.java

package "handler" 만들어주고
handler.java 생성


그리고 handler 패키지 밑에 handler.member 패키지를 만들어주고
class 파일로 JoinHandler.java를 만들어준다.






이런식으로 만들어준다.










Handler.java

package handler;

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

// 모든 요청 처리 클래스의 부모 
public interface Handler {
	String process(HttpServletRequest request, HttpServletResponse response);
}











파일 다운로드

서버에 있는 파일을 클라이언트에게 복사하는것

//다운로드 폴더
        String downDir = "C:\\down\\";
       
        //사용자가 클릭한 파일명
        String fname = request.getParameter("fname");
       
        // 다운로드할 파일 전체 경로
        String path = downDir + fname;

        //파일에 대한 정보. 파일크기, 읽기, 쓰기, 실행 가능, 존재하는지 유무
        File file = new File(path);
       
        //다운로드 파일의 내용을 읽을 스트림 생성
        FileInputStream in = new FileInputStream(path);

        //파일명 인코딩
        fname = new String(fname.getBytes("euc-kr"), "8859_1");

        //다운로드 응답을 보내기 위한 response 설정
        //setContentType(): 파일의 마임설정. 파일의 종류.
        //octet-stream: 바이너리 파일 한 종류
        response.setContentType("application/octet-stream");
        
        //헤더 설정. 패킷의 중요 정보를 설정. 첨부파일 전송 설정
        response.setHeader("Content-Disposition", "attachment; filename=" + fname);

        //다운로드 파일 내용을 response에 출력할 출력 스트림 획득
        OutputStream os = response.getOutputStream();

        int length;
        
        //다운로드 파일에서 읽은 내용을 담을 byte배열을 파일 크기와 동일하게 생성
        byte[] b = new byte[(int) file.length()];

        //파일에서 읽은 내용을 response에 출력
        while ((length = in.read(b)) > 0) {
            os.write(b, 0, length);
        }
       
        //강제출력
        os.flush();

        //스트림 닫기
        os.close();
        in.close();











자료실 만들기

sql

create table filedown(
num number primary key,
writer varchar2(20) references member(id) on delete cascade,
w_date date,
title varchar2(50),
content varchar2(100),
fname varchar2(100),
cnt number 
);

create sequence seq_filedown;






0개의 댓글