본문 바로가기

Programming/국비학원

221013 - JSTL(fmt/fn 라이브러리, 등록/조회 구현) & 서블릿(URL 패턴,파일 다운로드/업로드)

JSTL
  • fmt 라이브러리
  • 날짜 포매팅 (formatDate)
	<c:set var="now" value="<%=new Date() %>" />
	<h2>오늘은 ${now}</h2>
	
    //date
	<fmt:formatDate value="${now }" type="date" var="fmtNow" />
	<h2>오늘은 ${fmtNow}</h2>
	
	<fmt:formatDate value="${now }" type="date" var="fmtNow3" dateStyle="full" />
	<h2>오늘은 ${fmtNow3}</h2>
	
    //time
	<fmt:formatDate value="${now }" type="time" var="fmtNow2" />
	<h2>오늘은 ${fmtNow2}</h2>
	
    //both
	<fmt:formatDate value="${now }" type="both" var="fmtBoth" />
	<h2>오늘은 ${fmtBoth}</h2>
	
	<fmt:formatDate value="${now }" type="both" var="fmtBoth2" dateStyle="full" timeStyle="full" />
	<h2>오늘은 ${fmtBoth2}</h2>
	
	<fmt:formatDate value="${now }" type="both" var="fmtBoth3" pattern="YYYY-MM-dd hh:mm:ss" />
	<h2>오늘은 ${fmtBoth3}</h2>

//
오늘은 Thu Oct 13 16:06:14 KST 2022


오늘은 2022. 10. 13.
오늘은 2022년 10월 13일 목요일


오늘은 오후 4:06:14


오늘은 2022. 10. 13. 오후 4:06:14
오늘은 2022년 10월 13일 목요일 오후 4시 6분 14초 대한민국 표준시
오늘은 2022-10-13 04:06:14

 

 

  • 시간대 포매팅 (timeZone)
<fmt:timeZone value="America/New york" >
	<fmt:formatDate value="${now }" type="both" var="fmtNY" 
        dateStyle="full" timeStyle="full" />
</fmt:timeZone>
<h2>뉴욕은 ${fmtNY}</h2>

//
뉴욕은 2022년 10월 13일 목요일 오전 7시 11분 15초 그리니치 표준시

 

 

 

 

https://luigi-yoon.tistory.com/13

  • fn 함수 라이브러리
  • 문자열
	<c:set var="str1" value="computer"/>
	<c:set var="str2" value="HELLO"/>
	<c:set var="str3" value="  java  "/>
	<c:set var="pos" value="mp"/>
	
	<h2>문자열 길이 : ${fn:length(str1) }</h2>
	<h2>문자열 길이 : ${fn:length(str2) }</h2>
	
	<h2>문자열을 대문자로 : ${fn:toUpperCase(str1) }</h2>
	<h2>문자열을 소문자로 : ${fn:toLowerCase(str2) }</h2>
	
	<h2>일부 문자 반환 : ${fn:substring(str1,3,6) }</h2> <%-- 인덱스 3~5 --%>
	
	<h2>좌우 공백 제거 : ${fn:trim(str3) }</h2>
	
	<h2>문자열 대체 : ${fn:replace(str1,"o","i")  }</h2>
	<h2>문자열 대체 : ${fn:replace(str3," ","^")  }</h2>
	
	<h2>문자열 위치 : ${fn:indexOf(str1,pos) }</h2>
	<h2>문자열 위치 : ${fn:indexOf(str1,p) }</h2>
	
	<h2>문자열 포함여부 : ${fn:contains(str1,pos) }</h2>
	<h2>문자열 포함여부 : ${fn:contains(str1,str3) }</h2>

//
문자열 길이 : 8
문자열 길이 : 5


문자열을 대문자로 : COMPUTER
문자열을 소문자로 : hello


일부 문자 반환 : put


좌우 공백 제거 : java


문자열 대체 : cimputer
문자열 대체 : ^^java^^


문자열 위치 : 2
문자열 위치 : 0


문자열 포함여부 : true
문자열 포함여부 : false

 

 

 

 

  • JSP, JSTL 활용한 회원 등록/조회 기능
  • MemberBean.java
