HTML폼 전송 방식
(1) enctype="application/x-www-form-urlencoded"
-> 폼데이터를 name=value&name=value...의 형태로 전송하라는 의미
-> HTML폼 데이터를 서버로 전송하는 가장 기본적인 방식
-> 별도로 enctype설정을 정의하지 않으면 request헤더에 application/x-www-form-urlencoded로 전송되었음이 추가
-> 입력한 데이터는 요청메시지의 body에 name=value&name=value...의 형식으로 전송
입력한 파라미터와 파라미터는 &기호로 구분된다.
<!-- 파일업로드 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<!--===============================파일업로드============================== -->
<beans:bean id="multipart" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="4000000"/>
</beans:bean>




@Controller
@RequestMapping("/board")
public class BoardController {
private BoardService service;
private FileUploadService fileuploadService;
@Autowired
public BoardController(BoardService service, FileUploadService fileuploadService) {
super();
this.service = service;
this.fileuploadService = fileuploadService;
}
@GetMapping("/write")
public String write() {
return "board/writepage";//뷰이름
}
//게시글등록을 위해 사용자가 입력한 내용과 첨부한 파일이 업로드되도록 처리
@PostMapping("/write")
public String insert(BoardDTO board, HttpSession session)
throws IllegalStateException, IOException {
System.out.println("파일업로드:"+board);
//1. MultipartFile 정보를 추출
List<MultipartFile> file = board.getFiles();
//2. 업로드될 서버의 실제 위치를 추출
// - 실제 서버에서 인식하는 업로드된 파일이 저장될 폴더의 경로를 추출하기
// - context내부에 있으므로 ServletContext객체를 잉ㅇ
// - ServletContext객체는 프로젝트(context)에 대한 정보를 담고 있는 객체이고
// 이 안에 실제 경로를 구할 수 있는 기능이 있음
// - ServletContext는 세션객체를 통해 생성
String path = WebUtils.getRealPath(session.getServletContext(), "/WEB-INF/upload");
System.out.println("^^^^^^"+path);
service.insert(board);
//3. 업로드 로직을 처리하는 서비스의 메소드를 호출
fileuploadService.uploadFiles(file, path);
return "redirect:/board/list?category=all";
}
}
@Service
public class FileUploadService {
public void uploadFiles(List<MultipartFile> multipartFiles, String path)
throws IllegalStateException, IOException {
for(MultipartFile multipartFile:multipartFiles) {
//파일명
String filename = multipartFile.getOriginalFilename();
//~~~~/WEB-INF/upload + / + 파일명
//-------------------
// path
multipartFile.transferTo(new File(path+File.separator+filename));
}
}
}




파일업로드갯수가 매번 다른데 넘어오는건 멀티파트 하나
동일한 파일명 덮어쓰는거 해결해야함
첨부되는 파일 정보는 게시글에 종속적임

파일테이블의 pk가 있어야 삭제/업데이트 등 가능

@Data
@AllArgsConstructor
@NoArgsConstructor
public class BoardFileDTO {
private String board_file_no;//식별할 수 있는 번호
private String board_no;//첨부된 파일이 어떤 게시글의 파일인지 구분하기 위한 게시글 번호(tbboard의 board_no로 fk)
private String originalFilename;//원본파일명
private String storeFilename;//실제저장될 파일명
}

파일업로드부분이 5개라서 첨부 안한부분은 빈파일됨

파일이 첨부하지않은건 업로드안되게 설정하기

BoardFileDTO 리스트로 반환하게 만들기


등록버튼 누르면 게시글 내용과 파일등록이 각각의 테이블에 등록되어야함






