본문 바로가기

Spring

240223 스프링 프로젝트

오늘은 어제 했던 메일 보내기 다시하기

mail.jsp 생성 및 칸 만들기

<div>
  <h1>메일 테스트</h1>
</div>
<div>
  <form action="./mail" method="post">
    <input type="email" name="email" class="form-control"/>
    <input type="text" name="title" class="from-control" />
    <textarea name="content" class="form-control"></textarea>
    <button type="submit" class="btn btn-outline-dark">보내기</button>
  </form>
</div>

 

컨트롤러에서 값 받기, 새로 MailController 를 생성

@Controller
public class MailController {

  @Autowired
  private MailService mailService;
	
  @GetMapping("/mail")
  public String mail() {
    return "mail";
  }
	
  @PostMapping("/mail")
  public String sendEmail(String email, String title, String content) throws EmailException {
    // mailService.sendHTMLMail(email, title, content);
    return "redirect:/mail";
  }
}

 

현재 계정이 막혀져있어, 메일을 보내지는 못해 주석처리

MailService 에서 메일 보내는 법 정리, 어제는 Util 에서 했지만 오늘은 Service 에서 해보기

@Service
public class MailService {

  //메일 보내기
  public void sendMail(String email, String title, String content) throws EmailException {
    String emailAddr = "-----"; // 보내는 사람 이메일 = outlook
    String name = "-----"; // 보내는 사람 이름
    String pw = "-----"; // 보내는 사람 비번 = outlook 만든거
    String host = "smtp-mail.outlook.com"; // 아웃룩 호스트
    int port = 587; // 아웃룩 포트

    SimpleEmail mail = new SimpleEmail(); // 여기다 조립
    mail.setCharset("UTF-8"); // 언어셋 인코딩
    mail.setDebug(true); // 디버그
    mail.setHostName(host); // 호스트
    mail.setAuthentication(emailAddr, pw);// 보내는 사람 이메일주소, 비번
    mail.setSmtpPort(port);// 보내는 쪽의 포트
    mail.setFrom(emailAddr, name); // 보내는 사람의 주소, 이름 -> EmailException throw
    mail.addTo(email); // 받는 사람
    mail.setSubject(title); // 메일 제목
    mail.setMsg(content); // 메일 내용
    mail.send(); // 발송
  }

  public void sendHTMLMail(String email, String title, String content) throws EmailException {
    String emailAddr = "-----"; // 보내는 사람 주소
    String pw = "-----"; // 보내는 이메일 비밀번호
    String name = "-----"; // 보내는 사람 이름

    String host = "smtp-mail.outlook.com"; // 아웃룩 호스트 주소
    int port = 587; // 아웃룩 호스트 포트번호

    HtmlEmail mail = new HtmlEmail();

    mail.setCharset("utf-8"); // 인코딩하기
    mail.setDebug(true); // 디버그하기
    mail.setHostName(host); // 메일에 호스트 주소 세팅
    mail.setAuthentication(emailAddr, pw); // 보내는 이메일과 비밀번호 세팅
    mail.setSmtpPort(port); // 메일 포트번호 세팅
    mail.setFrom(emailAddr, name); // 보내는 사람과 이름 세팅
    mail.setStartTLSEnabled(true); // 인증 방법 -> 알아보기
    mail.addTo(email); // 받는 이메일 주소
    mail.setSubject(title); // 이메일 제목
    mail.setMsg(content); // 이메일 내용

    // 첨부 파일 세팅하기
    EmailAttachment file = new EmailAttachment();
    // 내용 안에 파일 세팅하기, 경로 세팅
    file.setPath("c:\\users\\username\\downloads\\파일이름");
    mail.attach(file); // 메일에 파일 첨부하기

    mail.send(); // 보내기
  }
}

 

파일 첨부 해보기

먼저 db-context 가 있던 resources > spring 에 file-context.xml 파일 생성

파일의 인코딩과 최대 크기 등  설정

<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
  <property name="defaultEncoding" value="utf-8" />
  <property name="maxUploadSizePerFile" value="52428800" />
  <property name="maxUploadSize" value="104857600" />
</bean>

 

파일 업로드를 하기 위한 file.jsp, Controller 생성

form 에 꼭 enctype 을 적어주어야 함

<form action="./file" method="post" enctype="multipart/form-data">
  <!-- accept : 업로드할 파일을 지정할 수 있음 -->
  <input type="file" accept="image/*" class="form-control" name="upFile">
  <button type="submit" class="btn btn-outline-dark">전송</button>
</form>

 

Controller 세팅하기

@Controller
public class FileController {
  @GetMapping("/file")
  public String file() {
    return "file";
  }
  
