Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

Everything has an expiration date

[SpringMVC] 20240130 [프로그램 소스] 본문

[Spring MVC]/Program source (Spring MVC)

[SpringMVC] 20240130 [프로그램 소스]

Jelly-fish 2024. 1. 30. 12:23

 

SpringMVCStudy

 

FileSystemApp06


체크할 사항

 

Ⅰ. MultipartRequest 객체의 매개변수 구성

multi = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());

 

 

① 기본 request 를 넘겨준다.

 

이때, 이전 페이지 Test.jsp 에서 데이터 전송을 일반적인 방식이 아닌 `enctype="multipart/form-data"`를 이용하여

데이터를 전송했음을 확인할 수 있다.

Test.jsp
<form action="Test_ok.jsp" method="post" enctype="multipart/form-data">
	....
</form>

 

일반적인 request 가 아니라, multipart 로 넘겨준다는 것은... binary 형태의 request로 넘겨준다는 것을 뜻한다.


② 클라이언트가 업로드한 파일을 서버단에서 받아 물리적으로 저장해 둘 위치 savePath를 문자열로 넘겨준다.
String root = pageContext.getServletContext().getRealPath("/");
String savePath = root + "pds" + "\\" + "saveFile";

// 테스트
//System.out.println(savePath);
// C:\SpringMVCStudy\.metadata\.plugins\org.eclipse.wst.server.core
//   \tmp0\wtpwebapps\FileSystemApp06_02\pds\saveFile

③ 클라이언트가 최대로 업로드 가능한 파일 크기 maxFileSize 를 넘겨준다.
int maxFileSize = 5*1024*1024;	//-- 최대 업로드 크기(5MB)

④ 인코딩 방식 encType 을 넘겨준다.
String encType = "UTF-8";		//-- 인코딩 방식(UTF-8)

⑤ 파일 이름 정책 DefaultFileRenamePolicy()을 매개변수로 넘겨준다.
new DefaultFileRenamePolicy()

 

`new DefaultFileRenamePolicy()`

  • 파일의 이름 정책에 있어서 기본 값을 적용하겠다는 의미이다.

 

클라이언트가 파일을 웹 브라우저에 업로드 할 때마다 서버에서 새로운 파일이 만들어져야 하는데...

이 파일명은 중복되어서는 안 된다.
이때, 중복되는 파일의 이름을 새롭게 변경하여 붙여주는 정책을 FileRenamePolicy() 라고 하며

`DefaultFileRenamePolicy()` 로 설정한다는 것은 파일 이름 정책에 기본값을 적용하겠다는 의미가 된다.

 

ex)

폴더명 : "새 폴더" 생성한 후 → 폴더명 : "새 폴더" 를 새로 생성할시...
폴더명이 중복되므로 "새 폴더(1)" 이런 식으로 파일 명을 다시 짓는 규칙이 적용된다.
이것이 `FileRenamePolicy()` 이다!


 

Ⅱ. MultipartRequest 매개변수 총 정리

new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());

 

MultipartRequest(①, ②, ③, ④, ⑤)
① request 요청객체
② savePath 클라이언트가 올린 파일을 저장할 문자열 경로
③ maxFileSize 업로드 가능한 파일 용량
④ encType 인코딩 방식
⑤ DefaultFileRenamePolicy() 파일 이름 정책

 


Ⅲ. 연습 - 클라이언트가 업로드한 파일에 대한 정보 View 페이지 출력

 

1. 실제 경로 찾아오기
String root = pageContext.getServletContext.getRealPath("/");

2. 클라이언트가 업로드한 파일을 받아 서버단에서 물리적으로 저장할 경로 지정하기
String savePath = root + "pds" + "\\" + "saveFile";
//-- 이 디렉터리 경로에 클라이언트가 업로드한 파일이 저장된다.

3. 새로운 파일 객체 생성하기, 위에서 지정한 서버 저장 경로에 파일 생성
File dir = new File(savePath);

4. 경로 디렉터리가 존재하지 않는다면, 디렉터리를 생성한다.
if (!dir.exists())
	dir.mkdirs();

5. 인코딩 방식 설정하기
String encType = "UTF-8";

6. 최대 업로드 크기 지정하기
int maxFileSize = 5*1024*1024;

7. MultipartRequest 생성 - 단, try~catch 문 내부에서!