@Controller
@RequestMapping("/board")
public class BoardController {
private BoardService service;
private FileUploadService fileuploadService;
@Autowired
public BoardController(BoardService service, FileUploadService fileuploadService) {
super();
this.service = service;
this.fileuploadService = fileuploadService;
}
@GetMapping("/write")
public String write() {
return "board/writepage";//뷰이름
}
//게시글등록을 위해 사용자가 입력한 내용과 첨부한 파일이 업로드되도록 처리
@PostMapping("/write")
public String insert(BoardDTO board, HttpSession session)
throws IllegalStateException, IOException {
System.out.println("파일업로드:"+board);
//1. MultipartFile 정보를 추출
List<MultipartFile> file = board.getFiles();
//2. 업로드될 서버의 실제 위치를 추출
// - 실제 서버에서 인식하는 업로드된 파일이 저장될 폴더의 경로를 추출하기
// - context내부에 있으므로 ServletContext객체를 잉ㅇ
// - ServletContext객체는 프로젝트(context)에 대한 정보를 담고 있는 객체이고
// 이 안에 실제 경로를 구할 수 있는 기능이 있음
// - ServletContext는 세션객체를 통해 생성
String path = WebUtils.getRealPath(session.getServletContext(), "/WEB-INF/upload");
System.out.println("^^^^^^"+path);
//3. 업로드 로직을 처리하는 서비스의 메소드를 호출
List<BoardFileDTO> boardfiledtolist = fileuploadService.uploadFiles(file, path);
System.out.println(boardfiledtolist);
service.insert(board,boardfiledtolist);
return "redirect:/board/list?category=all";
}
}


public class TransactionBasicTest {
public static void main(String[] args) {
String url = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
String user = "erp";
String password = "erp";
String sql ="";
Connection con =null;
PreparedStatement ptmt =null;
boolean state = false;
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(url, user, password);
//con.setAutoCommit(false)로 정의하면 여기서부터 하나의 트랜잭션으로 처리가된다.
con.setAutoCommit(false);
sql = "insert into test values('15','111','111','111',1000,'111','002')";
ptmt = con.prepareStatement(sql);
ptmt.executeUpdate();
sql = "insert into test values('16','222','222','222',1000,'222','002')";
ptmt = con.prepareStatement(sql);
ptmt.executeUpdate();
sql = "insert into test values('17','333','333','333',1000,'333','002')";
ptmt = con.prepareStatement(sql);
ptmt.executeUpdate();
state = true;
}catch(ClassNotFoundException e){
System.out.println("오류발생");
}catch(SQLException e){
e.printStackTrace();
}finally{
try {
if(state) {
con.commit();//정상처리상태
}else {
con.rollback();//모든 작업을 취소
}
}catch(SQLException e){
e.printStackTrace();
}
}
}
}

보드파일시퀀스.넥스트발에서 보드파일넘버로 변경
시퀀스해서 넥스트발해서 증가시키고싶은데 Insert all 하면 쓸수없음. 그래서 빠른처리위해 일단 유효아이디로 처리
내부에서 ArrayList를 가지고 작업하는 경우 하나씩 꺼내서 file변수에 담아주는 것. el과 상관없이 마이바티스 내부에서 처리
-> 이 값들은 daoimpl에서 넘어오는 List가 하나씩 꺼내져서 file이라는 이름으로 액세스 할 수 있도록 마이바티스내부에서 처리
인서트안에 저장된갯수만큼 문장 만들어지는데
separator는 공백을 하나 주고 시작해서 이런식으로 코드가 만들어짐


https://blog.naver.com/heaves1/223446401203









@Controller
@RequestMapping("/member")
@SessionAttributes("user")
public class MemberController {
private MemberService service;
private DeptService deptservice;
private FileUploadService fileuploadService;
@Autowired
public MemberController(MemberService service, DeptService deptservice, FileUploadService fileuploadService) {
super();
this.service = service;
this.deptservice = deptservice;
this.fileuploadService = fileuploadService;
}
@GetMapping("/insert")
public String insert(Model model) {
//기존의 DeptServiceImpl의 셀렉트메소드를 호출해서 결과를 공유
List<DeptDTO> deptlist = deptservice.select();
model.addAttribute("deptlist",deptlist);
return "member/insert";
}
@PostMapping("/insert")
public String insertPage(MemberDTO member, HttpSession session)
throws IllegalStateException, IOException{
System.out.println(member);
//1. 파일업로드
MultipartFile file = member.getUserImage();
String path = WebUtils.getRealPath(session.getServletContext(), "/WEB-INF/upload");
String storeFilename = fileuploadService.uploadFile(file, path);
member.setProfile_photo(storeFilename);
member.setGender("0");
System.out.println(member);
//2.디비에 저장하기
service.insert(member);
return "member/insert";
}
}









본 포스팅은 멀티캠퍼스의 멀티잇 백엔드 개발(Java)의 교육을 수강하고 작성되었습니다.