이미지 업로드, MultipartFile

0

Spring

목록 보기
16/23

기본 설정

@PostMapping("write")
	public ResponseEntity<?> write(HttpSession session, //String boardTitle, String boardContent, // 두개의 매개변수를 Board 객체로 
			Board board, MultipartFile f1, List<MultipartFile> f2 
// 이미지 파일을 올리기 위해서 MultipartFile 이용/ 여러개를 올리고 싶다면  
// 프론트에서 전달을 할때 <input type="file" name ="f1"> <input type="file" name="f2" multiple> -> multiple 형태로 같은 이름의 여러개의 이미지
// 보내려면 list로 선언, 보내려는 이미지파일들의 속성이 같지 않다면 기본 선언  
			) throws AddException {	
}
  • pom.xml에 설정 후
<!-- 아파치 이미지 파일 업로드 -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
  • 빈으로 등록 - 비즈니스로직과 관련 없으므로 myServletContext.xml에 정의
	<!-- 파일 업로드용  -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="defaultEncoding" value="UTF-8"/>
		<property name="maxUploadSize" value="102400"/> <!-- 업로드되는 파일의 total size -->
		<property name="maxUploadSizePerFile" value="10240"/> <!-- 업로드 되는 파일 한개 단위의 max size -->
	</bean>

코드

	@PostMapping("write")
	public ResponseEntity<?> write(HttpSession session, //String boardTitle, String boardContent, // 두개의 매개변수를 Board 객체로 
			Board board, MultipartFile f1, List<MultipartFile> f2 // 이미지 파일을 올리기 위해서 MultipartFile 이용/ 여러개를 올리고 싶다면  
			// 프론트에서 전달을 할때 <input type="file" name ="f1"> <input type="file" name="f2" multiple> -> multiple 형태로 같은 이름의 여러개의 이미지
			// 보내려면 list로 선언, 보내려는 이미지파일들의 속성이 같지 않다면 기본 선언  
			) throws AddException {
		if(f1 != null) { //첨부파일 f1이 전달 된 경우. f1은 안넣고 f2만 받아올경우 f1에서 NullException뜸 
		long f1Size = f1.getSize(); // 첨부된파일의 사이즈 알아내기 
		String f1Origin = f1.getOriginalFilename();
		System.out.println("---f1---");
		System.out.println("f1Size" + f1Size + ", f1Origin : " + f1Origin);
		}
		System.out.println("--f2--"); // list는 전달이 안될 경우 list가 비어있을 뿐임. 작동은 함 
		for(MultipartFile mf : f2) {
			long mfSize = mf.getSize();
			String mfOrigin = mf.getOriginalFilename();
			System.out.println("mfSize" + mfSize + ", mfOrigin : " + mfOrigin);
		}
//		service.write(board);
		return new ResponseEntity<>(HttpStatus.OK);
	}
  • 첨부파일 f1이 없다면 NullPointerException이 뜨지만,
  • 첨부파일 f2가 없다면 list는 만들어 지지만, list안에 요소가 없는 것이고 NullPointerException은 뜨지 않음!!
  • 넣으려는 첨부파일의 크기가 지정한 maxSize를 넘으면(SizeLimitExceededException), 파라미터로 전달 될 때 에러가 발생하기 때문에 코드로 처리할 수가 없음. 컨테이너에 예외를 전달함.-> controllerAdvice가 이를 감지한다. -> 처리 코드를 advice에 작성
	@ExceptionHandler(MaxUploadSizeExceededException.class)
	@ResponseBody
	public ResponseEntity<?> exceptMaxUploadSize(MaxUploadSizeExceededException e) {
		org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders(); // 메시지 한글깨짐 방지 
		headers.add("Content-Type", "application/json;charset=UTF-8");
		headers.add("Access-Control-Allow-Origin", "http://192.168.0.14:5500"); // myServletContext에 설정한 cors는 controller에 관한 세팅. advice에는 적용되지 않으므로 따로 넣어줘야함.
		headers.add("Access-Control-Allow-Origin-Credentials", "true"); // controller까지 못들어가고 생기는 오류이기 때문에 설정해줘야 한다.
		return new ResponseEntity<>("파일크기가 너무 큽니다.", headers, HttpStatus.BAD_REQUEST);
	   }
	}

↳ 메서드 내부에서 try-catch로만 처리하는 것이 아니라 Handler Apdapter에서 예외가 났을 경우 Advice의 도움을 받을 수 있다.!!

  • 일반 컨트롤러(GET,POSTMAPPING)라면 produces로 응답형식을 지정해주면 되지만, 일반 컨트롤러가 아닌 advice이기 때문에 직접 header를 설정해서 응답할때 같이 보내줘야 한다.
  • 파일 업로드시, CORS에러가 난다..!
    • 이미 myServletContext.xml에 CORS설정을 해줬지만 이는 controller의 cors를 설정해주는 것이고 이는 method에 들어가기 전에 발생하는 오류이므로 header에 따로 추가해줘야한다.

글 작성중 오류

Caused by: org.apache.ibatis.type.TypeException: Error setting null for parameter #1 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 부적합한 열 유형: 1111

  • 자바객체인 board_num은 board_seq.NEXTVAL로 채워짐
  • 자바객체로 쓰이는 null을 db쪽에서는 어떤 자료형으로 바라볼 것이냐.
  • 자바에서는 숫자자료형은 기본형 int 또는 Integer가 있음 -> db쪽(오라클)으로 오면 NUMBER 자료형이 됨
    String -> VARCHAR2, CHAR
  • 자바에서의 null은 오라클에서 어떤 자료형으로 매핑할 것이니? 라고 마이바티스가 물어보는 것
    • null은 null로 들어가도록 세팅 해줘야함.
<!-- config.xml -->
<setting name="jdbcTypeForNull" value="NULL"/>

추가해주기.!

  • 자바에서의 null값은 DB에서도 무조건 null로 처리해줘라~~
  • fk에 not null설정을 안하면 null값이 들어갈 수 있음.

갑자기 db에러, 메모리누수가 나는 이유?

  • commit 안했거나
  • session.close() 안했거나!
    • connection풀로 돌아가지 않아서. 주의~
profile
백엔드를 공부하고 있습니다.

0개의 댓글