동일한 파일 업로드 예제
fileupload_commons_2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파일 업로드(commons.jar이용)</title>
</head>
<body>
<!-- enctype 속성 : 전송타입 설정,
파일을 전송하기 위해서는 반드시 multipart/form-data로 지정함-->
<form action="fileupload_commons_2_process.jsp" name="fileForm" method="post"
enctype="multipart/form-data">
<p><b>올린 사람 : </b><input type="text" name="name" /></p>
<p><b>파 일 : </b><input type="file" name="filename" /></p>
<p><input type="submit" value="파일 업로드" /></p>
</form>
</body>
</html>
fileupload_commons_2_process.jsp
<%@page import="java.io.File"%>
<%@page import="java.util.Iterator"%>
<%@page import="org.apache.commons.fileupload.FileItem"%>
<%@page import="java.util.List"%>
<%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>파일 업로드(commons)</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String path="C:\\workspace-jsp\\upload";
String fileName = "";
//넘겨온 파일의 형태가 "multipart/form-data" 인지 확인
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart) {
//메모리나 파일로 업로드할 때 파일을 보관하는 역할을하는 fileItem의 factory설정.
DiskFileItemFactory factory = new DiskFileItemFactory();
//업로드 요청처리하는 ServletFileUpload 객체 생성.
ServletFileUpload upload = new ServletFileUpload(factory);
//업로드의 요청이 들어올때 파싱해서 FileItem목록 구하는 코드
List<FileItem> items = upload.parseRequest(request);
//반복자를 얻음.
Iterator<FileItem> iterator = items.iterator();
while(iterator.hasNext()) {
FileItem item = iterator.next();
//파일인지 여부확인하는 부분
//텍스트라면
if(item.isFormField()) {
String name = item.getFieldName(); // 태그 속성이 name
String value = item.getString("UTF-8");
out.println("일반 폼 필드 : " +name+ "-" +value);
}
//파일이라면
else {
String fileFieldName = item.getFieldName(); // 태그 속성이 name
String contentType = item.getContentType();
boolean isinMemory = item.isInMemory(); // 메모리상 할당되어 있다면 true.
long sizeInBytes = item.getSize(); //파일용량
fileName = item.getName();
fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
File file = new File(path +"/"+ fileName);
//파일이 이미 존재한다면
if(file.exists()) {
for(int i = 0; true; i++) {
file = new File(path +"/"+ "(" +i+ ")" + fileName);
//빠져나가는 경우(같은 파일이 존재하지 않는 경우)
if(!(file.exists()) == true) {
fileName = "(" +i+ ")" +fileName;
break;
}
}
}//if
item.write(file);
out.println("<br/>--------------------------------------------------------<br/>");
out.println("저장 파일 이름 : " +fileName+ "<br/>");
out.println("요청 피라미터 이름 : " +fileFieldName+ "<br/>");
out.println("요청 콘텐츠 유형 : " +contentType+ "<br/>");
out.println("파일 크기 : " +sizeInBytes+ "<br/>");
out.println("파일 경로 : " +path+ "<br/>");
}//else
}//while
}//if
%>
저장된 이미지
<img alt="사진" src="C://workspace-jsp//upload//<%=fileName %>">
</body>
</html>
이클립스 내장 웹으로 실행
웹스토어 이미지 업로드 추가 예제
부트스트랩 다운로드 4.5.3
getbootstrap.com/docs/4.5/getting-started/download/
Product.java -> dto 추가
package kr.gov.dto;
/*
* *자바 빈(bean)을 이요한 정보 조회
* 1.자바 빈
* 1) Java EE 프로그래밍시 여러 객체를 거치면서 만들어지는 데이터를 저장하거나 전달하는데 사용되는 클래스.
* 2) 자바의 DTO(Data Transfer Object, 데이터 전송 객체)클래스, VO(Value Object, 값객체) 클래스와
* 같은 개념.
* 2.자바 빈 특징
* 1) 속성의 접근 제한자는 private이다.
* 2) 각속성(attribute, property)은 각각의 setter/getter를 가진다.
* 3) 인자 없는 생성자를 반드시 가지며 다른 생성자도 추가할수 있다.
*/
//Product라는 클래스 => 자바빈의 객체가 되는 것.
public class Product {
private String productId; //상품 아이디
private String pname; //상품
private Integer unitprice; //상품가격
private String description; //상품 설명
private String menufecturer; //제조사
private String category; //분류
private long numberOfstock; //재고 수
private String condition; //신상품 or 중고품 or 재생품
private String filename; //제품이미지
public Product() {
}
//생성자 오버로드
public Product(String productId, String pname, Integer unitprice) {
super();
this.productId = productId;
this.pname = pname;
this.unitprice = unitprice;
}
//getter, setter
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Integer getUnitprice() {
return unitprice;
}
public void setUnitprice(Integer unitprice) {
this.unitprice = unitprice;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getMenufecturer() {
return menufecturer;
}
public void setMenufecturer(String menufecturer) {
this.menufecturer = menufecturer;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public long getNumberOfstock() {
return numberOfstock;
}
public void setNumberOfstock(long numberOfstock) {
this.numberOfstock = numberOfstock;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
}
ProductRepository.java -> dao 추가
package kr.gov.dao;
import java.util.ArrayList;
import kr.gov.dto.Product;
public class ProductRepository {
private ArrayList<Product> listOfProducts = new ArrayList<>();
//ProductRepository인스턴스를 하나만 공유하게끔 싱글톤 패턴 사용
private static ProductRepository instance = new ProductRepository();
// 생성, add 생성자
//ProductRepository인스턴스를 리턴하는 getter메서드
public static ProductRepository getInstance() {
return instance;
}
public ProductRepository() {
//DB 연동만 임시데이터로 활용
Product phone = new Product("iPhone13,4", "iPhone 12 Pro Max", 1490000);
phone.setDescription("6.7-unch, 2778*1284-pixel, OLED Super Retina XDR display, cameras");
phone.setCategory("Smart Phone");
phone.setMenufecturer("Apple");
phone.setUnitprice(1490000);
phone.setNumberOfstock(7000);
phone.setCondition("New");
phone.setFilename("iphone-12-pro-max-gold-hero.jpg");
Product notebook = new Product("15U70N-PA70K", "LG 울트라 기어", 1930000);
notebook.setDescription("15-unch, 1920*1080-pixel, IPS LED display, 10세대 인텔 코어 i7-10510U 프로세서");
notebook.setCategory("notebook");
notebook.setMenufecturer("LG");
notebook.setUnitprice(1930000);
notebook.setNumberOfstock(5000);
notebook.setCondition("Refurbished");
notebook.setFilename("usp_0103.jpg");
Product tablet = new Product("SM-T970NZKEKOO", "갤럭시 탭 S7+", 1149500);
tablet.setDescription("12-unch, 2800*1752-pixel, Super AMOLED display, Octa-Core 프로세서");
tablet.setCategory("Tablet");
tablet.setMenufecturer("SAMSUNG");
tablet.setUnitprice(1149500);
tablet.setNumberOfstock(3000);
tablet.setCondition("Old");
tablet.setFilename("b008b623-6fe8-4191-82bd-d988db87e6e6.jpg");
listOfProducts.add(phone);
listOfProducts.add(notebook);
listOfProducts.add(tablet);
}
//항목을 리턴해주는 객체 추가
public ArrayList<Product> getAllProducts() {
return listOfProducts;
}
//productId값을 받아서 리턴해주는 메서드
public Product getProductById(String productId) {
Product productById = null;
for(int i = 0; i<listOfProducts.size(); i++) {
Product product = listOfProducts.get(i);
if(productId != null && product.getProductId() != null &&
product.getProductId().equals(productId)) {
productById = product;
break;
}
}
return productById;
}
//상품을 추가하는 메서드
public void addProduct(Product product) {
listOfProducts.add(product);
}
}
products.jsp
<%@page import="kr.gov.dao.ProductRepository"%>
<%@page import="kr.gov.dto.Product"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.Calendar"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- <jsp:useBean id="productDAO" class="kr.gov.dao.ProductRepository" scope="session"/> --%>
<% request.setCharacterEncoding("UTF-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 목록</title>
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"> -->
<link rel="stylesheet" href="./resources/css/bootstrap.min.css">
</head>
<body>
<jsp:include page="menu.jsp"/>
<div class="jumbotron">
<div class="contaner">
<h1 class="display-3">상품 목록</h1>
</div>
</div>
<%
//싱글톤 객체사용
ProductRepository dao = ProductRepository.getInstance();
//상품목록 가져옴
ArrayList<Product> listOfProducts = dao.getAllProducts();
%>
<div class="container">
<div class="row" align="center">
<%
for(int i = 0; i<listOfProducts.size(); i++){
Product product = listOfProducts.get(i);
%>
<div class="col-md-4">
<!-- 경로를 지정해서 이미지를 출력 -->
<img alt="" src="C:/workspace-jsp/upload/<%=product.getFilename() %>">
<h3><%=product.getPname() %></h3>
<p><%=product.getDescription() %></p>
<p><%=product.getUnitprice() %>원</p>
<p><a href="./product.jsp?id=<%=product.getProductId() %>"
class="btn btn-secondary" role="button">상세 정보 »</a></p>
</div>
<%
}
%>
</div>
<hr>
</div>
<jsp:include page="footer.jsp"/>
</body>
</html>
product.jsp
<%@page import="kr.gov.dto.Product"%>
<%@page import="kr.gov.dao.ProductRepository"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%-- <jsp:useBean id="productDAO" class="kr.gov.dao.ProductRepository" scope="session"/> --%>
<% request.setCharacterEncoding("UTF-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 상세 정보</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css">
</head>
<body>
<jsp:include page="menu.jsp"/>
<div class="jumbotron">
<div class="contaner">
<h1 class="display-3">상품 정보</h1>
</div>
</div>
<%
//넘어온 상품 아이디값을 얻었다.
String id =request.getParameter("id");
ProductRepository dao = ProductRepository.getInstance();
//넘어온 상품아이디값을 이용해 실제 해당되는 Product객체를 얻음.
Product product = dao.getProductById(id);
%>
<div class="container">
<div class="row">
<div class="col-md-5">
<img alt="" src="C:/workspace-jsp/upload/<%=product.getFilename() %>" style="width:100%">
</div>
<div class="col-md-6">
<h3><%=product.getPname() %></h3>
<p><%=product.getDescription() %></p>
<p><b>상품 코드 :</b><span class="badge badge-danger" ><%=product.getProductId() %><span></b></p>
<p><b>제조사 : </b><%=product.getMenufecturer() %></p>
<p><b>분류 : </b><%=product.getCategory() %></p>
<p><b>제고 수 : </b><%=product.getNumberOfstock() %></p>
<h4><%=product.getUnitprice() %>원</h4>
<p><a href="addProduct.jsp" class="btn btn-info">상품 등록»</a></p>
<a href="./products.jsp" class="btn btn-secondary">상품 목록»</a>
</div>
</div>
<hr>
</div>
<jsp:include page="footer.jsp"/>
</body>
</html>
addProduct.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 등록</title>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css">
</head>
<body>
<jsp:include page="menu.jsp"/>
<!-- 점보트론 : 대형전광판이라는 의미. 점보트론 안에 다양한 컴포넌트(텍스트,이미지,회사로고 등) 포함 가능 -->
<div class="jumbotron">
<div class="contaner">
<h1 class="display-3">상품 등록</h1>
</div>
</div>
<div class="container">
<!-- class = "form-horizontal" : 폼요소들이 수평적으로 배치되도록 해주는 속성 -->
<form action="./processAddProduct.jsp" name="newProduct" class="form-horizontal"
method="post" enctype="multipart/form-data">
<div class="form-group row">
<!-- 화면크기 768px 이상일때 col-sm-?이 부분이 적용되고, div요소의 block특성에 의해
100%너비를 가지면 수직으로 쌓이게 만들어준다. -->
<label class="col-sm-2"><b>상품 코드</b></label>
<div class="col-sm-3">
<input type="text" name="productId" class="form-control" placeholder="상품코드를 입력하세요.">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"><b>상품명</b></label>
<div class="col-sm-3">
<input type="text" name="pname" class="form-control" placeholder="상품명를 입력하세요.">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"><b>가격</b></label>
<div class="col-sm-3">
<input type="text" name="unitprice" class="form-control" placeholder="가격을 입력하세요.">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"><b>상세 정보</b></label>
<div class="col-sm-5">
<textarea rows="2" cols="50" name="description" class="form-control"></textarea>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"><b>제조사</b></label>
<div class="col-sm-5">
<input type="text" name="menufecturer" class="form-control" placeholder="제조사를 입력하세요.">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"><b>분류</b></label>
<div class="col-sm-5">
<input type="text" name="category" class="form-control" placeholder="분류를 입력하세요.">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"><b>제고 수</b></label>
<div class="col-sm-5">
<input type="text" name="numberOfstock" class="form-control" placeholder="제고 수를 입력하세요.">
</div>
</div>
<div class="form-group row">
<label class="col-sm-2"><b>상태</b></label>
<div class="col-sm-5">
<input type="radio" name="condition" value="New">신규 제품
<input type="radio" name="condition" value="Old">중고 제품
<input type="radio" name="condition" value="Refurbished">재생 제품
</div>
</div>
<!-- 상품 이미지 업로드 부분 -->
<div class="form-group row">
<label class="col-sm-2"><b>이미지</b></label>
<div class="col-sm-5">
<input type="file" name="productImage" class="form-control">
</div>
</div>
<div class="form-group row">
<!-- offset지점은 col의 2만큼 띄움 -->
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" class="btn btn-primary" value="등록">
</div>
</div>
</form>
</div>
</body>
</html>
processAddProduct.jsp -> MultipartRequest적용 상세상품 이미지출력
<%@page import="java.util.Enumeration"%>
<%@page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy"%>
<%@page import="com.oreilly.servlet.MultipartRequest"%>
<%@page import="kr.gov.dto.Product"%>
<%@page import="kr.gov.dao.ProductRepository"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
//addProduct.jsp에서 사용자가 업로드한 이미지 부분을 받아저장.
String filename = "";
String realFolder = "C:\\workspace-jsp\\upload"; //웹 애플리케이션에서 절대경로
int maxsize = 100 * 1024 * 1024; //최대 업로드 크기
String encType = "UTF-8"; //인코딩 유형
MultipartRequest multi = new MultipartRequest(request, realFolder, maxsize,
encType, new DefaultFileRenamePolicy());
/* addProduct.jsp에서 사용자가 입력한 부분 받아서 저장 */
String productId = multi.getParameter("productId"); //상품 아이디
String pname = multi.getParameter("pname"); //상품
String unitprice = multi.getParameter("unitprice"); //상품가격
String description = multi.getParameter("description"); //상품 설명
String menufecturer = multi.getParameter("menufecturer"); //제조사
String category = multi.getParameter("category"); //분류
String numberOfstock = multi.getParameter("numberOfstock"); //재고 수
String condition = multi.getParameter("condition"); //신상품 or 중고품 or 재생품
Integer price;
long stock;
//단가 입력창에 미 입력시에
if(unitprice.isEmpty()){
price = 0; //오토박싱
}
else {
//String을 Integer로 변환
price = Integer.valueOf(unitprice);
}
if(numberOfstock.isEmpty()){
stock = 0;
}
else {
//String을 long타입으로 변환
stock = Long.valueOf(numberOfstock);
}
Enumeration files = multi.getFileNames();
String fname = (String)files.nextElement();
String fileName = multi.getFilesystemName(fname);
ProductRepository dao = ProductRepository.getInstance();
Product newProduct = new Product();
//Product 객체에 사용자가 입력한 내용을 저장
newProduct.setProductId(productId);
newProduct.setPname(pname);
newProduct.setUnitprice(price);
newProduct.setDescription(description);
newProduct.setMenufecturer(menufecturer);
newProduct.setCategory(category);
newProduct.setNumberOfstock(stock);
newProduct.setCondition(condition);
//이미지 저장 부분
newProduct.setFilename(fileName);
//Arraylist에 새상품을 추가
dao.addProduct(newProduct);
//페이지 이동시킴
response.sendRedirect("products.jsp");
%>