Log4j 세팅
- https://mvnrepository.com/ 접속
- slf4j 검색
- 로그출력 라이브러리 (jdk 및 라이브러리 호출 정보)
- https://mvnrepository.com/artifact/org.slf4j/slf4j-api/2.0.17
- slf4j-log4j 검색
- java 또는 Controller, Model을 구현시 결과처리 정보를 기록
- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12/2.0.17
- jcl slf4j 검색
- 서버 오류 및 소켓통신, 포트통신일 경우 기록
- https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j/2.0.17
- pom.xml 에 붙이기
- 셋다 버전이 같이야함
- log4j 검색
- 로그를 콘솔에 출력
- 레거시형태인데 메이븐도 써도됨 간단한 형태
- https://mvnrepository.com/artifact/log4j/log4j/1.2.17
> 속성 수정 (runtime) 후 maven > update > force
<dependency> <!-- slf4j : 로그 출력 라이브러리 (jdk 및 라이브러리 호출 정보) -->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.17</version>
</dependency>
<dependency> <!-- java 또는 Controller, Model을 구현시 결과처리 정보를 기록 -->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>2.0.17</version>
<!-- <type>pom</type> <scope>test</scope> -->
<scope>runtime</scope> <!-- 실행시간동안 작동되게 함 -->
</dependency>
<dependency> <!-- 서버 오류 및 소켓통신, 포트통신일 경우 기록 -->
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>2.0.17</version>
<scope>runtime</scope> <!-- 실행시간동안 작동되게 함 -->
</dependency>
<dependency> <!-- 로그를 콘솔에 출력 -->
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>runtime</scope> <!-- 실행시간동안 작동되게 함 -->
</dependency>
- 컨트롤러에서 어노테이션으로 사용
- 뒤에 추가 속성 써서 사용하기
새로운 컨트롤러 추가
컨트롤러 추가시 webpage2.xml에 추가
<beans:bean class="spring_learning.mainpage3"></beans:bean>
컨트롤러 클래스 위에 컨트롤러 어노테이션 추가
@Controller
I/O 환경설정
Spring에서 I/O를 사용하기 위한 환경설정
webpage2.xml에 추가
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="defaultEncoding" value="uft-8"/>
<beans:property name="maxUploadSize" value="-1"/>
<beans:property name="maxInMemorySize" value="2097152"/>
</beans:bean>
- defaultEncoding : 파일명의 기본 언어셋
- maxUploadSize : 최대 업로드 파일 크기 (-1 : 무제한)
- 제한해두면 서버가 죽어버림 그래서 무조건 -1로 설정 -> 컨트롤러에서 핸들링
- maxInMemorySize : Tomcat에서 사용되는 메모리 사이즈 (파일 업로드시 작동되는 메모리양)
- 너무 크게 잡으면 메모리가 뻗어버림 2메가 정도면 적당
메모리 얼마나 잡아먹는지 보여주는거
프리퍼런스 >제너럴 > 쇼힙스테이터스
적용하면 하단에 보이게됨
파일 업로드 저장, 삭제 코드
file.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Spring으로 파일 전송</title>
</head>
<body>
<form id="frm" method="post" action="./fileok.do" enctype="multipart/form-data">
첨부파일 : <input type="file" name="mfile"><br>
<input type="button" value="전송" onclick="ok()">
</form>
<br><br><br>
<form id="frm2" method="post" action="./fileok2.do" enctype="multipart/form-data">
첨부파일 : <input type="file" name="mfile"><br>
첨부파일 : <input type="file" name="mfile"><br>
첨부파일 : <input type="file" name="mfile"><br>
<!--
첨부파일 멀티 : <input type="file" name="mfile" multiple="multiple"><br>
-->
<input type="button" value="전송" onclick="ok2()">
</form>
</body>
<script>
function ok(){
frm.submit();
}
function ok2(){
frm2.submit();
}
</script>
</html>
mainpage3.java (Controller)
package spring_learning;
import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
// I/O Controller
//원래 서블릿할땐 파일업로드용 어노테이션 썼었는데 지금은 commons-fileupload 라이브러리 불러와서 안써도 가능
@Controller
public class mainpage3 {
// MultipartFile : Spring I/O = xml 환경설정과 연결
@PostMapping("/fileok.do")
public String fileupload(MultipartFile mfile) {
if (mfile.getSize() > 2097152) {
System.out.println("test");
}
System.out.println(mfile.getOriginalFilename());
return "load";
}
// 여러개의 첨부파일을 받는 메소드 => 파일을 "배열"로 받기
/*
MultipartFile[] : Interface로 파일을 Front-end에서 받을 경우
반복문으로 처리시 multiple로 전송할 경우는 별도의 조건문 없이 저장이 가능
단, 같은 name으로 여러개의 파일전송 속성을 사용하였을 경우 반복문 사용시
조건문이 없을 경우 500 에러로 인하여 문제 발생함
FileCopyUtils.copy : 파일 전송 관련 I/O이며, Spring, Spring-boot에서 사용
*/
@PostMapping("/fileok2.do")
public String fileupok(MultipartFile[] mfile, HttpServletRequest req) throws Exception{
String url = req.getServletContext().getRealPath("/upload/");
// System.out.println(url);
// /Users/nayeong/Documents/projects/webspring/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/spring_learning/upload/
int w = 0;
while( w <mfile.length) {
//지금 프론트에서 멀티로 보낸게 아니라 따로 3개를 보내서 null이면 오류남
//=> 이 안에 null이 아닐때 파일카피유틸 사용하기
//멀티플로 보내면 에러 안남
//스프링 전용 갱장희 빠르게 저장하는 라이브러리 !
FileCopyUtils.copy(mfile[w].getBytes(), new File(url + mfile[w].getOriginalFilename()));
w++;
}
return "load";
}
/*
// DTO를 사용하여 여러개의 첨부파일을 받는 메소드 => 막코드
// 굳이 안씀 DTO로 받을수도있긴한데 다시 MultipartFile 써야해서 DTO 의미가 없음 => 막코드
@PostMapping("/fileok2.do")
public String fileupok(file_DTO dto) {
MultipartFile[] m = dto.getMfile(); // 이거 또써야됨 => 의미없음
System.out.println(m[0].getOriginalFilename());
return "load";
}
*/
//웹디렉토리에 있는 파일 리스트를 출력하는 Contoller
@GetMapping("/filelist.do")
public String filelist(HttpServletRequest req) throws Exception {
//웹 디렉토리 경로
String url = req.getServletContext().getRealPath("/upload/");
//웹 디렉토리에 저장되어있는 모든 파일명을 담는 클래스배열 (링크드로하면 개오래걸림)
File f = new File(url);
String f_list[] = f.list();
ArrayList<String> filenm = new ArrayList<String>(Arrays.asList(f_list));
req.setAttribute("filenm", filenm); //Model로 전달하면 좋은데 req로 전달함 (아직 jstl잘몰라서)
return null;
}
// 파일 삭제 메소드
/* 아래 메소드와 같음!
@PostMapping("/filedel.do")
public String filedel(String fnm) {
System.out.println(fnm);
return null;
}
*/
// @RequestParam : Front-end 전달된 값 request.getParameter()
@PostMapping("/filedel.do")
public String filedel(@RequestParam("fnm") String filenm, HttpServletRequest req, Model m) throws Exception {
// System.out.println(filenm);
String url = req.getServletContext().getRealPath("/upload/");
File f = new File(url + filenm);
f.delete(); //파일 삭제 메소드
//js 메세지를 작성 후 Model로 JSP로 전달을 하게 됨
String msg = "alert('정상적으로 삭제 되었습니다.');"
+ "location.href='./filelist.do';";
m.addAttribute("msg",msg);
return "load";
}
}
- MultipartFile[]
- Interface로 파일을 Front-end에서 받을 경우
반복문으로 처리시 multiple로 전송할 경우는 별도의 조건문 없이 저장이 가능 - 단, 같은 name으로 여러개의 파일전송 속성을 사용하였을 경우 반복문 사용시
조건문이 없을 경우 500 에러로 인하여 문제 발생함
- Interface로 파일을 Front-end에서 받을 경우
- FileCopyUtils.copy : 파일 전송 관련 I/O이며, Spring, Spring-boot에서 사용
filelist.jsp
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
ArrayList<String> filenm = (ArrayList)request.getAttribute("filenm");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>첨부파일 리스트</title>
</head>
<body>
<table border="1">
<tr>
<th>파일명</th>
<th>삭제</th>
</tr>
<%
int w = 0;
while(w < filenm.size()){
%>
<tr>
<td><%=filenm.get(w) %></td>
<td><input type="button" value="삭제"
onclick="file_del('<%=filenm.get(w) %>')"></td>
</tr>
<%
w++;
}
%>
</table>
<!-- 선택한 파일의 이름만 POST로 전송 -->
<form id="fm" method="post" action="./filedel.do">
<input type="hidden" name="fnm" value="">
</form>
</body>
<script>
function file_del(fnm) {
fm.fnm.value = fnm;
fm.submit();
}
</script>
</html>
load.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<script>
//Controller에서 Model로 전달된 값을 JSTL 변수 형태로 출력시키는 방식
${msg}
</script>