  @PostMapping("/file")
  public String file(MultipartFile upFile) { // 들어오는 값과 이름이 같으면 자동 세팅됨
    System.out.println("파일 이름 : " + upFile.getOriginalFilename());
    System.out.println("파일 사이즈 : " + upFile.getSize());
    System.out.println("파일 타입 : " + upFile.getContentType());
    
    // 경로, 파일 이름
    File file = new File("C:\\Users\\userName\\test", upFile.getOriginalFilename());
    try {
      upFile.transferTo(file);
    } catch (IllegalStateException | IOException e) {
      e.printStackTrace();
    }
    return "redirect:/file";
  }
}

 

해서 파일을 보내면 해당 폴더에 정상 저장되는 것을 볼 수 있음

이미지 선택 후 전송
정상 저장되는 모습

 

파일 업로드 시 이름이 겹칠 경우 파일이 덮어쓰기 되는 등 파일의 손상을 막기 위해 UUID 라는 것을 만듬

// UUID 생성하기, 파일의 중복을 제거하기 위한 노력
// 만약 이름이 name.png 면 해당 이름에 겹치지 않는 이름을 붙여서 저장, 중복의 위험 제거
UUID uuid = UUID.randomUUID();
System.out.println(uuid); // 93fbd71b-88ed-4c19-aca4-22a1972d1043 등 랜덤 코드

 

계속 해보니 파일별로 UUID 는 고정인 것 같음

-> 다시 해보니 업로드할 때마다 달라짐

업로드 시 마다 달라지는 UUID 코드

 

썸네일 만들어주는 라이브러리 추가하기

https://mvnrepository.com/artifact/net.coobird/thumbnailator

pom.xml 에 dependencies 안에 추가하기

 <!-- 썸네일 만들기 -->
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
  <groupId>net.coobird</groupId>
  <artifactId>thumbnailator</artifactId>
  <version>0.4.20</version>
</dependency>

 

Controller 에서 이제 썸네일 만들어보기

꼭 파일 전송을 가장 밑으로 내려야 함, 파일 전송 후 만들기 하면 에러 발생

// 썸네일 만들기
// 새로운 파일을 s_ + uuid 코드를 이용하여 만듬
FileOutputStream thumbnail = 
        new FileOutputStream(new File("C:\\Users\\ppj21\\test", "s_" + newFileName));
// MultipartFile.getInputStream(), 썸네일, 가로 크기, 세로 크기
Thumbnailator.createThumbnail(upFile.getInputStream(), thumbnail, 100, 100);
thumbnail.close();
// 파일 보내기
upFile.transferTo(file);

 

파일이 저장될 곳을 지정해보기

resources 밑에 폴더 생성

 

// 경로 만들기
String upFileURL = util.getSession().getServletContext().getRealPath("/");
System.out.println("upfileURL : " + upFileURL);
String url = upFileURL + "resources\\upfile\\";
System.out.println("url : " + url);

 

경로 출력하면 이런 경로가 나옴

 

해당 경로로 업로드 될 파일 넣어주기