try
{
	MultipartRequest multi = null;
	multi = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
	// 1. 요청객체, 2. 저장 경로, 3. 최대 파일 용량, 4. 인코딩 방식, 5. 파일명 재정의 정책 객체

	8. 위에서 생성한 MultipartRequest 객체 내부에 요청객체가 있으므로
	   이를 이용하여 View 페이지단에 클라이언트가 업로드한 파일에 대한 정보를 출력해 준다.
	
	8-1. 이전 뷰 페이지(Test.jsp)에서 입력받은 값이므로 『getParameter("name")』 으로 접근
	out.println("작성자 : " + multi.getParameter("userName"));
	out.println("제목 : " + multi.getParameter("subject") + "<br>");

	8-2. 파일에 대한 정보를 가져오는 것이므로, 별도의 메소드를 사용한다.
	out.println("서버에 저장된 파일명 : " + multi.getFilesystemName("uploadFile") + "<br>");
	out.println("업로드한 파일명 : " + multi.getOriginalFileName("uploadFile") + "<br>");
	out.println("파일 타입 : " + multi.getContentType("uploadFile") + "<br>");
	
	8-3. 이전 페이지(Test.jsp)에서 전송한 파일("uploadFile")을 받아오기.
	File file = multi.getFile("uploadFile");

	8-4. 파일이 존재할 때, 파일 크기를 뷰 페이지에 출력하기
	if (file != null)
	{
		out.print("파일 크기 : " + file.length() + "<br>");
	}

}
catch(Exception e)
{
	System.out.println(e.toString());
}

 

[파일에 대한 정보를 가져오는 메소드 정리]
getFilesystemName("FileName") 서버에 저장된 파일명 가져오기
(* 중복 파일명의 경우 FileRenamePolicy() 적용)

ex) `"맛있는떡볶이2.jpg"`
getOriginalFileName("FileName") 클라이언트가 실제로 업로드한 원본 파일명 가져오기

ex) `"맛있는떡볶이.jpg"`
getContentType("FileName") 업로드한 파일의 타입 가져오기

ex) `image/jpg`

 

 


FileSystemApp06


실행 스크린샷

0123
Test.jsp, Test_ok.jsp - 같은 파일명을 여러 번 올릴 경우 FileRenamePolicy() 정책에 따라 숫자가 붙는다.

 

WebContent

Test.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test.jsp</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>

<div>
	<h1>파일 업로드 - 단일 파일 업로드</h1>
	<hr>
</div>

<div>
	<form action="Test_ok.jsp" method="post" enctype="multipart/form-data">
		
		작성자 : <input type="text" name="userName">
		<br>
		
		제목 : <input type="text" name="subject">
		<br>
		
		파일 : <input type="file" name="uploadFile">
		<br>
		
		<button type="submit" class="btn">파일 올리기</button>
		
	</form>
</div>

</body>
</html>

 


WebContent