package jsp04.ex01;

import java.sql.Date;

public class MemberBean {

	private String id;
	private String pwd;
	private String name;
	private String email;
	private Date joinDate;
	
	public MemberBean() {
		
	}

	public MemberBean(String id, String pwd, String name, String email) {
		this.id = id;
		this.pwd = pwd;
		this.name = name;
		this.email = email;
	}

	public Date getJoinDate() {
		return joinDate;
	}

	public void setJoinDate(Date joinDate) {
		this.joinDate = joinDate;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}
	
}

 

 

 

  • MemberDAO
public class MemberDAO {

	private Connection con; 
	private PreparedStatement pstmt; 
	private DataSource dataFactory; //
	
	public MemberDAO() { //
		try {
			Context ctx = new InitialContext();
			Context envContext = (Context)ctx.lookup("java:/comp/env");
			dataFactory = (DataSource) envContext.lookup("jdbc/oracle");
		} catch(Exception e) {
			System.out.println("DB 연결 실패");
		}
	}
	
	//회원정보 목록
	public List<MemberBean> listMembers(){
		
		List<MemberBean> list = new ArrayList<MemberBean>();
		try {
			con = dataFactory.getConnection(); //서버 통해 db 연결
			String query = "select * from member_list";
			pstmt = con.prepareStatement(query);
			ResultSet rs = pstmt.executeQuery(); //쿼리 실행
			while(rs.next()) { //쿼리 결과값 한 행씩
				String id = rs.getString("id");
				String pwd = rs.getString("pwd");
				String name = rs.getString("name");
				String email = rs.getString("email");
				Date joinDate = rs.getDate("joindate");
				
				MemberBean memBean = new MemberBean();
				memBean.setId(id);
				memBean.setPwd(pwd);
				memBean.setName(name);
				memBean.setEmail(email);
				memBean.setJoinDate(joinDate);
				
				list.add(memBean);
			}
			rs.close();
			pstmt.close();
			con.close();
		} catch(Exception e) {
			System.out.println("자료 처리 중 에러 발생");
		}
		return list;
		
	}
	
	public void addMember(MemberBean memberBean) {
		try {
			con = dataFactory.getConnection();
			
			String id = memberBean.getId();
			String pwd = memberBean.getPwd();
			String name = memberBean.getName();
			String email = memberBean.getEmail();
			
			String query = "insert into member_list(id, pwd, name, email) values(?,?,?,?)";
			pstmt = con.prepareStatement(query);
			pstmt.setString(1, id);
			pstmt.setString(2, pwd);
			pstmt.setString(3, name);
			pstmt.setString(4, email);
			pstmt.executeUpdate();
			pstmt.close();
		} catch(Exception e) {
			System.out.println("회원 추가 중 에러 발생");
		}
	}
	
	public void delMember(String id) {
		try {
			con = dataFactory.getConnection();
			String query = "delete from member_list where id=?";
			pstmt = con.prepareStatement(query);
			pstmt.setString(1,id);
			pstmt.executeUpdate();
			pstmt.close();
		} catch(Exception e) {
			System.out.println("삭제 중 에러 발생");
		}
	}
	
}

 

 

 

  • memberForm.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입 창</title>
<script type="text/javascript">
	function fn_sendMember(){
		let frmMember = document.frmMember;
		let id = frmMember.id.value;
		let pwd = frmMember.pwd.value;
		let name = frmMember.name.value;
		let email = frmMember.email.value;
		
		if(id.length==0||id==""){
			alert('아이디를 입력해주세요');
		} else if (pwd.length==0||pwd==""){
			alert('비밀번호를 입력해주세요');
		} else if (name.length==0||name==""){
			alert('이름을 입력해주세요');
		} else if (email.length==0||email==""){
			alert('이메일을 입력해주세요');
		} else {
			frmMember.method="post";
			frmMember.action="memberAction.jsp";
			frmMember.submit(); 
		}
	}
