form ํ๊ทธ์์ ์ธ์ฝ๋ฉ ๋ฐฉ์์ ํน๋ณํ ์ง์ ํ์ง ์๋๋ค๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก POST ๋ฐฉ์์ผ๋ก "uid=newlec&name=dragon"์ฒ๋ผ &๋ก ๊ตฌ๋ถ๋ "ํค=๊ฐ"์ด ์ ์ก๋๋ค. url์ ์ฌ์ฉ๋๋ ์ฟผ๋ฆฌ์คํธ๋ง๊ณผ ๊ฐ์ ํ์์ด๋ค. ๋ฌธ์์ด๋ง ๋ณด๋ผ ๋๋ ์ด๋ฌํ ๋ฐฉ์์ผ๋ก ๋ณด๋ด๋ ๋์ง๋ง ๋ฐ์ด๋๋ฆฌ ๊ฐ์ ๋ณด๋ผ ๋ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ฏ๋ก ํด๋ผ์ด์ธํธ์์ ์ธ์ฝ๋ฉ ๋ฐฉ์์ ๋ฌ๋ฆฌํด์ผ ํ๋ค. (=>multipart)
multipart ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ์ ๊ทธ๋ฆผ์ฒ๋ผ ํํธ๋ฅผ ๋๋์ด์ ์ ์กํ๊ฒ ๋๋ค. (์ฒซ ๋ฒ์งธ ํํธ๋ uid, ๋ ๋ฒ์งธ ํํธ๋ name, ์ธ ๋ฒ์งธ ํํธ๋ file...)
ํด๋ผ์ด์ธํธ์์ ๊ฐ์ ์ ์กํ ๋์ ๊ธฐ๋ณธ ๋ฐฉ์์ด application/x-www-form-urlencoded ์ด๋ผ์ multipart ๋ฐฉ์์ ์ค์ ํด์ผ ํ๋ ๊ฒ์ฒ๋ผ, ์๋ฒ์์๋ multipart ๋ฐฉ์์ ๋ฐ๊ธฐ ์ํด์๋ ๋ ๋ค๋ฅธ ์ค์ ์ด ํ์ํ๋ค.
servlet-context.xml
<!-- ํ์ผ ์
๋ก๋๋ฅผ ์ํ multipart ์ค์ -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size 300MB(1024-1024*300) -->
<property name="maxUploadSize" value="314572800"></property>
</bean>
์๋ธ๋ฆฟ ์ค์ ์ CommonsMultipartResolver๋ฅผ ์ถ๊ฐํ๋ค.
- setMaxUploadSize : ์ ์ฒด ํ์ผ ์ฌ์ด์ฆ์ ์ต๋ ์ฌ์ด์ฆ
- setMaxUploadSizePerFile : ์ ๋ก๋ํ๋ ํ์ผ ํ๋ ๋น ์ต๋ ์ฌ์ด์ฆ
- setDefaultEncoding์ ํ์ง ์์๋ ๋จ. (ํํฐ๋ฅผ ์ฌ์ฉํด ์ธ์ฝ๋ฉ์ ์ง์ ํ๊ธฐ ๋๋ฌธ)
1024byte=1KB ์ด๊ณ 1024byte*1024byte=1MB, ๋ฐ๋ผ์ 1024*1024*300์ 300MB์ด๋ค. 300MB๋ฅผ ์ต๋ ์ฌ์ด์ฆ๋ก ํ๊ธฐ ์ํด value์ 314572800์ ๊ฐ์ ๋ฃ์๋ค.
reg1.html
<form action="reg" method="post" enctype="multipart/form-data">
<!-- ์ดํ ์๋ต -->
form ํ๊ทธ์ enctype="multipart/form-data" ์ค์ ์ ์ถ๊ฐํ๋ค. (๋ํดํธ๋ application/x-www-form-urlencoded)
NoticeController.java
@RequestMapping("reg")
@ResponseBody
public String reg(String title, String content, MultipartFile file, String category, String[] foods, String food) {
String fileName = file.getOriginalFilename();
long fileSize = file.getSize();
System.out.printf("fileName:%s, fileSize:%d\n", fileName, fileSize);
for(String f : foods) {
System.out.println(f);
}
return String.format("title:%s, content:%s<br>category:%s, food:%s", title, content, category, food);
}
MultipartFile ํ์ ์ผ๋ก file์ ๋ฐ์์จ๋ค.
- getOriginalFilename : ํ์ผ์ ์ ์ฅ๋ช .ํ์ฅ์ (ex. img1.png)
- getSize : ํ์ผ์ ์ฌ์ด์ฆ (ex. 2881) => ๋ฐ์ดํธ๋ฅผ ์๋ฏธ
pom.xml
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
commons-fileupload ๋ํ๋์๋ฅผ ์ถ๊ฐํ๋ค.
์คํํ๊ณ ๋ทฐ ํ์ด์ง์์ ํ์ผ์ ์ฒจ๋ถํ์ฌ submit ํ๋ฉด ํ์ผ ์ด๋ฆ๊ณผ ์ฌ์ด์ฆ๊ฐ ์ถ๋ ฅ๋๋ค.
* ๋ฌผ๋ฆฌ ๊ฒฝ๋ก ์ป๊ธฐ์ ํ์ผ ์ ์ฅํ๊ธฐ
์ ๋ฌ๋ฐ์ ํ์ผ์ ๋๋ ํ ๋ฆฌ์ ์ ์ฅํ๊ณ ์ ํ ๋๋ ๊ฒฝ๋ก ๋๋ ํ ๋ฆฌ๋ฅผ ์ง์ ํ๊ณ ๊ทธ๊ณณ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ฉด ๋๋ค. ํ ๋๋ ํ ๋ฆฌ๋ฅผ ์์๋ด์ ํด๋น ๊ฒฝ๋ก์ ์ ์ฅํด์ผ ํ๋๋ฐ, ๊ฐ๋ฐํ ๋์ ๊ฒฝ๋ก์ ๊ฐ๋ฐ ํ ์๋ฒ ๋ฐฐํฌํ์ ๋์ ๊ฒฝ๋ก๊ฐ ๋ค๋ฅผ ์ ์๋ค(๊ฐ๋ฐ PC์ ์๋ฒ PC๊ฐ ๋ค๋ฅผ ๊ฐ๋ฅ์ฑ์ด ๋งค์ฐ ํฌ๊ธฐ ๋๋ฌธ). ๋ฐ๋ผ์ ํ์ผ ์ ๋ก๋์ ์ ์ฅ ์์ ๊ฒฝ๋ก๋ฅผ ๋์ ์ผ๋ก ์์๋ด๋ ์์ ์ด ํ์ํ๋ค.
ServletContext๋ฅผ ์ป์ด์ ์ ๋ ๊ฒฝ๋ก๋ฅผ ์ป์ด๋ผ ์๋ ์๊ณ , HttpServletRequest๋ฅผ ํตํด ์ ๋ ๊ฒฝ๋ก๋ฅผ ์ป์ด๋ผ ์๋ ์๋ค. ๊ฒฝ๋ก๋ฅผ ์ป์ด๋ธ ํ์๋ ํ์ผ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ ์ ์กํ๋ฉด ๋๋ค.
NoticeController.java
@Controller("adminNoticeController")
@RequestMapping("/admin/board/notice/")
public class NoticeController {
@Autowired
private ServletContext ctx;
@RequestMapping("reg")
@ResponseBody
public String reg(String title, String content, MultipartFile file, String category, String[] foods, String food, HttpServletRequest request) {
//ํ์ผ ์
๋ก๋
String fileName = file.getOriginalFilename();
long fileSize = file.getSize();
System.out.printf("fileName:%s, fileSize:%d\n", fileName, fileSize);
//webapp/static/upload ํด๋ ์์ ํ์ผ์ ์ ์ฅํ ๊ฒ์ด๋ค.
//ํด๋์ ์ ๋๊ฒฝ๋ก(D:.....)๋ฅผ ์ฐ์ง ์๊ณ (๊ฐ๋ฐpc์ ์ด์์๋ฒpc์ ๊ฒฝ๋ก๊ฐ ์ผ๋ฐ์ ์ผ๋ก ๋ค๋ฅด๊ธฐ ๋๋ฌธ)
// ServletContext ctx = request.getServletContext(); //=>์ด๋ ๊ฒ ํด๋ ๋จ. ์ฌ๊ธฐ์ ํ๋๋ก ์ ์ธํจ.
String webPath = "/static/upload";
String realPath = ctx.getRealPath(webPath);
System.out.printf("realPath: %s\n", realPath);
File savePath = new File(realPath); //์ ์ฅ ๊ฒฝ๋ก์ธ realPath
//์
๋ก๋ ํ๊ธฐ ์ํ ๊ฒฝ๋ก๊ฐ ์์ ๊ฒฝ์ฐ์๋ ๊ทธ ๊ฒฝ๋ก๋ฅผ ์ง์ ์์ฑํ๊ฒ ํจ
//exists() : ๊ฒฝ๋ก๊ฐ ์กด์ฌํ๋์ง ์๋์ง ๋ฐํ(boolean)
if(!savePath.exists()) {
savePath.mkdirs(); //๊ฒฝ๋ก๊ฐ ์๋ค๋ฉด, ๋๋ ํ ๋ฆฌ ์์ฑ
/*
mkdir : ๋งจ ๋ ๊ฒฝ๋ก ํ๋๋ง ์์ฑ
mkdirs : ์ค๊ฐ ๊ฒฝ๋ก๋ถํฐ ์์ผ๋ฉด ์ ๋ถ ์์ฑ
*/
}
realPath += File.separator + fileName;
//realPath ๋ค์ ์ญ์ฌ๋์(\)๊ฐ ๋ถ๊ณ ํ์ผ ์ด๋ฆ์ด ๋ํด์ ธ์ผ ํ๋๋ฐ,
//์๋์ฐ๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ๊ตฌ๋ถ์๊ฐ ์ญ์ฌ๋์๊ฐ ์๋ ์ ์์.
//separator๋ ํ์ฌ ์์คํ
์ ๋ง๊ฒ ๊ตฌ๋ถ์๋ฅผ ๋ง๋ค์ด์ฃผ๋ ์ญํ ์ ํจ
File saveFile = new File(realPath); //ํ์ผ ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค. => ๊ป๋ฐ๊ธฐํ์ผ(๊ฒฝ๋ก+ํ์ผ๋ช
)
file.transferTo(saveFile); //์
๋ก๋ํ ํ์ผ ๋ฐ์ดํฐ์ '๊ฒฝ๋ก+ํ์ผ๋ช
' ๊ป๋ฐ๊ธฐ๋ฅผ ์
ํ๋ค.
}
}
์ ๋ก๋ํ ํ์ผ์ ์ ์ฅํ upload ํด๋๋ฅผ static ํด๋ ์์ ์์ฑํ๋ค. ๋จผ์ HttpServletRequest๋ฅผ ํตํด ์ ๋ ๊ฒฝ๋ก๋ฅผ ์์๋ด๊ธฐ ์ํด ๋ฉ์๋์์ HttpServletRequest ๊ฐ์ฒด๋ฅผ ์ป์ด์จ๋ค.
"/static/upload"๋ฅผ web path๋ก ์ง์ ํ๊ณ , ServletContext์ getRealPath๋ฅผ ์ด์ฉํ๋ฉด ๊ทธ ๊ฒฝ๋ก๋ฅผ ํตํด ์ ๋ ๊ฒฝ๋ก ๊ฐ์ ์ป์ด์ฌ ์ ์๋ค. ServletContext๋ ๋ฉ์๋ ์์์ request๋ฅผ ์ด์ฉํด ๋ฐ์์ฌ ์๋ ์์ง๋ง ํนํ ์ ์ญ์ ์ผ๋ก ์ฌ์ฉํ๋ค๋ฉด ํ๋์ ์ ์ธํ์ฌ ์ฃผ์ ํด๋ ๋๋ค. (์ด ๊ฒฝ์ฐ HttpServletRequest request ์์ด๋ ๋จ)
์คํ๋ง์ ServletContext ๊ฐ์ฒด๋ฅผ IoC ์ปจํ ์ด๋์ ๋ด์๋๊ณ ์๊ธฐ ๋๋ฌธ์ @Autowired๋ฅผ ์ด์ฉํด ๊บผ๋ด ์ธ ์ ์๋ค.
์ฝ์ ์ถ๋ ฅ๊ฐ (real path)
realPath: D:\....workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\webprj\static\upload |
์ํฌ์คํ์ด์ค์ .metadata ํด๋ ์์ ์ค์ ์ ์ฅ ๊ฒฝ๋ก๊ฐ ์์ฑ๋์ด ์๋ค. ํ์ผ ์ ๋ก๋ ์ ์ด ๊ฒฝ๋ก์ ํ์ผ์ ์ ์ฅํ๊ฒ ๋๋ค.
realPath๋ฅผ ์ ์ฅํ ๊ป๋ฐ๊ธฐ ํ์ผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. (File savePath = new File(realPath);)
์ด ๊ฒฝ๋ก ํด๋๊ฐ ์์ ๋ ๋ฐ์๋๋ ์๋ฌ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด์ ๊ฒฝ๋ก๊ฐ ์๋์ง ๊ฒ์ฌ ํ์ ์์ผ๋ฉด ๋๋ ํ ๋ฆฌ๋ฅผ ์์ฑํ๊ฒ ํ๋ ์กฐ๊ฑด๋ฌธ์ ๊ฑฐ์น๊ฒ ํ๋ค.
๊ทธ ํ์๋ realPath์ ๊ตฌ๋ถ์(File.separator)์ ํ์ผ๋ช (fileName)์ ๋ํด ์ ์ฅํ๋ค. ์ญ์ฌ๋์๋ฅผ ์ถ๊ฐํ์ง ์๊ณ separator๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋, ์๋์ฐ๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ์ญ์ฌ๋์๊ฐ ์๋๋ผ ์ฌ๋์๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค. separator๋ฅผ ์ฌ์ฉํ๋ฉด ์์คํ ํ๊ฒฝ์ ๋ง๋ ๊ตฌ๋ถ์๋ฅผ ๋ฃ์ด์ฃผ๋ ์ญํ ์ ํ๋ค.
๊ทธ ํ ๊ฒฝ๋ก+ํ์ผ๋ช ์ด ๋ํด์ง realPath๋ก ํ์ผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ฐ, ์ด๋ ๊ป๋ฐ๊ธฐ ํ์ผ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค. transferTo๋ฅผ ์ด์ฉํด์, form ํ์ผ์์ ๋์ด์จ ๋ฐ์ดํฐ์ธ file์ ๊ป๋ฐ๊ธฐ๋ฅผ ์ ํ์ ์ ์ฅํ๋ค.
* ๋ค์ค ํ์ผ ์ ๋ก๋
๋ช ๊ฐ์ง ์ฌํญ๋ง ๋ฐ๊พธ๋ฉด ๋ค์ค ํ์ผ ์ ๋ก๋๋ฅผ ๊ฐ๋จํ ๊ตฌํํ ์ ์๋ค.
reg1.html
<tr>
<th>์ฒจ๋ถํ์ผ</th>
<td colspan="3" class="text-align-left text-indent"><input type="file" name="files" /> </td>
</tr>
<tr>
<th>์ฒจ๋ถํ์ผ</th>
<td colspan="3" class="text-align-left text-indent"><input type="file" name="files" /> </td>
</tr>
input type="file"์ ํ๋ ๋ ์ถ๊ฐํ๊ณ , ๋ค์ค ํ์ผ ์ ๋ก๋์ด๋ฏ๋ก name์ files๋ก ์์ ํ์๋ค. ๊ฐ์ name์ผ๋ก ์ฌ๋ฌ๊ฐ์ ๊ฐ์ด ์ ๋ฌ๋๋ฉด ๋ฐฐ์ด๋ก ๋ฐ์ ์ ์๋ค.
NoticeController.java
@RequestMapping("reg")
@ResponseBody
public String reg(String title, String content, MultipartFile[] files, String category, String[] foods, String food/*, HttpServletRequest request*/) throws IllegalStateException, IOException {
for(MultipartFile file : files) {
String fileName = file.getOriginalFilename();
long fileSize = file.getSize();
System.out.printf("fileName:%s, fileSize:%d\n", fileName, fileSize);
String webPath = "/static/upload";
String realPath = ctx.getRealPath(webPath);
System.out.printf("realPath: %s\n", realPath);
File savePath = new File(realPath);
if(!savePath.exists()) { //๊ฒฝ๋ก๊ฐ ์๋ค๋ฉด
savePath.mkdirs(); //๋๋ ํ ๋ฆฌ ์์ฑํ๋ค.
}
realPath += File.separator + fileName; //realPath ๋ค์ ์ญ์ฌ๋์(\)๊ฐ ๋ถ๊ณ ํ์ผ ์ด๋ฆ์ด ๋ํด์ ธ์ผ ํ๋๋ฐ, ์๋์ฐ๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ๊ตฌ๋ถ์๊ฐ ์ญ์ฌ๋์๊ฐ ์๋ ์ ์์. separator๋ ํ์ฌ ์์คํ
์ ๋ง๊ฒ ๊ตฌ๋ถ์๋ฅผ ๋ง๋ค์ด์ฃผ๋ ์ญํ ์ ํจ
File saveFile = new File(realPath); //ํ์ผ ๊ฐ์ฒด๋ฅผ ๋ง๋ ๋ค. (๊ฒฝ๋ก+ํ์ผ๋ช
) => ๊ป๋ฐ๊ธฐ ํ์ผ
file.transferTo(saveFile); //์
๋ก๋ํ ํ์ผ ๋ฐ์ดํฐ๋ฅผ ์ง์ ํ ํ์ผ์ ์ ์ฅ. ์์์ ๋ง๋ ๊ป๋ฐ๊ธฐ ํ์ผ saveFile์ ์
ํ๋ค.
}
return String.format("title:%s, content:%s<br>category:%s, food:%s", title, content, category, food);
}
์ป์ด์ค๋ MultipartFile ๊ฐ์ฒด๋ฅผ ๋ฐฐ์ด๋ก ๋ฐ๊พธ๊ณ ๋ณ์๋ช ์ files์ผ๋ก ์ค์ ํ๋ค. (MultipartFile[] files)
์ฌ๋ฌ ํ์ผ์ ๋ํด์ ํ๋์ฉ ์ ์ฅํ ์ ์๊ฒ for each๋ฌธ์ ์ฌ์ฉํ๋ค.
'๐ปStudy > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
POST ์ ๋ ฅ (ํ ์คํธ๋ฐ์ค, ์ฝค๋ณด๋ฐ์ค, ์ฒดํฌ๋ฐ์ค, ๋ผ๋์ค๋ฒํผ) / ํํฐ๋ฅผ ์ด์ฉํ ํ๊ธ ์ธ์ฝ๋ฉ (0) | 2021.03.04 |
---|---|
์ ๋ ฅ์ ์ข ๋ฅ / QueryString ์ ๋ ฅ (0) | 2021.03.04 |
๋ฐ์ดํฐ ํํ / JSON ์ถ๋ ฅํ๊ธฐ (0) | 2021.03.03 |
@RestController์ ํ๊ธ ์ถ๋ ฅ ์ค์ (0) | 2021.03.03 |
๋ฌธ์ ์ถ๋ ฅ ๋ฐฉ๋ฒ 4๊ฐ์ง, @ResponseBody (0) | 2021.03.03 |