Test_ok.jsp
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<%
	// Test_ok.jsp
	
	//String root = request.getRealPath("/");		//-- 예전 방식
	String root = pageContext.getServletContext().getRealPath("/");
	//String savePath = root + "\\" + "pds" + "\\" + "saveFile";
	String savePath = root + "pds" + "\\" + "saveFile";
	
	File dir = new File(savePath);
	

	// 테스트
	//System.out.println(savePath);
	//--==>> 
	// C:\SpringMVCStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FileSystemApp06_02\pds\saveFile 
	

	// 경로 디렉터리가 존재하지 않는다면...
	// 디렉터리를 생성하라.
	if (!dir.exists())
		dir.mkdirs();
	
	String encType = "UTF-8";		//-- 인코딩 방식(UTF-8)
	int maxFileSize = 5*1024*1024;	//-- 최대 업로드 크기(5MB)
	
	try
	{
		// com.oreilly.servlet → cos.jar
		// multipart 를 지원하는 라이브러리이다.
		// multipart/form-data 의 경우 기존의 request.getParameter()로 데이터 수신이 안 됐기 때문
		
		MultipartRequest multi = null;
		multi = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
		
		
		// request 를 매개변수로 받은 multi 에서 파라미터를 꺼내온다.
		out.println("작성자 : " + multi.getParameter("userName"));
		out.println("제목 : " + multi.getParameter("subject") + "<br>");
		out.println("서버에 저장된 파일명 : " + multi.getFilesystemName("uploadFile") + "<br>");
		out.println("업로드한 파일명 : " + multi.getOriginalFileName("uploadFile") + "<br>");
		out.println("파일 타입 : " + multi.getContentType("uploadFile") + "<br>");
		
		File file = multi.getFile("uploadFile");
		
		if (file != null)
		{
			out.println("파일 크기 : " + file.length() + "<br>");
		}
		
		// 바이너리 형태의 request 를 필터링하는 과정이다.
		// MultipartRequest()의 매개변수로 기본 request 를 넘겨준다.
		// 일반적인 request 가 아니라, multipart 로 넘겨준다는 것은
		// 바이너리 형태의 request로 넘겨주는 것이기 때문이다.
		// savePath :  파일이 업로드 되는 물리적인 저장 위치를 문자열로 넘겨준다.
		// maxFileSize : 최대 업로드 파일 크기 5MB 를 의미한다.
		// encType : 인코딩 방식
		// new DefaultFileRenamePolicy() : 파일의 이름 정책에 있어서 기본 값을 적용하겠다는 의미이다.
		// 서버에서 새로운 파일이 만들어져야 한다.
		// 이름을 새롭게 붙이는 정책을 FileRenamePolicy()!!!
		// 폴더명 : "새 폴더" 생성한 후 -> 폴더명 : "새 폴더" 새로 생성시...
		// 폴더명이 중복되므로 "새 폴더(1)" 이런 식으로 파일 명을 다시 짓는 규칙이 적용된다.
		// 이것이 FileRenamePolicy() 이다!
		
		
		
	}
	catch(Exception e)
	{
		System.out.println(e.toString());
	}
	
	
	
	
	// 아래 보여지는 템플릿 모두 제거
%>

 


 

FileSystemApp07


실행 스크린샷

012345
Write.jsp, Write_ok.jsp, 다운로드 클릭시, 파일탐색기가 열리면서 다운로드가 됨을 확인.

 


 

WebContent

Write.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Write.jsp</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>

<div>
	<h1>파일업로드 - 단일파일업로드 및 다운로드</h1>
	<hr>
</div>

<div>
	<form action="Write_ok.jsp" method="post" enctype="multipart/form-data">
	
		작성자 : <input type="text" name="userName"><br>
		제목 : <input type="text" name="subject"><br>
		파일 : <input type="file" name="uploadFile"><br>
		<br>
		
		<button type="submit" class="btn">파일올리기</button>
		
	</form>
</div>




</body>
</html>

WebContent

Write_ok.jsp
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<%
	/* Write_ok.jsp */
	
	// ① 주요 속성값들 준비
	// ①-1. 경로
	String root = "/";
	root = pageContext.getServletContext().getRealPath(root);
	
	//* pds : 파티션 데이터 세트(Partitioned data sets)
	String savePath = root + "pds" + File.separator + "saveFile";
	//                               ───────
	//                                  → "\\"
	
	// C:\SpringMVCStudy\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FileSystemApp07\pds\saveFile
	
	
	// ①-2. 인코딩방식
	String encType = "UTF-8";
	// ①-3. 최대파일용량
	int maxFileSize = 5*1024*1024;
	
	// ② 위에서 설정한 경로 상 디렉터리가 존재하지 않으면... 생성한다.
	File dir = new File(savePath);
	if (!dir.exists())
		dir.mkdirs();
		//-- 1. mkdir() : 단일 디렉토리 하나만 새롭게 생성한다.
		//-- 2. mkdirs() : 디렉터리 경로 상에 구성되어 있지 않은 디렉터리들을 모두 생성해 준다.
	
	// ③ MultipartRequest 객체 구성
	MultipartRequest req = null;
	String urlFile = "";
	
	try
	{
		// ※ 인자 리스트
		//    - request요청객체, 파일저장경로, 파일최대크기, 인코딩방식, 중복파일명처리정책
		req = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
		
		// ④ 구성된 MultipartRequest 객체로부터 필요한 값 얻어내기
		//    - getParameter()
		out.println("작성자 : " + req.getParameter("userName") + "<br>");
		out.println("제목 : " + req.getParameter("subject") + "<br>");
		//	  - getFilesystemName()
		out.println("서버에 저장된 파일명 : " + req.getFilesystemName("uploadFile") + "<br>");
		//    - getOriginalFileName()
		out.println("업로드한 파일명 : " + req.getOriginalFileName("uploadFile") + "<br>");
		//    - getContentType()
		out.println("파일 타입 : " + req.getContentType("uploadFile") + "<br>");
		
		//	  - getFile()
		File f = req.getFile("upladFile");
		if (f != null)
		{
			// - length
			out.println("파일 크기 : " + f.length() + "Bytes. <br>");
		}
		
		// ⑤ 다운로드 기능을 수행하기 위한 속성을 get 방식으로 처리
		urlFile = "Download.jsp?saveFileName=" + req.getFilesystemName("uploadFile");
		//-- 속성 구성 1 → 서버에 저장된 파일의 이름
		urlFile += "&originalFileName=" + req.getOriginalFileName("uploadFile");
		//-- 속성 구성 2 → 실제 업로드한 파일의 이름
		
		
	}
	catch(Exception e)
	{
		System.out.println(e.toString());
	}
	
	
	
	
	