</script>
</head>
<body>
	<form name=frmMember>
		<h2>회원가입 창</h2>
		<table>
			<tr>
				<td>아이디</td>
				<td><input type="text" name="id"></td>
			</tr>
			<tr>
				<td>비밀번호</td>
				<td><input type="password" name="pwd"></td>
			</tr>
			<tr>
				<td>이름</td>
				<td><input type="text" name="name"></td>
			</tr>
			<tr>
				<td>이메일</td>
				<td><input type="text" name="email"></td>
			</tr>
		</table>
		<input type="button" value="가입하기" onclick="fn_sendMember()">
		<input type="reset" value="다시 입력">
		<input type="hidden" name="command" value="addMember"> <!-- ★어떤 목적(탈퇴면 value="delMember")으로 서버에 접근하는지 확인 -->
	</form>
</body>
</html>

 

 

 

  • memberAction.jsp (멤버 조회)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*, jsp04.ex01.*"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<% request.setCharacterEncoding("utf-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 정보 조회</title>
<jsp:useBean id="mem" class="jsp04.ex01.MemberBean" />
<jsp:setProperty property="*" name="mem"/>
<%
	MemberDAO memDAO = new MemberDAO();
	memDAO.addMember(mem); //db 내 회원리스트에 회원 객체 추가
	List memberList = memDAO.listMembers(); //db 내 회원리스트 List 객체로 가져오기
	request.setAttribute("memberList", memberList); //바인딩
%>
</head>
<body>
	<jsp:forward page="memberList.jsp"/>
</body>
</html>

 

 

 

  • memberList.jsp (조회한 멤버 출력)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<% request.setCharacterEncoding("utf-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원 목록 출력</title>
</head>
<body>
	<table border="1" align="center">
		
		<tr align="center" bgcolor="beige">
			<th>아이디</th><th>비밀번호</th><th>이름</th><th>이메일</th><th>가입일</th>
		</tr>
		
-		<c:choose>
			<c:when test="${memberList==null }">
				<tr>
					<td colspan="5">등록된 회원이 없습니다</td>
				</tr>
			</c:when>
			<c:when test="${memberList!=null }">
				<c:forEach var="m" items="${memberList }">
					<tr align="center">
						<td>${m.id }</td>
						<td>${m.pwd }</td>
						<td>${m.name }</td>
						<td>${m.email }</td>
						<td>${m.joinDate }</td>
					</tr>
				</c:forEach>
			</c:when>			
		</c:choose>

	</table>
</body>
</html>

 

 

https://shiningjean.tistory.com/15
※ redirect vs forward

redirect
URL 변경 O, request 객체 재사용 X
시스템(session, DB)에 변화가 생기는 요청(로그인, 글작성, 회원가입)에 적합

forward
URL 변경 X, request 객체 재사용 O
Web Container의 내부에서 이동하므로 request, response 객체 공유가 가능
시스템에 변화가 생기지 않는 단순 조회(검색)에 적합

 

 

 

 

https://azderica.github.io/00-java-urlpattern/
https://byungmin.tistory.com/65

서블릿

파일업로드 api 다운
https://commons.apache.org/proper/commons-fileupload/download_fileupload.cgi

 

 

 

 

  • URL 패턴

: 서블릿의 매핑 이름 
=> 클라이언트가 브라우저에서 요청할 때 사용되는 이름 (/로 시작)

 

 

 

  • 종류

1. 정확한 매핑 : 정확히 이름까지 일치 "/login/hello.do"
2. 경로 매핑 : 디렉터리 일치 "/login/*"
3. 확장자 매핑 : 확장자 일치 "*.do"
4. 디폴트 매핑 : "/"

 

 

 

 

https://code-nen.tistory.com/36

  • URL 패턴별 서블릿 매핑
  • URLTest01 
@WebServlet("/first/test")
public class URLTest01 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
        
		String context = request.getContextPath(); //컨텍스트(프로젝트) 이름
		String url = request.getRequestURL().toString(); 
        //전체 경로 (프로토콜+도메인+포트번호+컨텍스트 경로+서블릿 경로)
		String mapping = request.getServletPath(); //서블릿 매핑 이름
		String uri = request.getRequestURI(); //컨텍스트 경로+서블릿 경로
        
		out.print("<html><body bgcolor='whitesmoke'>");
		out.print("<p>URLTest03 클래스</p>");
		out.print("<p>컨텍스트 이름 : " + context + "</p>");
		out.print("<p>전체 경로 : " + url + "</p>");
		out.print("<p>매핑 이름 : " + mapping + "</p>");
		out.print("<p>URI 이름 : " + uri + "</p>");
		out.print("</body></html>");
	}

}