// 경로, 파일 이름
File file = new File(url, upFile.getOriginalFilename());
try {
  // 썸네일 만들기
  // 새로운 파일을 s_ + uuid 코드를 이용하여 만듬
  FileOutputStream thumbnail = 
      new FileOutputStream(new File(url + "thumbnail", "s_" + newFileName));
  // MultipartFile.getInputStream(), 썸네일, 가로 크기, 세로 크기
  Thumbnailator.createThumbnail(upFile.getInputStream(), thumbnail, 100, 100);
  thumbnail.close();

 

사진 등록할 때 파일 확장자 체크하기

function fileCheck() {
  let fileVal = $('#upFile').val(); // 파일 이름 가져오기
  if (fileVal == "" || fileVal == null) {
    alert('파일을 선택하세요.');
    return false;
  } else {
    let ext = fileVal.split('.').pop().toLowerCase(); // 확장자 분리
    // 아래 확장자가 있는지 체크
    if ($.inArray(ext, ['jpg', 'jpeg', 'gif', 'png']) == -1) {
      alert('jpg, jpeg, gif, png 파일만 등록할 수 있습니다.');
      return false;
    }
  }
}

 

button 에 onclick=return fileCheck() 추가해야 함

 

등록된 사진 확인하는 게시판 만들기

Gallery 테이블 생성

 

 

파일 저장하는 것, FileController 에서 만든 것을 Util 로 옮김

옮기면서 UUID + 파일명 생성과 파일 저장을 서로 나눠둠

/**
 * @param 기존 파일명 {@code String}
 * @return s_ + UUID + fileName {@code String}
 */
public String createUUID(String originalFileName) {
  // UUID 생성하기, 파일의 중복을 제거하기 위한 노력
  // 만약 이름이 name.png 면 해당 이름에 겹치지 않는 이름을 붙여서 저장, 중복의 위험 제거
  UUID uuid = UUID.randomUUID();
  return "s_" + uuid.toString() + originalFileName;
}
  
/**
  * @param MultipartFile {@code MultipartFile}
  * @param UUID 처리 된 파일이름 {@code String}
  */
public void saveFile(MultipartFile upFile, String newFileName) {
  // 경로 만들기, apache 내부의 경로 ?
  String upFileURL = getSession().getServletContext().getRealPath("/");
  String url = upFileURL + "resources\\upfile\\";
    
  // 경로, 파일 이름
  File file = new File(url, newFileName);
  try {
    // 썸네일 만들기
    // s_ + uuid 코드를 이용해 만든 이름으로 저장 
    FileOutputStream thumbnail = 
        new FileOutputStream(new File(url + "thumbnail", newFileName));
    // MultipartFile.getInputStream(), 썸네일, 가로 크기, 세로 크기
    Thumbnailator.createThumbnail(upFile.getInputStream(), thumbnail, 100, 100);
    thumbnail.close();
    // 파일 보내기
    upFile.transferTo(file);
  } catch (IllegalStateException | IOException e) {
    e.printStackTrace();
  }
}

 

galleryInsert 로 파일 등록하기, galleryInsert.jsp 파일 생성

<div class="">
  <div>
    <h1 class="text-center">갤러리 Insert</h1>
  </div>
  <div class="d-flex justify-content-center align-items-center">
    <form action="./galleryInsert" method="post" enctype="multipart/form-data">
      <div class="input-group my-3">
        <span class="input-group-text" id="basic-addon3">제목</span>
        <input type="text" class="form-control" id="gtitle"
            aria-describedby="basic-addon3" name="gtitle" required="required">
      </div>
      <div class="input-group my-3">
        <span class="input-group-text">내용</span>
        <textarea class="form-control" aria-label="With textarea" name="gcontent" id="gcontent"
            required="required" maxlength="400"></textarea>
      </div>
      <div class="input-group">
        <!-- accept : 업로드할 파일을 지정할 수 있음 -->
        <input type="file" accept="image/*" class="form-control" id="upFile" 
            aria-label="Upload" name="upFile" aria-describedby="inputGroupFileAddon">
        <button type="submit" class="btn btn-outline-dark"
            id="inputGroupFileAddon" onclick="return fileCheck()">전송하기</button>
      </div>
    </form>
  </div>
</div>

 

파일 전송 시 받을 DTO 생성

@Data
public class GalleryDTO {
  private int gno, glike;
  private String gtitle, gcontent, gfile, gthumbnail, gdate, mname, mid, gdel;
}

 

컨트롤러 생성

@PostMapping("/galleryInsert")
public String galleryInsert(GalleryDTO dto, MultipartFile upFile) {
//  System.out.println("gtitle : " + dto.getGtitle());
//  System.out.println("gcontent : " + dto.getGcontent());
//  System.out.println("파일 이름 : " + upFile.getOriginalFilename());
//  System.out.println("파일 사이즈 : " + upFile.getSize() + " Byte");
//  System.out.println("파일 타입 : " + upFile.getContentType());
  String newFileName = util.createUUID(upFile.getOriginalFilename());
  dto.setGfile(newFileName);
  util.saveFile(upFile, newFileName);
  int result = galleryService.galleryInsert(dto);
  if (result == 1) {
    return "redirect:/gallery";
  } else {
    return "redirect:/error";
  }
}

 

Service 생성

public int galleryInsert(GalleryDTO dto) {
  if (util.getMid() != null) {
    // 세션의 mid 세팅하기
    dto.setMid(util.getMid());
    return galleryRepository.galleryInsert(dto);
  } else {
    return 0;
  }
}

 

DB 에 집어넣기

<insert id="galleryInsert" parameterType="galleryDTO">
  insert into gallery (gtitle, gcontent, gfile, mno)
  values (#{gtitle}, #{gcontent}, #{gfile}, (select mno from member where mid=#{mid}))
</insert>

 

정상 입력 확인

 

 

'Spring' 카테고리의 다른 글

240227 스프링 프로젝트  (1) 2024.02.27
240226 스프링 프로젝트  (2) 2024.02.26
240222 스프링 프로젝트  (0) 2024.02.22
240221 스프링 프로젝트  (2) 2024.02.21
240220 스프링 프로젝트  (0) 2024.02.20