개발자의 오르막

SW 심화과정 18일차 본문

교육과정 ( SW 개발자 심화과정 )/Java

SW 심화과정 18일차

계단 2019. 8. 2. 11:25

# 파일 업로드

 

- <input type="file"> 은 파일을 서버로 업로드 할 때 사용한다.

- 이 때는 반드시 enctype="multipart/form-data" 을 사용한다.
- fileup 에 해당하는 서블릿은 cos.jar 파일의 MultipartRequest 를
    이용하여 업로들르 처리하는 것이 일반적이다.
- request 는 브라우저에서 서버로 요청을 보낸다.
- request.getInputStream() 은 브라우저에서 서버로 전달되는 내용을
   볼 수 있다.
 

   이 내용들을 재구성한 기능이 cos.jar 파일의 MultipartRequest 이다.

 

package study3;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

public class FileUpServlet extends HttpServlet{

	private ServletContext application = null;
	
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		application = config.getServletContext();
	}

	@Override
	public void service(HttpServletRequest request, 
			HttpServletResponse response) 
					throws ServletException, IOException {
		String l = process2(request);
		System.out.println(l);
		
	}
	
	public String process(HttpServletRequest request) throws IOException{
		
		byte[] buf = new byte[1024];
		int len = 0;
		
		StringBuffer sb = new StringBuffer();
		
		InputStream in = request.getInputStream();
		while((len = in.read(buf)) != -1) {
			sb.append(new String(buf, 0, len));
		}
		
		in.close();
		
		return sb.toString();
	}
	
public String process2(HttpServletRequest request) 
		throws IOException{
	
		// fileup 디렉토리의 실제 저장위치 (절대경로) 값을 파악한다.
		String path = application.getRealPath("/WEB-INF/fileup");
		System.out.println(path);
	
		// cos.jar 에서 제공되는 클래스
		MultipartRequest mpr = new MultipartRequest(
				request, path, 1024 * 1024 * 20, "UTF-8", 
				new DefaultFileRenamePolicy());
		// DefaultFileRenamePolicy() 를 대신해 null 값을 주면 덮어씌우게 된다.
		
		
		// 업로드한 원래 파일 이름
		String ofn = mpr.getOriginalFileName("apple");
		
		// 중첩되는 경우에 이름을 바꾸어 저장하는 이름
		String fsn = mpr.getFilesystemName("apple");
		System.out.println(ofn + ", " + fsn);
		
		// MultipartRequest 쓰면 request.getParameter 못 쓴다.
		// 대신 MultipartRequest 안의 getParameter 써야 한다.
		// 한글 처리도 내부에서 다 해줌 ("UTF-8" 로 설정해서)
		String title = mpr.getParameter("title");
		System.out.println(title);
		
		
		return null;
	}
	
}

- DefaultFileRenamePolicy는 이름이 겹칠 때 이름을 바꿔서 올려준다.

- 올릴 때 이름과 서버에 올려진 이름이 다를 수 있다.

 

 

# 파일 다운로드

 

- 서블릿을 통해 경로를 지정한다.

package study3;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

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

@SuppressWarnings("serial")
public class FileDownServlet extends HttpServlet{

   @Override
   public void service(HttpServletRequest request, 
		   HttpServletResponse response) 
				   throws ServletException, IOException {
      String fsn = request.getParameter("fsn");
      String ofn = request.getParameter("ofn");
      if(ofn == null) {
         ofn = fsn;
      }
      
      String path = request.getServletContext().getRealPath("/WEB-INF/fileup");
      
      /* 전송 이전에 어떤 성격의 정보를 전달할지를 브라우저에 먼저 통보
       * MIME Type라고 한다
       * 
       * 주의 : 반드시 응답을 내보내기 전에 작성되어야한다.
       */
      response.setContentType("application/octet-stream");
      response.setHeader("content-disposition", "attachment;filename="+ofn);

      // 서버에 보관중인 파일을 읽어서 브라우저로 내보내는 전송 프로그램
      InputStream in = new FileInputStream(path+"\\"+fsn);
      OutputStream out = response.getOutputStream();
      
      byte[] buf = new byte[1024 * 4];
      int len = 0;
      
      while((len = in.read(buf)) != -1) {
         out.write(buf, 0, len);
         out.flush();
      }
      
      out.close();
      in.close();
   }
}

 

# Forward

 

 

