* 제작 순서
- 메뉴 작업
- 컨트롤러에 추가 또는 생성
- jsp 연결
- 화면 구성
- db로 보낼거면 service - repository - mybatis
이메일
menu.jsp
메뉴에 ./mail 추가
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav text-uppercase ms-auto py-4 py-lg-0">
<li class="nav-item"><a class="nav-link" href="./board">게시판</a></li>
<li class="nav-item"><a class="nav-link" href="./mail">메일</a></li>
<li class="nav-item"><a class="nav-link" href="./notice">공지사항</a></li>
<c:choose>
<c:when test="${sessionScope.mid ne null }">
<li class="nav-item"><a class="nav-link" href="./myInfo@${sessionScope.mid }">${sessionScope.mname } 님</a></li>
<li class="nav-item"><a class="nav-link" href="./logout">로그아웃</a></li>
</c:when>
<c:otherwise>
<li class="nav-item"><a class="nav-link" href="./login">로그인</a></li>
</c:otherwise>
</c:choose>
</ul>
</div>
MailController.java
메일 컨트롤러 새로 생성해주기.
@Controller
public class MailController {
@GetMapping("/mail")
public String mail() {
// 로그인 한 사용자만 접근 가능
return "mail";
}
mail.jsp
메일보내기 form 만들기
<!-- 메일 보내기 -->
<section class="container">
<div class="row justify-content-center">
<div class="col-md-6">
<h2>비밀번호 찾기 인증번호 발송</h2>
<form action="/mail" method="post">
<div class="mb-3">
<label for="email" class="form-label">받는 사람</label>
<input type="email" class="form-control" id="email" name="email" placeholder="youremail@example.com">
</div>
<div class="mb-3">
<label for="title" class="form-label">제목</label>
<input type="text" class="form-control" id="title" name="title" placeholder="메일 제목을 입력하세요">
</div>
<div class="mb-3">
<label for="content" class="form-label">본문</label>
<textarea class="form-control" id="content" name="content" rows="4" placeholder="메일 내용을 입력하세요"></textarea>
</div>
<button type="submit" class="btn btn-primary">전송</button>
</form>
</div>
</div>
</section>
mail.jsp 기본 폼
<section class="page-section" id="mail">
<div class="container d-flex justify-content-center">
<div class="text-center">
<form action="/mail" method="post">
받는 사람<input type="email" name="email">
제목 : <input type="text" name="title">
본문 : <textarea name="content"></textarea>
<button type="submit">전송</button>
</form>
</div>
</div>
</section>
MailController.java
* post 추가
** 순서 : jsp -> controller -> service에서 메일 발송 (db로 갈 필요가 없음. 서비스까지만 감)
@PostMapping("/mail")
public String mail(@RequestParam("email") String email,
@RequestParam("title") String title,
@RequestParam("content") String content) {
// 값이 제대로 오는지 확인
System.out.println("email : " + email);
System.out.println("title : " + title);
System.out.println("content : " + content);
return "redirect:/mail";
}
-> 3개 값을 서비스에 보내서 작동시키기
-> MailService.java 파일 생성
-> 컨트롤러에도 연결하기
MailController.java
메일 서비스의 Autowired 생성
서비스에 있는 sendMail에게 일 시킴~
@Autowired
private MailService mailService;
@PostMapping("/mail")
public String mail(@RequestParam("email") String email,
@RequestParam("title") String title,
@RequestParam("content") String content) {
mailService.sendMail(email, title, content);
return "redirect:/mail";
}
-> sendMail 생성 (MailService에 생성하기)
MailService.java
@Service
public class MailService {
// 메일 보내기 (메일만 보내고 끝남 = void)
public void sendTextMail(String email, String title, String content) throws EmailException {
String emailAddr = "----@outlook.kr"; // 보내는 사람 (outlook.kr)
String name = "15번"; // 보내는 사람 이름
String pw = ""; // 보내는 사람 pw
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); // 사용할 port번호
mail.setStartTLSEnabled(true); // 인증방법 = 고정
mail.setFrom(emailAddr, name); // throws (컨트롤러에서도 throws 필요함)
mail.addTo(email); // 받는사람
mail.setSubject(title); // 제목
mail.setMsg(content); // 내용 text
mail.send();
}
}
-> 홈페이지의 메일 페이지에 가서 직접 이메일, 제목, 내용을 써서 발송하면 메일이 전송됨
-> public void sendMail을 sendTextMail로 변경
MailController.java
mailService.sendTextMail(email, title, content);
mailService.sendHTMLMail(email, title, content);
-> sendHTMLMail 생성 (MailService)
MailService.java
public void sendHTMLMail(String email, String title, String content) throws EmailException {
String emailAddr = "-----@outlook.kr"; // 보내는 사람 (outlook.kr)
String name = "15번"; // 보내는 사람 이름
String pw = "-----"; // 보내는 사람 pw
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); // 사용할 port번호
mail.setStartTLSEnabled(true); // 인증방법 = 고정
mail.setFrom(emailAddr, name); // throws (컨트롤러에서도 throws 필요함)
mail.addTo(email); // 받는사람
mail.setSubject(title); // 제목
mail.setMsg(content); // 내용 text
// 첨부파일
EmailAttachment file = new EmailAttachment();
file.setPath("c:\\temp\\img.png"); // 메일에 이 파일을 첨부해서 전송
mail.attach(file);
mail.send();
}
}
이미지 게시판 만들기 (파일 업로드)
menu.jsp
<li class="nav-item"><a class="nav-link" href="./file">파일</a></li>
FileController.java
@Controller
public class FileController {
@GetMapping("/file")
public String file() {
return "file";
}
}
file.jsp
<!-- 파일 업로드 -->
<section class="page-section" id="my-info">
<div class="container d-flex justify-content-center">
<div class="text-center">
<form action="./file" method="post" enctype="multipart/form-data">
<div class="input-group">
<input type="file" class="form-control" name="file1" id="inputGroupFile04" aria-describedby="inputGroupFileAddon04" aria-label="Upload">
<button class="btn btn-outline-secondary" type="submit" id="inputGroupFileAddon04">Button</button>
</div>
</form>
</div>
</div>
</section>
FileController.java
파일 업로드하면 콘솔에 찍히는지 확인
@Controller
public class FileController {
@GetMapping("/file")
public String file() {
return "file";
}
@PostMapping("file")
public String file(@RequestParam("file1") MultipartFile upFile) {
System.out.println("파일 이름 : " + upFile.getOriginalFilename());
System.out.println("파일 사이즈 : " + upFile.getSize());
System.out.println("파일 타입 : " + upFile.getContentType());
return "redirect:/file";
}
}
servlet-context.xml
기존의 db-context.xml을 *로 변경
<beans:import resource="classpath:/spring/*-context.xml" />
file-context.xml
db-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>
</beans>
FileController.java
@PostMapping("file")
public String file(@RequestParam("file1") MultipartFile upFile) {
// 진짜 업로드 저장
File f = new File("c:\\temp\\upfile", upFile.getOriginalFilename()); // "경로", "파일명"
try {
upFile.transferTo(f);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/file";
}
file.jsp
- 이미지 파일만 올리도록 확장자 막는 방법 : input에 accept="image/png, image/jpg" 또는 "image/*"
<div class="card-body">
<div class="mb-3">
<input type="file" accept="image/*" class="form-control" id="file1" name="file1">
</div>
FilController.java
UUID(Universally Unique Identifier)
진짜 업로드 저장할 때 File f의 파일명에 newFileName 로 변경.
// UUID 생성 (Universally Unique Identifier)
UUID uuid = UUID.randomUUID();
System.out.println("UUID : " + uuid);
String newFileName = uuid.toString() + "-" + upFile.getOriginalFilename();
System.out.println("새로 만들어진 파일명 : " + newFileName);
// 진짜 업로드 저장
File f = new File("c:\\temp\\upfile", newFileName); // "경로", "파일명"
try {
upFile.transferTo(f);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/file";
}
}
pom.xml
썸네일 만들기 : thumbnailator 코드 추가
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.20</version>
</dependency>
FileController.java
-> 총 2개 파일 생성: 업로드한 파일 + s_ 붙은 썸네일(100x100) 파일도 생성됨.
// 썸네일 만들기 (파일명 앞에 s_ 붙이도록)
FileOutputStream thumbnail = new FileOutputStream(new File("c:\\temp\\upfile", "s_"+newFileName));
Thumbnailator.createThumbnail(upFile.getInputStream(), thumbnail, 100, 100);
thumbnail.close();
upFile.transferTo(f);
upfile 폴더 생성
webapp - resources - upfile 폴더 생성하기
servlet-context.xml
<resources mapping="/assets/upfile/**" location="/resources/assets/upfile/" />
FileController.java
// 경로
String root = request.getSession().getServletContext().getRealPath("/");
System.out.println("upfileURL : " + root);
String upfile = root + "upfile/";
System.out.println("upfile : " + upfile);
-> File f = new File의 경로를 upfile로 변경
// 진짜 업로드 저장
File f = new File(upfile, newFileName); // "경로", "파일명"
< FileController.java 전체코드 >
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
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;
import net.coobird.thumbnailator.Thumbnailator;
@Controller
public class FileController {
@GetMapping("/file")
public String file() {
return "file";
}
@PostMapping("file")
public String file(@RequestParam("file1") MultipartFile upFile, HttpServletRequest request) {
System.out.println("파일 이름 : " + upFile.getOriginalFilename());
System.out.println("파일 사이즈 : " + upFile.getSize());
System.out.println("파일 타입 : " + upFile.getContentType());
// 경로
String root = request.getSession().getServletContext().getRealPath("/");
System.out.println("upfileURL : " + root);
String upfile = root + "resources/upfile/";
System.out.println("upfile : " + upfile);
// upfileURL : C:\workspace-spring\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\feb15\
// upfile : C:\workspace-spring\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\feb15\resources/upfile/
// UUID 생성 (Universally Unique Identifier)
UUID uuid = UUID.randomUUID();
System.out.println("UUID : " + uuid);
String newFileName = uuid.toString() + "-" + upFile.getOriginalFilename();
System.out.println("새로 만들어진 파일명 : " + newFileName);
// 진짜 업로드 저장
File f = new File(upfile, newFileName); // "경로", "파일명"
try {
// 썸네일 만들기 (파일명 앞에 s_ 붙이도록)
FileOutputStream thumbnail = new FileOutputStream(new File("c:\\temp\\upfile", "s_"+newFileName));
Thumbnailator.createThumbnail(upFile.getInputStream(), thumbnail, 100, 100);
thumbnail.close();
upFile.transferTo(f); // 실제 저장
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/file";
}
}
file.jsp
-> form에 onsubmit="fileCheck()" 추가하기
<form action="./file" method="post" enctype="multipart/form-data" onsubmit="fileCheck()">
-> fileCheck() function 생성 (var는 let으로 대체 가능, let이 더 나음)
<script type="text/javascript">
function fileCheck(){
var fileVal = $("#file").val();
if(fileVal == ""){
alert('파일을 선택하세요.');
return false;
} else {
var ext = fileVal.split('.').pop().toLowerCase();
// 아래 확장자가 있는지 확인
if($.inArray(ext, ['jpg','jpeg','gif','png']) == -1) {
alert('jpg, gif, jpeg, png 파일만 업로드 할 수 있습니다.');
return false;
}
}
}
</script>
갤러리 만들기
menu.jsp
<li class="nav-item"><a class="nav-link" href="./gallery">갤러리</a></li>
GalleryController.java
@Controller
public class GalleryController {
@GetMapping("/gallery")
public String gallery() {
return "gallery";
}
@GetMapping("/galleryInsert")
public String galleryInsert() {
return "galleryInsert";
}
@PostMapping("/galleryInsert")
public String galleryInsert(GalleryDTO dto) {
return "redirect:/gallery";
}
}
GalleryDTO.java
import lombok.Data;
@Data
public class GalleryDTO {
private int gno, gcount, glike, gdel;
private String gtitle, gcontent, gfile, gthumbnail, gdate;
}
db 테이블 생성
CREATE TABLE gallery (
gno INT AUTO_INCREMENT PRIMARY KEY,
glike INT,
gdel INT,
gtitle VARCHAR(255),
gcontent TEXT,
gfile VARCHAR(255),
gdate TIMESTAMP,
mno INT,
);
세부 조건들은 아래의 이미지와 맞추기.
GalleryDAO.java
@Repository
public class GalleryDAO {
@Autowired
private SqlSession sqlSession;
public int galleryInsert(GalleryDTO dto) {
return sqlSession.insert("gallery.galleryInsert", dto);
}
}
GalleryService.java
@Service
public class GalleryService {
@Autowired
private GalleryDAO galleryDAO;
@Autowired
private Util util;
public int galleryInsert(GalleryDTO dto) {
if(util.getSession().getAttribute("mid") != null) {
dto.setMid((String) util.getSession().getAttribute("mid"));
return galleryDAO.galleryInsert(dto);
} else {
return 0;
}
}
}
GalleryController.java
@Autowired
private GalleryService galleryService;
@PostMapping("/galleryInsert")
public String galleryInsert(GalleryDTO dto) {
int result = galleryService.galleryInsert(dto);
return "redirect:/gallery";
}
gallery-mapper.xml
<mapper namespace="gallery">
<insert id="galleryInsert" parameterType="galleryDTO"> <!-- -->
INSERT INTO gallery (gtitle, gcontent, mno)
VALUES (#{gtitle}, #{gcontent}, #{mid})
</insert>
</mapper>
mybatis-config.xml
<typeAlias type="org.-----.dto.GalleryDTO" alias="galleryDTO"/>
jsp 파일 생성
gallery (이미지 리스트) / galleryInsert (실제 업로드 화면)
GalleryController.java
@Autowired
private Util util;
@PostMapping("/galleryInsert")
public String galleryInsert(GalleryDTO dto, @RequestParam("file1") MultipartFile upFile) {
System.out.println(dto.getGtitle());
System.out.println(dto.getGcontent());
System.out.println(upFile.getOriginalFilename());
dto.setGfile(upFile.getOriginalFilename());
// 파일 업로드 -> util
String newFileName = util.fileUpload(upFile);
dto.setGfile(newFileName); // UUID
int result = galleryService.galleryInsert(dto);
return "redirect:/gallery";
}
}
gallery-mapper.xml
<insert id="galleryInsert" parameterType="galleryDTO"> <!-- -->
INSERT INTO gallery
(gtitle, gcontent, gfile, mno) VALUES
(#{gtitle}, #{gcontent}, #{gfile}, (SELECT mno FROM member WHERE mid=#{mid}))
</insert>
Util.java
-> fileUpload 생성 (util)
public String fileUpload(MultipartFile upFile) {
// 경로저장
String root = req().getSession().getServletContext().getRealPath("/");
String upfilePath = root + "resources\\upfile\\";
// UUID 뽑기
UUID uuid = UUID.randomUUID();
// UUID를 포함한 파일명
String newFileName = uuid.toString() + upFile.getOriginalFilename();
// 실제 업로드
File file = new File(upfilePath, newFileName);
try {
upFile.transferTo(file);
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
return newFileName;
}
}
=> 로그인을 해야지 업로드가 되고 db에 저장이 됨.
Util.java
file.mkdirs(); 코드 추가
// 실제 업로드
File file = new File(upfilePath, newFileName);
if(file.exists() == false) {
file.mkdirs(); // 경로가 없다면 다 만들어주기.
}
try {
FileOutputStream thumbnail = new FileOutputStream(new File(upfilePath, "s_"+newFileName)); // 경로, s_붙인 파일명
Thumbnailator.createThumbnail(upFile.getInputStream(), thumbnail, 100, 100);
thumbnail.close();
upFile.transferTo(file);
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
-> 업로드한 이미지 화면에 띄우기
GalleryController.java
@Controller
public class GalleryController {
@Autowired
private GalleryService galleryService;
@Autowired
private Util util;
@GetMapping("/gallery")
public String gallery(Model model) {
List<GalleryDTO> list = galleryService.galleryList();
model.addAttribute("list",list);
return "gallery";
}
-> galleryList() 생성 : GalleryService, GalleryDAO
GalleryService.java
public List<GalleryDTO> galleryList() {
return galleryDAO.galleryList();
}
GalleryDAO
public List<GalleryDTO> galleryList() {
return sqlSession.selectList("gallery.galleryList");
}
gallery-mapper.xml
<select id="galleryList" resultType="galleryDTO">
SELECT * FROM gallery
</select>
gallery.jsp
<script type="text/javascript">
function fileCheck(){
location.href = './galleryInsert';
return false; // form의 실제 submit 동작 방지
}
</script>
<section class="page-section" id="gallery">
<div class="container d-flex justify-content-center">
<div class="col-md-6">
<table>
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>이미지</th>
<th>등록일</th>
<th>좋아요</th>
</tr>
</thead>
<tbody>
<c:forEach items="${list }" var="row">
<tr>
<td>${row.gno }</td>
<td>${row.gtitle }</td>
<td>
<img alt="thumbnail" src="./resources/upfile/s_${row.gfile }">
</td>
<td>${row.gdate }</td>
<td>${row.glike }</td>
</tr>
</c:forEach>
</tbody>
</table>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary btn-lg" onclick="location.href='./galleryInsert'">글쓰기</button>
</div>
</div>
</div>
</section>
galleryInsert.jsp
<!-- 갤러리 업로드 폼 -->
<section class="page-section" id="gallery">
<div class="container d-flex justify-content-center">
<div class="col-md-6">
<h2 class="text-center mb-4 mt-4">갤러리</h2>
<form action="/galleryInsert" method="post"
enctype="multipart/form-data" id="galleryForm">
<div class="mb-3">
<label for="gtitle" class="form-label">제목</label> <input
type="text" class="form-control" id="gtitle" name="gtitle">
</div>
<div class="mb-3">
<label for="gcontent" class="form-label">본문</label>
<textarea class="form-control" id="gcontent" name="gcontent"
rows="4" placeholder="내용을 입력하세요"></textarea>
</div>
<div class="mb-3">
<label for="file1" class="form-label">이미지 업로드</label> <input
type="file" accept="image/*" class="form-control" id="file1"
name="file1">
</div>
<div class="d-flex justify-content-end">
<button type="submit" class="btn btn-primary"
onclick="fileCheck()">전송</button>
</div>
</form>
</div>
</div>
</section>
'개발 공부 Today I Learned' 카테고리의 다른 글
[국비 66일차 TIL] 공지사항, 글 삭제, 페이징 (0) | 2024.02.27 |
---|---|
[국비 65일차 TIL] 갤러리 글 상세보기 (0) | 2024.02.26 |
[국비 63일차 TIL] spring 조회수, 좋아요 버튼, myinfo, 이메일 인증 (0) | 2024.02.22 |
[국비 62 xxxxxxx] 로그인 확인, 횟수 제한 (0) | 2024.02.22 |
[국비 62일차 TIL] 로그인 확인, 횟수 제한 (0) | 2024.02.21 |
댓글