user.service
UserService.java (Interface)
ObjectStorageService.java(Interface)
user.service.impl
UserServiceImpl.java
NCPObjectStorage.java
package user.service.impl;
import org.springframework.stereotype.Service;
import user.service.ObjectStorageService;
@Service
public class NCPObjectStorage implements ObjectStorageService {
}
spring
mybatis-config.xml ====> 제거
db.properties
navar.properties
ncp.accessKey=
ncp.secretKey=
ncp.regionName=kr-standard
ncp.endPoint=https://kr.object.ncloudstorage.com
UserUploadController.java
//imageFileName = UUID.randomUUID().toString(); 주석걸기
@Autowired
private ObjectStorageService objectStorageService;
private String bucketName = "bitcamp-9th-bucket-132";
//네이버 클라우드 Object Storage-------------------------------
imageFileName = objectStorageService.uploadFile(bucketName, "storage/", img);
@Controller
@RequestMapping(value="user")
public class UserUploadController {
@Autowired
private UserUploadService userUploadService;
@Autowired
private ObjectStorageService objectStorageService;
private String bucketName = "bitcamp-9th-bucket-132";
for(MultipartFile img: list) {
//imageFileName = UUID.randomUUID().toString();
//네이버 클라우드 Object Storage-------------------------------
imageFileName = objectStorageService.uploadFile(bucketName, "storage/", img);
ObjectStorageService.java
package user.service;
import org.springframework.web.multipart.MultipartFile;
public interface ObjectStorageService {
public String uploadFile(String bucketName, String string, MultipartFile img);
}
NCPObjectStorage.java
package user.service.impl;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import user.service.ObjectStorageService;
@Service
public class NCPObjectStorage implements ObjectStorageService {
@Override
public String uploadFile(String bucketName, String directoryPath, MultipartFile img) {
// TODO Auto-generated method stub
return null;
}
}
aws java sdk s3
pom.xml
<!-- AWS -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.610</version>
</dependency>
파일 업로드
spring.conf
SpringConfiguration.java
NaverConfiguration.java
package spring.conf;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import lombok.Getter;
import lombok.Setter;
@Configuration
@PropertySource("classpath:spring/naver.properties")
@Getter
@Setter
public class NaverConfiguration {
private @Value("${ncp.accessKey}") String accessKey; //접근할 수 있는 키값
private @Value("${ncp.secretKey}") String secretKey; //보안 키값
private @Value("${ncp.regionName}") String regionName;
private @Value("${ncp.endPoint}") String endPoint;
}
NCPObjectStorage.java
package user.service.impl;
import java.io.InputStream;
import java.util.UUID;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import spring.conf.NaverConfiguration;
import user.service.ObjectStorageService;
@Service
public class NCPObjectStorage implements ObjectStorageService {
final AmazonS3 s3;
public NCPObjectStorage(NaverConfiguration naverConfiguration) {
s3 = AmazonS3ClientBuilder
.standard()
.withEndpointConfiguration(
new AwsClientBuilder.
EndpointConfiguration(naverConfiguration.getEndPoint(),
naverConfiguration.getRegionName()))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(naverConfiguration.getAccessKey(), naverConfiguration.getSecretKey())))
.build();
}
@Override
public String uploadFile(String bucketName, String directoryPath, MultipartFile img) {
try(InputStream inputStream = img.getInputStream()){
String imageFileName = UUID.randomUUID().toString();
//String imageFileName = img.getOriginalFilename(); 둘 중 뭐로 올릴지는 우리가 선택 !
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(img.getContentType());
PutObjectRequest putObjectRequest =
new PutObjectRequest(bucketName,
directoryPath + imageFileName,
inputStream,
objectMetadata).withCannedAcl(CannedAccessControlList.PublicRead); //리소스에 대한 접근 권한
//모든 사용자가 객체를 읽을 수 있지만, 수정과 삭제는 불가능하다.
s3.putObject(putObjectRequest);
return imageFileName;
}catch (Exception e) {
throw new RuntimeException("파일 업로드 에러");
}
}
}
db.properties -- Naver Cloud 주석 풀어주기 !
userUpload.sql
use study db;
create table userUpload (
seq int(10) primary key auto_increment,
imageName varchar(50),
imageContent varchar(4000),
imageFileName varchar(100) not null,
imageOriginalFileName varchar(100) not null);
uploadList.jsp
<%-- <img src="/spring2/storage/${userUploadDTO.imageOriginalFileName}" --%> 주석걸고
경로바꾸기
<img src=
"https://kr.object.ncloudstorage.com/bitcamp-9th-bucket-132/storage/${userUploadDTO.imageFileName}"
<td>
<%-- <img src="/spring2/storage/${userUploadDTO.imageOriginalFileName}" width="100" height="100" alt="${userUploadDTO.imageName}"> --%>
<%-- Object Storage --%>
<img src="https://kr.object.ncloudstorage.com/bitcamp-9th-bucket-132/storage/${userUploadDTO.imageFileName}" width="100" height="100" alt="${userUploadDTO.imageName}">
</td>
select * from userUpload;
파일 출력
uploadList.jsp
<a href="/spring2/user/uploadView?seq=${userUploadDTO.seq}">
<td>
<a href="/spring2/user/uploadView?seq=${userUploadDTO.seq}">
<%-- <img src="/spring2/storage/${userUploadDTO.imageOriginalFileName}" width="100" height="100" alt="${userUploadDTO.imageName}"> --%>
<%-- Object Storage --%>
<img src="https://kr.object.ncloudstorage.com/bitcamp-9th-bucket-132/storage/${userUploadDTO.imageFileName}" width="100" height="100" alt="${userUploadDTO.imageName}">
</a>
</td>
UserUploadController.java
@RequestMapping(value = "uploadView")
public String uploadView(@RequestParam String seq, Model map) {
UserUploadDTO userUploadDTO = userUploadService.getUploadDTO(seq);
return "/upload/uploadView";
}
UserUploadService.java
public UserUploadDTO getUploadDTO(String seq);
package user.service;
import java.util.List;
import user.bean.UserUploadDTO;
public interface UserUploadService {
public void upload(List<UserUploadDTO> imageUploadList);
public List<UserUploadDTO> uploadList();
public UserUploadDTO getUploadDTO(String seq);
}
UserUploadServiceImpl.java
@Override
public UserUploadDTO getUploadDTO(String seq) {
return userUploadDAO.getUploadDTO(seq);
}
package user.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import user.bean.UserUploadDTO;
import user.dao.UserUploadDAO;
import user.service.UserUploadService;
@Service
public class UserUploadServiceImpl implements UserUploadService {
@Autowired
private UserUploadDAO userUploadDAO;
@Override
public void upload(List<UserUploadDTO> imageUploadList) {
userUploadDAO.upload(imageUploadList);
}
@Override
public List<UserUploadDTO> uploadList() {
return userUploadDAO.uploadList();
}
@Override
public UserUploadDTO getUploadDTO(String seq) {
return userUploadDAO.getUploadDTO(seq);
}
}
UserUploadDAO.java
public UserUploadDTO getUploadDTO(String seq);
package user.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import user.bean.UserUploadDTO;
@Mapper
public interface UserUploadDAO {
public void upload(List<UserUploadDTO> imageUploadList);
List<UserUploadDTO> uploadList();
public UserUploadDTO getUploadDTO(String seq);
}
userUploadMapper.xml
<!-- 1개의 정보 -->
<select id="getUploadDTO" parameterType="String" resultType="userUploadDTO">
select * from userUpload where seq = #{seq}
</select>
seq는 원래 int형인데 String타입으로 오면 원래 비교 안해주는데 간단한경우에는 알아서 해결해준다.
대신 복잡해지면 error 떨어진다.
이게 싫으면 애초에 int형으로 보내면 된다.
(근데 나중에 이 부분 error 떠서 다 int형으로 바꿔줬다,,,,)
UserUploadController.java
@RequestMapping(value = "uploadView")
public String uploadView(@RequestParam String seq, Model model) {
UserUploadDTO userUploadDTO = userUploadService.getUploadDTO(seq);
model.addAttribute("userUploadDTO", userUploadDTO);
return "/upload/uploadView";
}
uploadView.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<tr>
<td rowspan="3">
<img src="https://kr.object.ncloudstorage.com/bitcamp-9th-bucket-132/storage/${userUploadDTO.imageFileName}" alt="${userUploadDTO.imageFileName }" />
</td>
<td width="250" style="text-indent: 10pt;">번호 : ${userUploadDTO.seq }</td>
</tr>
<tr>
<td>상품명 : ${userUploadDTO.imageName }</td>
</tr>
<tr>
<td>파일명 : ${userUploadDTO.imageOriginalFileName } </td>
</tr>
<tr>
<td colspan="2" height="200">
<pre>${userUploadDTO.imageContent }</pre>
</td>
</tr>
</table>
</body>
</html>
파일 수정
uploadView.jsp
<div style="margin-top: 5px;">
<input type="button" value="목록" onclick="location.href='/spring2/user/uploadList'" />
<input type="button" value="수정" onclick="location.href='/spring2/user/uploadUpdateForm?seq=${userUploadDTO.seq }'" />
</div>
UserUploadController.java
@RequestMapping(value = "uploadUpdateForm")
public String uploadUpdateForm(@RequestParam String seq, Model model) {
UserUploadDTO userUploadDTO = userUploadService.getUploadDTO(seq);
model.addAttribute("userUploadDTO", userUploadDTO);
return "/upload/uploadUpdateForm";
}
uploadUpdateForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>이미지 수정</title>
<link rel="stylesheet" href="../css/uploadFormList.css">
</head>
<body>
<div class="container">
<h2>이미지 수정</h2>
<form id="uploadUpdateForm">
<input type="hidden" name="seq" value="${userUploadDTO.seq}">
<table>
<tr>
<td>상품명</td>
<td>
<input type="text" name="imageName" value="${userUploadDTO.imageName}" required>
</td>
</tr>
<tr>
<td>상품내용</td>
<td>
<textarea name="imageContent" rows="5" cols="40">${userUploadDTO.imageContent}</textarea>
</td>
</tr>
<tr>
<td colspan="2">
<img id="camera" id="img" name="img" alt="카메라" src="../image/camera.png" width="50" height="50">
<span id="showImageList">
<img src="https://kr.object.ncloudstorage.com/bitcamp-9th-bucket-132/storage/${userUploadDTO.imageFileName}" width="70" height="70" alt="${userUploadDTO.imageName}" />
</span>
<input type="file" id="img" name="img" style="visibility: hidden;">
</td>
</tr>
<tr>
<td colspan="2">
<input type="button" value="수정" id="uploadUpdateBtn" class="button">
<input type="button" value="취소" onclick="location.href='/spring2/user/uploadList'" class="button">
</td>
</tr>
</table>
</form>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.7.1.min.js"></script>
<script type="text/javascript" src="../js/uploadUpdate.js"></script>
<script type="text/javascript">
$('#camera').click(function(){
$('#img').trigger('click'); //강제 이벤트 발생
});
//이미지 미리보기
$('#img').change(function(){
$('#showImageList').empty();
for(var i=0; i<this.files.length; i++){
readURL(this.files[i]);
}
});
function readURL(file){
var reader = new FileReader();
var show;
reader.onload = function(e){
var img = document.createElement('img');
img.src = e.target.result;
img.width = 70;
img.height = 70;
$('#showImageList').append(img);
}
reader.readAsDataURL(file);
}
</script>
</body>
</html>
uploadUpdate.js
$(function(){
$('#uploadUpdateBtn').click(function(){
let formData = new FormData($('#uploadUpdateForm')[0]);
$.ajax({
type: 'post',
enctype: 'multipart/form-data',
processData: false,
contentType: false,
url: '/spring2/user/uploadUpdate',
data: formData,
success: function(data){
location.href = "/spring2/user/uploadList";
},
error: function(e){
console.log(e);
}
}); //$.ajax
});
});
UserUploadController.java
@RequestMapping(value = "uploadUpdate", produces = "text/html; charset=UTF-8")
@ResponseBody
public String uploadUpdate(@ModelAttribute UserUploadDTO userUploadDTO,
@RequestParam("img") MultipartFile img) {
userUploadService.uploadUpdate(userUploadDTO, img);
return "이미지 수정 완료";
}
UserUploadService.java
public void uploadUpdate(UserUploadDTO userUploadDTO, MultipartFile img);
package user.service;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
import user.bean.UserUploadDTO;
public interface UserUploadService {
public void upload(List<UserUploadDTO> imageUploadList);
public List<UserUploadDTO> uploadList();
public UserUploadDTO getUploadDTO(String seq);
public void uploadUpdate(UserUploadDTO userUploadDTO, MultipartFile img);
}
//실제폴더
String filePath = session.getServletContext().getRealPath("WEB-INF/storage");
System.out.println("실제 폴더 = " + filePath);
-- Controller에서 해도되고 service에서 해도된다. 이번엔 service에서 해보자 !!
UserUploadServiceImpl.java
@Autowired
private HttpSession session;
Object Storage(NCP)는 이미지를 덮어쓰지 않는다.
DB에서 seq에 해당하는 imageFileName을 꺼내와서 Object Storage(NCP)의 이미지를 삭제하고,
새로운 이미지를 올린다.
UserUploadServiceImpl.java
@Override
public void uploadUpdate(UserUploadDTO userUploadDTO, MultipartFile img) {
//실제폴더
String filePath = session.getServletContext().getRealPath("WEB-INF/storage");
System.out.println("실제 폴더 = " + filePath);
//Object Storage(NCP)는 이미 지를 덮어쓰지 않는다.
//DB에서 seq에 해당하는 imageFileName을 꺼내와서 Object Storage(NCP)의 이미지를 삭제하고,
//새로운 이미지를 올린다.
String imageFileName = userUploadDAO.getImageFileName(userUploadDTO.getSeq());
System.out.println(imageFileName);
}
select imageFileName from userUpload where seq = ?;
UserUploadDAO.java
public String getImageFileName(int seq);
package user.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import user.bean.UserUploadDTO;
@Mapper
public interface UserUploadDAO {
public void upload(List<UserUploadDTO> imageUploadList);
List<UserUploadDTO> uploadList();
public UserUploadDTO getUploadDTO(String seq);
public String getImageFileName(int seq);
}
userUploadMapper.xml
<!-- imageFileName 얻기 -->
<select id="getImageFileName" parameterType="String" resultType="String">
select imageFileName from userUpload where seq = #{seq};
</select>
UserUploadServiceImpl.java
NCP에 있는 이미지 삭제하고 새로운 이미지 올리는 작업이 필요하다 !
//Object Storage(NCP) 이미지 삭제
objectStorageService.deleteFile(bucketName, "storage/", imageFileName);
//Object Storage(NCP) 새로운 이미지 올리기
imageFileName = objectStorageService.uploadFile(bucketName, "storage/", img);
ObjectStorageService.java
public void deleteFile(String bucketName, String string, String imageFileName);
package user.service;
import org.springframework.web.multipart.MultipartFile;
public interface ObjectStorageService {
public String uploadFile(String bucketName, String string, MultipartFile img);
public void deleteFile(String bucketName, String string, String imageFileName);
}
NCPObjectStorage.java
@Override
public void deleteFile(String bucketName, String directoryPath, String imageFileName) {
s3.deleteObject(bucketName, directoryPath + imageFileName);
}
UserUploadServiceImpl.java
String imageOriginalFileName = img.getOriginalFilename();
File file = new File(filePath, imageOriginalFileName);
try {
img.transferTo(file);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
userUploadDTO.setImageFileName(imageFileName);
userUploadDTO.setImageOriginalFileName(imageOriginalFileName);
//DB
userUploadDAO.uploadUpdate(userUploadDTO);
}
UserUploadDAO.java
public void uploadUpdate(UserUploadDTO userUploadDTO);
package user.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import user.bean.UserUploadDTO;
@Mapper
public interface UserUploadDAO {
public void upload(List<UserUploadDTO> imageUploadList);
List<UserUploadDTO> uploadList();
public UserUploadDTO getUploadDTO(String seq);
public String getImageFileName(int seq);
public void uploadUpdate(UserUploadDTO userUploadDTO);
}
userUploadMapper.xml
<!-- 수정 -->
<update id="uploadUpdate" parameterType="userUploadDTO">
update userUpload set imageName=#{imageName},
imageContent=#{imageContent},
imageFileName=#{imageFileName},
imageOriginalFileName=#{imageOriginalFileName}
where seq=#{seq}
</update>
이미지 수정 안 하고 올릴 때
이제 이미지를 수정안하고 올려버리면 null값이 저장되면서 기존 사진이 다시 안 불러와지고 error가 뜨게 된다.
그러므로 원래 db에서 데이터를 가져와서 그 값을 다시 넣어주는 작업이 필요하다 !!!
MultipartFile img 여기서 img의 size가 0일 경우와 0이 아닌 경우를 확인 후 코드를 if문으로 해서 나눠야한다 !!
UserUploadServiceImpl.java
@Override
public void uploadUpdate(UserUploadDTO userUploadDTO, MultipartFile img) {
//실제폴더
String filePath = session.getServletContext().getRealPath("WEB-INF/storage");
System.out.println("실제 폴더 = " + filePath);
System.out.println("img = " + img);
//Object Storage(NCP)는 이미 지를 덮어쓰지 않는다.
//DB에서 seq에 해당하는 imageFileName을 꺼내와서 Object Storage(NCP)의 이미지를 삭제하고,
//새로운 이미지를 올린다.
//String imageFileName = userUploadDAO.getImageFileName(userUploadDTO.getSeq());
UserUploadDTO dto = userUploadDAO.getUploadDTO(userUploadDTO.getSeq());
System.out.println("imageFileName = " + dto.getImageFileName());
System.out.println("size = " + img.getSize());
String imageFileName;
String imageOriginalFileName;
if(img.getSize() != 0) {
//Object Storage(NCP) 이미지 삭제
objectStorageService.deleteFile(bucketName, "storage/", dto.getImageFileName());
//Object Storage(NCP) 새로운 이미지 올리기
imageFileName = objectStorageService.uploadFile(bucketName, "storage/", img);
imageOriginalFileName = img.getOriginalFilename();
File file = new File(filePath, imageOriginalFileName);
try {
img.transferTo(file);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else {
System.out.println(dto.getImageFileName() + ", " + dto.getImageOriginalFileName());
imageFileName = dto.getImageFileName();
imageOriginalFileName = dto.getImageOriginalFileName();
}
userUploadDTO.setImageFileName(imageFileName);
userUploadDTO.setImageOriginalFileName(imageOriginalFileName);
//DB
userUploadDAO.uploadUpdate(userUploadDTO);
}
'Spring' 카테고리의 다른 글
스케줄러 데드락 에러 해결 ! (2) | 2024.12.27 |
---|---|
DAY 68 - 스프링 프레임워크 HOMEWORK - NCP 파일 삭제 (2024.10.14) (0) | 2024.10.15 |
DAY 67 - 스프링 프레임워크 HOMEWORK - 파일 DB 저장 / 이미지 출력 (2024.10.11) (0) | 2024.10.14 |
DAY 67 - 스프링 프레임워크 - 파일업로드 (2024.10.11) (0) | 2024.10.11 |
DAY 66 - 스프링 프레임워크 MVC HOMEWORK - 회원탈퇴 (2024.10.10) (1) | 2024.10.11 |