//

URLTest01 클래스

컨텍스트 이름 : /jsp05

전체 경로 : http://localhost:8070/jsp05/first/test

매핑 이름 : /first/test

URI 이름 : /jsp05/first/test

 

 

 

  • URLTest02
@WebServlet("/first/*") ////
public class URLTest02 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
        
		String context = request.getContextPath(); 
		String url = request.getRequestURL().toString();
		String mapping = request.getServletPath(); 
		String uri = request.getRequestURI(); 
        
		out.print("<html><body bgcolor='azure'>");
		out.print("<p>URLTest02 클래스</p>");
		out.print("<p>컨텍스트 이름 : " + context + "</p>");
		out.print("<p>전체 경로 : " + url + "</p>");
		out.print("<p>매핑 이름 : " + mapping + "</p>");
		out.print("<p>URI 이름 : " + uri + "</p>");
		out.print("</body></html>");
	}

}

 

 

 

  • URLTest03
@WebServlet("*.do") ////
public class URLTest03 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
        
		String context = request.getContextPath(); 
		String url = request.getRequestURL().toString();
		String mapping = request.getServletPath(); 
		String uri = request.getRequestURI();
        
		out.print("<html><body bgcolor='whitesmoke'>");
		out.print("<p>URLTest03 클래스</p>");
		out.print("<p>컨텍스트 이름 : " + context + "</p>");
		out.print("<p>전체 경로 : " + url + "</p>");
		out.print("<p>매핑 이름 : " + mapping + "</p>");
		out.print("<p>URI 이름 : " + uri + "</p>");
		out.print("</body></html>");
	}

}

 

 

※ URI(Uniform Resource Identifier) ⊃ URL 
URL : 실제 파일 위치 (ex. xxxx.com, xxxx.com/index.html)
URI : 실제 파일 위치 + 식별자도 포함 (ex. xxxx.com/01)

 

 

 

 

  • 파일 업로드 구현
  • uploadForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath }" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>업로드</title>
</head>
<body>
	<form action="${contextPath }/upload.do" method="post"
	enctype="multipart/form-data"> <!-- 폼 데이터가 서버로 제출될 때 데이터가 인코딩되는 방법 -->
		파일 1 : <input type="file" name="file1"><br>
		파일 2 : <input type="file" name="file2"><br>
		매개변수 1 : <input type= "text" name="param1"><br>
		매개변수 2 : <input type= "text" name="param2"><br>
		매개변수 3 : <input type= "text" name="param3"><br>
		<input type="submit" value="업로드">
	</form>
</body>
</html>

 

 

 

https://zincod.tistory.com/64

  • FileUpload