%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Write_ok.jsp</title>
<link rel="stylesheet" type="text/css" href="<%=cp %>/css/main.css">
</head>
<body>

<div>
	<a href="<%=urlFile%>">파일 다운로드</a>
</div>

</body>
</html>

 


WebContent

Download.jsp
<%@page import="com.test.util.FileManager"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<%
	/* Download.jsp */
	
	String root = "/";
	root = pageContext.getServletContext().getRealPath(root);
	
	String savePath = root + "pds" + File.separator + "saveFile";
	
	String saveFileName = request.getParameter("saveFileName");
	String originalFileName = request.getParameter("originalFileName");
	
	// check~!!!
	// 파일 다운로드
	out.clear();		//-- 기존 출력 스트림 클리어~
	boolean flag = FileManager.doFileDownload(saveFileName, originalFileName, savePath, response);
	
	
	
%>

 


 

Java Resources > src > com.test.util

FileManager.java
/*================================
        FileManager.java
=================================*/

package com.test.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletResponse;



public class FileManager
{
	// 파일 다운로드
	//-- 다운로드할 파일이 정상적으로 존재할 경우 true 반환
	//   파일이 존재하지 않아 정상적인 처리가 이루어지지 않을 경우 false 반환
	// - saveFileName     : 서버에 저장된 파일의 이름
	// - originalFileName : 클라이언트가 업로드한 파일의 이름
	// - path             : 서버에 저장된 경로
	// - response         : HttpServletResponse 응답객체
	public static boolean doFileDownload(String saveFileName, String originalFileName, String path, HttpServletResponse response)
	{
		
		// 워크스페이스 - 물리적인 실제 파일이 존재하는 서버 경로 → 전체 경로
		String loadDir = path + File.separator + saveFileName;
		
		// 확인
		System.out.println(loadDir); 
		
		try
		{
			if (originalFileName == null || originalFileName.equals(""))
			{
				originalFileName = saveFileName;
			}
			
			//new String(originalFileName.getBytes("EUC-KR"), "ISO-8859-1");
			originalFileName = new String(originalFileName.getBytes("EUC-KR"), "ISO-8859-1");
			// 파일명을 EUC-KR 방식으로 가져와서 ISO-8859-1 인코딩 방식으로새로운 문자열을 구성한다.
			// UnsupportedEncodingException : 지원하지 않는 인코딩 방식일 경우 예외를 발생시킨다.
			
		}
		catch(UnsupportedEncodingException e)
		{
			System.out.println(e.toString());
		}
		
		
		try
		{
			File file = new File(loadDir);
			
			// 서버에 물리적인 파일이 존재할 때
			if (file.exists())
			{
				// 1. 배열 미리 생성.
				byte[] readByte = new byte[4*1024];		//-- 4096 byte == 4 kb
				
				// 2. 응답하는 ContentType 설정. [mine 타입, content 타입] - 브라우저에게 전송.
				//    바이트 기반의 스트림일 때 아래와 같이 구성한다.
				response.setContentType("application/octet-stream");
				// 3.               _________________________________ ← 약속       파일명을 넘긴 것을 확인. 
				response.setHeader("Content-disposition", "attachment;filename=" + originalFileName);
				
				
				// 4. 서버의 물리적 파일의 전체 경로로 FIleInputStream 객체 생성
				//    이 객체를 BufferedInputStream 객체로 감싸는 처리
				BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file));
				
				OutputStream os = response.getOutputStream();
				
				int read;
				// readByte 로 읽어들여서 4 KB 만큼 써내고(os.write) ... 이 과정을 반복한다.
				// 값이 -1 이 된 것이면, 읽어들인 모든 byte 내용을 써냈음을 의미하는 것이므로 반복을 멈춘다.
				while ( (read=fis.read(readByte, 0, 4096)) != -1 )
				{
					os.write(readByte, 0, read);
				}
				
				// 버퍼의 내용을 밀어내기
				os.flush();
				
				// 리소스 반납하기
				os.close();
				fis.close();
				
				// 파일이 존재하는 상황이므로 true 반환
				
				return true;
				
			}
		}
		catch(Exception e)
		{
			System.out.println(e.toString());
		}
		
		// 파일이 존재하지 않아 정상적인 처리가 이루어지지 않는 상황이므로 false 반환
		return false;
		
	}// end doFileDownload()
	
	
	// 실제 서버의 파일 삭제(제거)
	public static void doFileDelete(String fileName, String path)
	{
		// 파일을 클라이언트가 받았을 때, 서버단에서 삭제하기를 희망하는 경우
		// 이 메소드를 사용하면 된다.
		try
		{
			File file = null;
			
			String fullFileName = path + File.separator + fileName;
			file = new File(fullFileName);
			
			// 파일이 존재하면 파일을 제거한다.
			if (file.exists())
			{
				file.delete();
			}
			
		}
		catch(Exception e)
		{
			System.out.println(e.toString());
		}
	}
}

 