- 브라우저로 하여금 새로운 요청을 하도록 지시한다.
- 응답의 맨 앞의 헤더부분을 이용한다.
- 주의 : 응답의 내용이 맏ㄴ들어진 이후에는 제대로 동작치 않을 수 있다.

- Test124_1.jsp 로 뛰는데, 주소창의 주소는 그대로이다.
- sendRedirect는 주소가 바뀐다.

 

- 위의 경우는 URL에서 계속해서 주소가 바뀌지만
  (124에 요청하고, 끊고, 124_1에 다시 요청해서 응답)

  같은 Context가 아니어도 상관 없음
- 아래의 경우는 주소가 바뀌지 않는 상태에서 서버에서 정보를 전송
  (124에 요청하면, 124에서 124_1로 정보를 넘겨주고 다시 웹에 응답해줌)
  같은 Context 이어야 함.

- 위와 달리 아래같은 경우는 정보를 넘길 때 요주(에러) 등의 정보를 함께

   넘길 수 있다.

 

- Forward는 다음페이지에 뭔가 전달이 가능하다. ( 전화돌리기 )

- SendRedirect 는 다음 페이지에 뭔가 전달이 가능하다.

  

 

 

# MVC

 

1. Controller 인터페이스 생성

package mvc;

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

public interface Controller {
	public String handleRequest(HttpServletRequest request, 
			   HttpServletResponse response) throws Exception;
	
}

 

2. RequestMapping 어노테이션 생성

package mvc;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
	public String value();
}

3. DispatcherServlet 생성

 
  package mvc;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DispatcherServlet extends HttpServlet{

	private Map<String, Controller> mapp = null;
	
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		mapp = new Hashtable<String, Controller>();
		String cs = "mvc.CtrlList, mvc.CtrlAdd2";
		
		String[] cs2 = cs.split(",");
		for(int i=0; i<cs2.length; i++){
			try {
				Class<?> cls = Class.forName(cs2[i]);
				
				RequestMapping an = cls.getAnnotation(RequestMapping.class);
				Controller value = (Controller)cls.newInstance();
				String key = an.value();
				
				mapp.put(key, value);
			}
			catch(Exception e) {
				
			}
		}
		System.out.println(mapp.toString());
		
	}
	// 최초에 들어갔을 때 실행되는 함수
	
	@Override
	protected void service(HttpServletRequest request, 
			HttpServletResponse response) 
					throws ServletException, IOException {
		
	}
}

4. CtrlList

package mvc;

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


@RequestMapping("/apple_list.do")
public class CtrlList implements Controller{

	@Override
	public String handleRequest(HttpServletRequest request, 
			HttpServletResponse response) 
					throws Exception {
		System.out.println("CtrlList");
		return "/apple_list.jsp";
	}
	
}

5. CtrlAdd2

package mvc;

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

@RequestMapping("/apple_add2.do")
public class CtrlAdd2 implements Controller{

	@Override
	public String handleRequest(HttpServletRequest request, 
			HttpServletResponse response) 
					throws Exception {
		System.out.println("CtrlAdd2");
		return "redirect:/apple_list.jsp";
	}
	
}

6. Web.xml

 

 

7. dispatcher controller 의 service 함수 구성

package mvc;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DispatcherServlet extends HttpServlet{

	private Map<String, Controller> mapp = null;
	
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		mapp = new Hashtable<String, Controller>();
		String cs = "mvc.CtrlList,mvc.CtrlAdd2";
		
		String[] cs2 = cs.split(",");
		for(int i=0; i<cs2.length; i++){
			try {
				Class<?> cls = Class.forName(cs2[i]);
				
				RequestMapping an = cls.getAnnotation(RequestMapping.class);
				Controller value = (Controller)cls.newInstance();
				String key = an.value();
				
				mapp.put(key, value);
			}
			catch(Exception e) {
				
			}
		}
		System.out.println(mapp.toString());
		
	}
	// 최초에 들어갔을 때 실행되는 함수
	
	@Override
	protected void service(HttpServletRequest request, 
			HttpServletResponse response) 
					throws ServletException, IOException {
		
		String ctxPath = request.getContextPath();  // /study3
		String uri = request.getRequestURI();		// /study3/asdfjasd.do
		
		uri = uri.substring(ctxPath.length()); //   /study3/asdfjasd.do
		
		Controller ctrl = mapp.get(uri);
		if( ctrl == null ) {
			System.out.println("해당 요청은 미등록입니다.");
			return;
		}
		
		
		try {
			String l = ctrl.handleRequest(request, response);
			if(l == null) {
			
			} else if (l.startsWith("redirect:")){
				response.sendRedirect(ctxPath + l.substring(9));
				
			} else {
				RequestDispatcher rd = request.getRequestDispatcher(l);
				rd.forward(request, response);
			}
		} catch (Exception e) {
			
			
			
			e.printStackTrace();
		}
	}
}

