개발자의 오르막
SW 심화과정 18일차 본문
# 파일 업로드
- <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 |