중첩 커맨드객체란?
커맨드 객체 안에 커맨드 객체가 있는 형식
사용자가 HTTP로 사용자 데이터를 보내올 때 커맨드 객체를 여러 번 중첩시켜서 보낼 수 있다. 이 중첩 커맨드 객체는 VO에 List 형태로 데이터를 받을 수 있다. HTML 파일에서 데이터를 전송할 때 데이터의 name 속성은 아래처럼 커맨드 객체의 속성명과 인덱스 그리고 속성을 명시해야한다.
JSP
헤더 부분
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="cpath" value="${pageContext.request.contextPath }" />
------------------------------------
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<h3>DTO를 이용한 여러 파일 업로드</h3>
<form method="POST" enctype="multipart/form-data">
<p><input type="text" name="name" placeholder="이름"></p>
<p><input type="number" name="age" placeholder="나이"></p>
<p>
<label><input type="checkbox" name="color" value="red">빨강</label>
<label><input type="checkbox" name="color" value="green">초록</label>
<label><input type="checkbox" name="color" value="blue">파랑</label>
</p>
<p><input type="file" name="uploadFile" multiple></p>
<p><input type="submit"></p>
</form>
<table>
<tr>
<th>NAME</th>
<th>AGE</th>
<th>FILENAME</th>
<th>이미지태그</th>
</tr>
<c:forEach var="dto" items="${list }">
<tr>
<td>${dto.name }</td>
<td>${dto.age }</td>
<td>${dto.fileName }</td>
<td>
<!-- java의 if else -->
<!-- 문자열 분리 delims의 값(,)을 이용하여 분리 하여 name에 담음 -->
<c:choose>
<c:when test="${fn:contains(dto.fileName, ',') }">
<c:forTokens var="name" items="${dto.fileName }" delims=",">
<img src="${cpath }/upload/${name }" height="100">
</c:forTokens>
</c:when>
<c:otherwise>
<img src="${cpath }/upload/${dto.fileName }" height="150">
</c:otherwise>
</c:choose>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
새로운 개념
1. c:choose
- java의 switch case와 유사함.
- when(~~일 경우)
- otherwise(when이 모두 해당안될 경우 case)
2. function 태그
- jstl fuctions를 사용하겠다고 최 상단에 선언해야 함.
- 함수들은 단독으로 사용할 수 없고 EL표현식과 함께 사용해야 함.
- contains
- String이 substr을 포함하면 return true
3. c:forTokens
- 문자열을 분리자를 사용해서 출력한다.
- 분리자 : delims=" "
컨트롤러
package com.itbank.controller;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.itbank.model.Ex04DTO;
import com.itbank.service.FileService;
@Controller
@RequestMapping("/ex04")
public class EX04Controller {
@Autowired
private FileService fileService;
@GetMapping
public ModelAndView ex04() {
ModelAndView mav = new ModelAndView();
List<Ex04DTO> list = fileService.getLists();
mav.addObject("list", list);
return mav;
}
@PostMapping
public ModelAndView ex04(Ex04DTO dto) {
List<MultipartFile> list = dto.getUploadFile(); // dto에서 업로드 파일 목록을 가져와서
list.removeIf(file -> file.getSize() == 0); // 크기가 0인것은 모두 없앤다
dto.setUploadFile(list); // 수정된 리스트를 다시 dto에 세팅하고
System.out.println(dto); // dto를 출력
int row = fileService.uploadMultipleFile(dto);
System.out.println(row);
// 1) forEach를 이용하여 신규 리스트에 추가하기
// ArrayList<String> fileNameList = new ArrayList<String>();
// list.forEach(f -> fileNameList.add(f.getOriginalFilename()));
// System.out.println(fileNameList);
// 2) stream().map() 을 이용하여 특정 속성만 남기기
// List<String> fileNameList = list.stream()
// .map(f -> f.getOriginalFilename())
// .collect(Collectors.toList());
// System.out.println(fileNameList);
ModelAndView mav = new ModelAndView("redirect:/ex04");
return mav;
}
}
service
package com.itbank.service;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.itbank.model.Ex03DTO;
import com.itbank.model.Ex04DTO;
import com.itbank.repository.UploadDAO;
@Service
public class FileService {
@Autowired private UploadDAO dao;
private final String saveDirectory = "D:\\upload_2023";
public FileService() {
File dir = new File(saveDirectory);
if(dir.exists() == false) {
dir.mkdirs();
}
}
public List<Ex04DTO> getLists() {
return dao.selectAlls();
}
public int uploadMultipleFile(Ex04DTO dto) {
int row = 0;
// 문자열을 특정 글자로 구분하여 저장하기
String fileName = "";
for(MultipartFile f : dto.getUploadFile()) {
row += upload(f);
fileName += f.getOriginalFilename();
fileName += ",";
}
fileName = fileName.substring(0, fileName.lastIndexOf(","));
dto.setFileName(fileName);
System.out.println(fileName);
row = dao.insertEx04DTO(dto);
return row;
}
DTO
package com.itbank.model;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
public class Ex04DTO {
private String name;
private int age;
private List<String> color;
private List<MultipartFile> uploadFile;
private String fileName;
@Override
public String toString() {
String str = String.format("%s, %d살, ", name, age);
// String colors = "";
// for(int i = 0; color != null && i < color.length; i++) {
// colors += color[i];
// colors += (i != color.length - 1) ? ", " : "\n";
// }
// str += colors;
str += color;
str += "\nuploadFile : " + uploadFile;
return str;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<String> getColor() {
return color;
}
public void setColor(List<String> color) {
this.color = color;
}
public List<MultipartFile> getUploadFile() {
return uploadFile;
}
public void setUploadFile(List<MultipartFile> uploadFile) {
this.uploadFile = uploadFile;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
다중으로 올릴 수 있어야 하므로 자바빈즈는의 자료형이 리스트가 되야 한다.(배열도 가능하나 리스트가 더 편함)
'개발자 > Spring' 카테고리의 다른 글
url 유효기간 설정_세션동작방식 (0) | 2023.07.13 |
---|---|
[SPRING] Interceptor의 의미와 구현 및 실습 (0) | 2023.01.10 |
[SPRING] spring으로 파일 업로드 구현 (0) | 2023.01.03 |
[SPRING] 간단하게 홈 컨트롤러 대체하기(GET,POST 방식으로 구분하지 않을때) (0) | 2023.01.03 |
[SPRING] 도서 CRUD 구현 + 검색기능까지 (0) | 2022.12.30 |