8. CtrlList

package mvc;

import java.util.List;

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

import study3.BangMyungDAO;
import study3.BangMyungDAO_OracleImpl;
import study3.BangMyungVO;


@RequestMapping("/apple_list.do")
public class CtrlList implements Controller{

	@Override
	public String handleRequest(HttpServletRequest request, 
			HttpServletResponse response) 
					throws Exception {
		System.out.println("CtrlList");
		
		BangMyungDAO dao = new BangMyungDAO_OracleImpl();
		List<BangMyungVO> rl = dao.findAll();
		
		
		request.setAttribute("rl", rl);
		
		return "/apple_list.jsp";
	}
	
}

 

9. CtrlAdd2

package mvc;

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

import study3.BangMyungDAO;
import study3.BangMyungDAO_OracleImpl;
import study3.BangMyungVO;
import study3.Util;

@RequestMapping("/apple_add2.do")
public class CtrlAdd2 implements Controller{

	@Override
	public String handleRequest(HttpServletRequest request, 
			HttpServletResponse response) 
					throws Exception {
		System.out.println("CtrlAdd2");
		
		String gul = Util.h(request.getParameter("gul"));
		BangMyungVO vo = new BangMyungVO();
		vo.setGul(gul);
		
		BangMyungDAO dao = new BangMyungDAO_OracleImpl();
		dao.add(vo);
		
		
		
		return "redirect:/apple_list.do";
	}
	
}

 

MVC1

 

MVC2 

 

 

- 이해도는 어려우나 서비스가 복잡해졌을 때 진가를 발휘함.

 

 

- web.xml

 

 

- XML만 수정하더라도 클래스들을 추가할 수 있다.

 

 

- 에러는 dispatcher 에서 통합적으로 발생함으로, 에러페이지 연결만 시켜주면 에러를 종합적으로 잡아준다.

 

 

 

# URL

package main;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

public class Test126 {
	public static void main(String[] args) throws Exception{
		/*
		 * java.net.URL은 이것 자체가 작은 웹브라우저의 역할을 한다.
		 * 요청을 날리고 그에 해당하는 응답을 받아들인다.
		 * 안드로이드 앱에서 버튼을 누르면 오늘의 배송정보가 넘어오는?
		 * 서버에 존재하는 배송정보를 다운받는 역할을 수행한다.
		 * 
		 * 소캣으로 다 짜는 것이 아니라 http 프로토콜로 서버와 통신할 때는
		 * 이 클래스를 주로 이용한다.
		 * 
		 * 앱같은 경우에서 서버로부터 많은 데이터를 다운받아야 할 경우에는 URL 클래스를 이용하여
		 * JSP 파일로부터 정보를 다운받는다.
		 * 
		 * 이게 워낙 많이 쓰이다보니까 오픈소스 라이브러리가 등장
		 * 아파치 Http client 프로젝트 (안드로이드 http 기반 표준 통신수단)
		 * 
		 * 구글에서 httpclient-4.4.jar 을 다운로드
		 */
		
		URL rl = new URL("http://192.168.2.71:8081/study3/Test126.jsp?pw=1234");
		URLConnection ucon = rl.openConnection();
		InputStream in = ucon.getInputStream();
		
		
		// 아답터 역할하는 애
		BufferedReader bin = new BufferedReader(
				new InputStreamReader(in, "UTF-8"));
		String l = null;
		while((l = bin.readLine()) != null) {
			System.out.println(l);
		}
		
		in.close();
	}
}

'교육과정 ( SW 개발자 심화과정 ) > Java' 카테고리의 다른 글

SW 심화과정 22일차  (0) 2019.08.06
SW 심화과정 21일차  (0) 2019.08.05
SW 심화과정 17일차  (0) 2019.07.31
SW 심화과정 16일차  (0) 2019.07.30
SW 심화교육 15일차  (0) 2019.07.29
Comments