@WebServlet("/upload.do")
public class FileUpload extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String encoding="utf-8";
		
		File currentFolder = new File("C:\\file_upload");
		DiskFileItemFactory factory = new DiskFileItemFactory(); //업로드된 파일 저장할 저장소
		factory.setRepository(currentFolder); //저장소 위치를 currentFolder로 지정
		factory.setSizeThreshold(1024*1024); //저장소에 임시파일을 생성할 최대 크기(byte)
		ServletFileUpload fileUpload = new ServletFileUpload(factory); //요청 객체의 변환 지원 클래스
		try {
			List items = fileUpload.parseRequest(request) //요청에서 받은 객체를 List로 반환
			for (int i=0; i<items.size();i++) {
				FileItem fileItem = (FileItem) items.get(i); //사용자가 업로드한 파일 or 사용자가 input에 입력한 일반 데이터 객체
				if (fileItem.isFormField()) { //true : 일반 입력 데이터 / false : 파일데이터
					System.out.println(fileItem.getFieldName()+" = "+fileItem.getString(encoding));
				} else {
					System.out.println("매개변수 이름 : "+fileItem.getFieldName());
					System.out.println("파일 이름 : "+fileItem.getName());
					System.out.println("파일 크기 : "+fileItem.getSize()+"bytes");
					if (fileItem.getSize()>0) {
						int idx = fileItem.getName().lastIndexOf("\\");
						if (idx==-1) {
							idx=fileItem.getName().lastIndexOf("/");
						}
						String fileName = fileItem.getName().substring(idx+1);
						File uploadFile = new File(currentFolder + "\\" + fileName); //해당 위치에 파일 업로드
						fileItem.write(uploadFile); //업로드된 파일을 저장소 디렉터리에 저장
					}
				}
			}
		} catch (Exception e) {
			System.out.println("파일 업로드 실패!");
		}
	}

}

 

 

 

 

https://velog.io/@alicesykim95/JSP-File-Upload-Download-%EC%97%85%EB%A1%9C%EB%93%9C-%EB%B0%8F-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C

  • 파일 다운로드 구현
  • FileDownload
@WebServlet("/download.do")
public class FileDownload extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String encoding = "utf-8";
		
		String fileFolder = "C:\\file_upload";
		String fileName = (String)request.getParameter("fileName");
		System.out.println("파일 이름 = "+fileName);
		
		OutputStream outS = response.getOutputStream(); //출력 스트림(통로) 생성
		String downFile = fileFolder + "\\" + fileName;
		File file = new File(downFile); //해당 경로의 파일 읽어와 객체 생성 (다운받을 객체)
		
		//헤더 설정
		response.setHeader("Cache-Control", "no-cache"); //응답 받은 결과를 캐싱하지 않도록
		response.setHeader("Content-disposition", "attachement;fileName="+fileName+".png"); //다운로드할 파일 화면 표시
		// 다운로드 or 로컬 저장인지 헤더
		
		//버퍼 이용해 8kb씩 브라우저 전송
		FileInputStream fInput = new FileInputStream(file); //입력 스트림 생성 => 다운받을 객체를 스트림에 담음
		byte[] buffer = new byte[1024*8]; //파일 읽을 buffer 생성 (8kb) 
		while(true) {
			int count=fInput.read(buffer); //입력 스트림 읽기
			if (count==-1) {
				break;
			}
			outS.write(buffer,0,count); //buffer 배열 내에서 인덱스 0부터 count만큼 출력
		}
		fInput.close();
		outS.close();
	}

}

 

 

 

  • downReq.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>다운로드 요청창</title>
</head>
<body>
	<form action="download.jsp" method="post">
		<input type="hidden" name="param1" value="a.png">
		<input type="hidden" name="param2" value="b.png">
		<input type="submit" value="이미지 다운로드">
	</form>
</body>
</html>

 

 

 

https://velog.io/@cyhse7/spring-%EB%8B%A4%EC%A4%91-%ED%8C%8C%EC%9D%BC-%EC%9D%B4%EB%AF%B8%EC%A7%80

  • download.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath }"/> <!-- 다른 곳에서도 사용 가능하게??? -->
<c:set var="file1" value="${param.param1 }"/>
<c:set var="file2" value="${param.param2 }"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>다운로드 창</title>
</head>
<body>
	첫번째 이미지 : <c:out value="${file1 }"/>
	<c:if test="${not empty file1 }">
		<img src="${contextPath }/download.do?fileName=${file1}" width="374" height="215"><br>
		<a href="${contextPath }/download.do?fileName=${file1}">파일 내려받기</a><br>
	</c:if>
	
	두번째 이미지 : <c:out value="${file2 }"/>
	<c:if test="${not empty file2 }">
		<img src="${contextPath }/download.do?fileName=${file2}" width="374" height="250"><br>
		<a href="${contextPath }/download.do?fileName=${file2}">파일 내려받기</a><br>
	</c:if>	
</body>
</html>