FileSystemApp08


실행 스크린샷

01
Test.jsp, Test_ok.jsp : 다중 파일 업로드 확인

WebContent

Test.jsp
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test.jsp</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>

<div>
	<h1>파일업로드 - 다중 파일 업로드</h1>
	<hr>
</div>

<div>
	<form action="Test_ok.jsp" method="post" enctype="multipart/form-data">
		
		작성자 : <input type="text" name="userName"><br>
		제목 : <input type="text" name="subject"><br>
		파일명 : <input type="file" name="uploadFile1"><br>
		파일명 : <input type="file" name="uploadFile2"><br>
		<br>
		
		<input type="submit" value="파일업로드">
		
	</form>
</div>

</body>
</html>

 


WebContent

Test_ok.jsp
<%@page import="java.util.Enumeration"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="java.io.File"%>
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<%
	/* Test_ok.jsp */
	
	String root = "/";
	root = pageContext.getServletContext().getRealPath(root);
	
	String savePath = root + "pds" + File.separator + "saveFile";
	
	// 확인
	System.out.println(savePath);
	
	File dir = new File(savePath);
	if (!dir.exists())
		dir.mkdirs();
	
	String encType = "UTF-8";
	int maxFileSize = 5*1024*1024;
	
	MultipartRequest req = null;
	
	try
	{
		req = new MultipartRequest(request, savePath, maxFileSize, encType, new DefaultFileRenamePolicy());
		
		out.println("작성자 : " + req.getParameter("userName") + "<br>");
		out.println("제목 : " + req.getParameter("subject") + "<br>");
		out.println("******************************************************<br>");
		
		out.println("업로드된 파일<br>");
		
		// check~!!!
		// ※ 다중 파일 업로드 구조에서 체크해야 할 사항
		//    『MultipartRequest』 객체의 『getFileNames()』
		//    → 요청으로 넘어온 파일들의 이름을 Enumeration 타입으로 반환한다.
		Enumeration files = req.getFileNames();
		
		// hasMoreElements() / nextElement()
		while(files.hasMoreElements())
		{
			String name = (String)files.nextElement();
			
			if (req.getFilesystemName(name) != null)
			{
				out.println("서버에 저장된 파일명 : " + req.getFilesystemName(name) + "<br>");
				out.println("업로드한 실제 파일명 : " + req.getOriginalFileName(name) + "<br>");
				out.println("파일 타입(유형) : " + req.getContentType(name) + "<br>");
				
				File f = req.getFile(name);
				if (f != null)
				{
					out.println("파일 크기(Bytes) : " + f.length() + "<br>");
				}
			}
			
		}
		
		
	}
	catch(Exception e)
	{
		System.out.println(e.toString());
	}
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>

</body>
</html>