<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
종류
- <form:password> : 패스워드 필드 요소
- <form:form> : 폼 요소
- <form:input path="text"> : 테스트 필드. id="test" name="test"
- <form:textarea> : 텍스트 영역
- <form:checkbox> : 체크박스
- <form:checkboxes> : 여러개 체크박스
- <form:radiobutton> : 라디오 버튼
- <form:radiobuttons> : 여러 개의 라디오 버튼
- <form:select> : 셀렉트 박스
- <form:hidden> : 숨겨진 필드
- <form:label> : 라벨
- <form:button> :버튼
JSP
register2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<script type="text/javascript" src="/resources/js/jquery.min.js"></script>
<h2>파일업로드</h2>
<!-- spring form 태그 생성 -->
<!-- 필수! modelAttribute = "폼객체의 속성명(VO)" (mybatis) -->
<form:form action="/item/registerPost2" method="post" enctype="multipart/form-data"
modelAttribute="memberVO"> <!-- 폼 객체의 속성명을 addAttribute 속성에 지정 (같은 이름으로) -->
<!-- MemberVO의 객체의 memName과 연동 -->
<!-- path = memberVo의 프로퍼티명
폼 항목에 바인딩(메모리에 데이터가 올라감)되는 폼 객체의 프로퍼티를 지정함
disabled : 폼 항목을 비활성화 할 때 사용. 기본값 false
readonly : 폼 항목을 읽기 전용으로 만들 때 사용. 기본값 false -->
<p>아이디: <form:input path="memId" disabled="true"/>
<p>이름 : <form:input path="memName" readonly="true"/></p>
<input type="file" name="fileImage" />
<button type="submit">파일업로드</button>
</form:form>
JAVA
ItemController.java
package kr.or.ddit.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.sun.org.apache.bcel.internal.generic.NEW;
import kr.or.ddit.vo.MemberVO;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnailator;
@RequestMapping("/item")
@Slf4j
@Controller
public class ItemController {
@Autowired
String uploadFolder;
// // 파일 등록 폼
// @GetMapping("/register2")
// public String register2(Model model) {
// MemberVO mem = new MemberVO();
// mem.setMemName("오리");
// mem.setMemId("a001");
// model.addAttribute("memberVo", mem);
// return "item/register2";
// }
// 컨트롤러는 기본적으로 자바빈즈 규칙에 맞는 객체 VO는
// 다시 화면으로 폼객체를 전달함
// 폼 객체의 속성명은 직접 지정하지 않으면 폼 객체의 클래스명의
// 맨처음 문자를 소문자로 변환하여 처리함 (memberVO)
// 속성명 지정 @ModelAttribute("이름")
@GetMapping("/register2")
public String register2(@ModelAttribute("memberVO") MemberVO memberVO) {
memberVO.setMemName("오리");
memberVO.setMemId("a001");
memberVO.setMemRegno1("123123");
return "item/register2";
}
// disabled한 파라미터의 값은 전달되지않음
@PostMapping("/registerPost2")
public String registerPost2(@ModelAttribute("memberVO") MemberVO memberVO) {
MultipartFile fileImage = memberVO.getFileImage();
// 계획 ( 경로와 파일이름 )
log.info("memName : "+ memberVO.getMemName());
log.info("memId : "+memberVO.getMemId());
log.info("mem "+memberVO);
//MIME(Multipurpose Internet Mail Extensions)타입
/*
Multipurpose Internet Mail Extensions의 약자로 간단히 말하면
파일 변환을 의미한다.현재는 웹을 통해 여러 형태의 파일을 전달하는데 사용하고 있지만
이 용어가 생길 땐 이메일과 함께 동봉할 파일을 텍스트 문자로 전환해서 이메일 시스템을
통해 전달하기 위해 개발되어 Internet Mail Extensions라고 불리기 시작했다고 한다.
*/
log.info("filename : "+fileImage.getOriginalFilename());
log.info("contentType : "+fileImage.getContentType());
log.info("size : "+fileImage.getSize());
long size = fileImage.getSize();
File uploadFolder = new File(this.uploadFolder, getFolder());
if(!uploadFolder.exists()) {
uploadFolder.mkdirs();
}
// 같은날 같은 이미지 업로드 시 파일 중복 방지!!
UUID uuid = UUID.randomUUID();
String fileName = uuid.toString()+"_"+fileImage.getOriginalFilename();
File upload = new File(uploadFolder, fileName);
// 파일 복사 실행
// 파일객체.transferTo(계획)
try {
fileImage.transferTo(upload);
// 썸네일 처리
if(checkImageType(upload)) { // 이미지인 경우
FileOutputStream thumbnail = new FileOutputStream(new File(uploadFolder, "s_"+fileName));
// 라이브러리 사용 (파일 객체, 계획, 가로크기, 세로크기)
Thumbnailator.createThumbnail(fileImage.getInputStream(), thumbnail, 100, 100);
thumbnail.close();
}
} catch (IllegalStateException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "item/register2";
}
// 연 / 월 / 일 폴더 생성
public String getFolder() {
// 2024-08-06 형식(format)지정
// 간단한 날짜 형식
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date today = new Date();
String str = sdf.format(today);
// 2024-08-06 > 2024\\08\\06
return str.replace("-", File.separator);
}
public boolean checkImageType(File file) {
//MIME(Multipurpose Internet Mail Extensions) : 문서, 파일 또는 바이트 집합의 성격과 형식. 표준화
//MIME 타입 알아냄. .jpeg / .jpg의 MIME타입 : image/jpeg
String contentType;
try {
contentType = Files.probeContentType(file.toPath());
// image로 시작
return contentType.startsWith("image");
} catch (Exception e) {
// TODO: handle exception
log.error(e.getMessage());
}
return false;
}
}
경로 수정
root-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!--
root-context.xml : 스프링 설정 파일
서블릿과 필터가 공유할 수 있는 루트 스프링 컨테이너 설정으로,
공통 빈(Service, Repository(DAO), DB, Log 등)을 설정함.
공통빈을 설정하는 곳으로 주로 View 지원을 제외한 bean을 설정함
스프링 설정?
view와 관련되지 않은 객체를 정의
Service(기능), DAO(Repository : 저장소), DB등 비즈니스 로직과 관련된 설정
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName() = "oracle.jdbc.driver.OracleDriver";
-->
<!-- dataSource : 데이터베이스와 관련된 정보를 설정 -->
<!--
db : database(개념. 공유/저장/통합/운영). RDB(Relational DB.관계형DB)
dbms : database management system(DB관리시스템.오라클)
localhost=127.0.0.1=내ip주소
xe : express(OracleXE11g.r2) => SID(sequence ID)
-->
<bean id="uploadFolder" class="java.lang.String">
<constructor-arg value="C:\\Users\\PC-13\\git\\repository4\\springProj\\src\\main\\webapp\\resources\\upload"></constructor-arg>
</bean>
<bean id="uploadFolderDirect" class="java.lang.String">
<constructor-arg value="C:\\eGovFrameDev-3.10.0-64bit\\workspace\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\springProj\\resources\\upload"></constructor-arg>
</bean>
<!--
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe");
-->
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="oracle.jdbc.driver.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="username" value="jsptest" />
<property name="password" value="java" />
</bean>
<!-- 데이터베이스와 연결을 맺고 끊어질 때까지의
라이프 사이클을 관리해주는 sqlSession 객체를 생성
1) dataSource
2) 매퍼 xml의 위치 지정. / : src/main/resources/
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
-->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations"
value="classpath:/sqlmap/**/*_SQL.xml" />
<property name="configLocation"
value="/WEB-INF/mybatisAlias/mybatisAlias.xml" />
</bean>
<!-- 데이터베이스에 개별적으로 쿼리를 실행시키는 객체.
이 객체를 통해 query를 실행함
-->
<bean id="sqlSessionTemplate"
class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<!-- 파일업로드 설정
CommonsMultipartResolver multipartResolver = new multipartResolver();
multipartResolver.setMaxUploadSize(10485760);
multipartResolver.setDefaultEncoding("UTF-8");
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 파일업로드 용량 (10MB)-->
<property name="maxUploadSize" value="10485760"/>
<property name="defaultEncoding" value="UTF-8" />
</bean>
<!-- 파일업로드 디렉토리 설정 -->
<bean id="uploadPath" class="java.lang.String">
<constructor-arg value="c:\\upload"/>
</bean>
</beans>