오늘이라도
[Spring] 10. 웹사이트 만들기 ⑨ : 공지사항에 첨부 파일 기능 추가 본문
반응형
https://github.com/upcake/Class_Examples
교육 중에 작성한 예제들은 깃허브에 올려두고 있습니다.
gif 파일은 클릭해서 보는 것이 정확합니다.
- 웹사이트 만들기 ⑨ : 공지사항에 첨부 파일 기능 추가 -
package com.hanul.iot;
import java.util.HashMap;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import common.CommonService;
import member.MemberServiceImpl;
import member.MemberVO;
import notice.NoticeServiceImpl;
import notice.NoticeVO;
@Controller
public class NoticeController {
@Autowired private NoticeServiceImpl service;
@Autowired private MemberServiceImpl member;
@Autowired private CommonService common;
//공지사항 목록화면 요청
@RequestMapping("/list.no")
public String list(Model model, HttpSession session) {
//공지사항 클릭 하면 admin으로 자동 로그인
HashMap<String, String> map = new HashMap<String, String>();
//HashMap : 데이터를 담을 자료 구조
map.put("id", "admin");
map.put("pw", "1234");
session.setAttribute("login_info", member.member_login(map));
session.setAttribute("category", "no");
//DB에서 공지 글 목록을 조회해와 목록 화면에 출력
model.addAttribute("list", service.notice_list());
return "notice/list";
}
//신규 공지 글 작성 화면 요청
@RequestMapping("/new.no")
public String notice() {
return "notice/new";
}
//신규 공지 글 저장 처리 요청
@RequestMapping("/insert.no")
public String insert(MultipartFile file, NoticeVO vo, HttpSession session) {
//첨부한 파일을 서버 시스템에 업로드하는 처리
if( !file.isEmpty() ) {
vo.setFilepath(common.upload("notice", file, session));
vo.setFilename(file.getOriginalFilename());
}
vo.setWriter( ((MemberVO) session.getAttribute("login_info")).getId() );
//화면에서 입력한 정보를 DB에 저장한 후
service.notice_insert(vo);
//목록 화면으로 연결
return "redirect:list.no";
}
}
▲NoticeController.java
package notice;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class NoticeServiceImpl implements NoticeService {
@Autowired private NoticeDAO dao;
@Override
public void notice_insert(NoticeVO vo) {
dao.notice_insert(vo);
}
@Override
public List<NoticeVO> notice_list() {
return dao.notice_list();
}
@Override
public NoticeVO notice_detail(int id) {
// TODO Auto-generated method stub
return null;
}
@Override
public void notice_update(NoticeVO vo) {
// TODO Auto-generated method stub
}
@Override
public void notice_delete(int id) {
// TODO Auto-generated method stub
}
}
▲NoticeServiceImpl.java
package notice;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class NoticeDAO implements NoticeService {
@Autowired private SqlSession sql;
@Override
public void notice_insert(NoticeVO vo) {
sql.insert("notice.mapper.insert", vo);
}
@Override
public List<NoticeVO> notice_list() {
return sql.selectList("notice.mapper.list");
}
@Override
public NoticeVO notice_detail(int id) {
// TODO Auto-generated method stub
return null;
}
@Override
public void notice_update(NoticeVO vo) {
// TODO Auto-generated method stub
}
@Override
public void notice_delete(int id) {
// TODO Auto-generated method stub
}
}
▲NoticeDAO.java
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="notice.mapper" >
<select id="list" resultType="notice.NoticeVO">
SELECT ROWNUM no, n.*
FROM (SELECT * FROM notice ORDER BY id) n
ORDER BY no desc
</select>
<insert id="insert">
INSERT INTO notice (title, content, writer, filename, filepath)
VALUES (#{title }, #{content }, #{writer }, #{filename }, #{filepath})
</insert>
</mapper>
▲notice-mapper.xml
package notice;
import java.sql.Date;
public class NoticeVO {
private int id, readcnt, no;
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
private String title, content, writer, filename, filepath;
private Date writedate;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getReadcnt() {
return readcnt;
}
public void setReadcnt(int readcnt) {
this.readcnt = readcnt;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getFilepath() {
return filepath;
}
public void setFilepath(String filepath) {
this.filepath = filepath;
}
public Date getWritedate() {
return writedate;
}
public void setWritedate(Date writedate) {
this.writedate = writedate;
}
}
▲NoticeVO.java
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="core" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>list JSP</title>
</head>
<body>
<h3>공지사항</h3>
<div id="list-top">
<div>
<ul>
<core:if test="${login_info.admin eq 'Y' }">
<li><a class="btn-fill" href="new.no">글쓰기</a></li>
</core:if>
</ul>
</div>
</div>
<table>
<tr>
<th class="w-px60">번호</th>
<th>제목</th>
<th class="w-px100">작성자</th>
<th class="w-px120">작성일자</th>
<th class="w-px60">첨부파일</th>
</tr>
<core:forEach items="${list }" var="vo">
<tr>
<td>${vo. no }</td>
<td>${vo.title }</td>
<td>${vo.writer }</td>
<td>${vo.writedate }</td>
<td></td>
</tr>
</core:forEach>
</table>
</body>
</html>
▲list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>new JSP</title>
</head>
<body>
<h3>신규 공지 글</h3>
<!--
- 파일 첨부 시 form 반드시 갖고 있어야 할 속성
1. 반드시 method는 post이어야만 한다.
2. enctype을 지정한다. ▶ enctype='multipart/form-data'
-->
<form action="insert.no" method="post" enctype="multipart/form-data">
<table>
<tr>
<th class="w-px160">제목</th>
<td><input type="text" name="title" class="need"/></td>
</tr>
<tr>
<th>작성자</th>
<td>${login_info.name }</td>
</tr>
<tr>
<th>내용</th>
<td><textarea name="content" class="need"></textarea></td>
</tr>
<tr>
<th>파일 첨부</th>
<td class="left">
<label>
<input type="file" name="file" id="attach-file"/>
<img src='img/select.png' class="file-img" />
</label>
<span id="file-name"></span>
<span id="delete-file" style="color: red; margin-left: 20px;" ><i class="fas fa-times font-img"></i></span>
</td>
</tr>
</table>
</form>
<div class="btnSet">
<a class="btn-fill" onclick="if(necessary()) $('form').submit()">저장</a>
<a class="btn-empty" href="list.no">취소</a>
</div>
<script type="text/javascript" src="js/need_check.js"></script>
<script type="text/javascript" src="js/file_attach.js"></script>
</body>
</html>
▲new.jsp
@charset "UTF-8";
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR&display=swap');
body {
margin: 0 auto;
text-align: center;
font-size: 16px;
font-family: 'Noto Sans KR', sans-serif;
}
a:link, a:visited {
text-decoration: none;
color: #000;
}
#content {
padding: 20px 0;
min-width: 1024px; /* 창의 최소 크기 지정 */
}
img {
vertical-align: middle; /* 세로축 가운데 정렬 */
}
table {
width: 80%;
margin: 0 auto;
border: 1px solid;
border-collapse: collapse; /* 테두리 겹침 설정 collapse: 겹치지 않게 처리 */
}
table th, table td {
border: 1px solid;
padding: 5px 10px;
}
table td a:hover { font-weight: bold; }
.btnSet { margin-top: 20px; }
a.btn-fill, a.btn-empty {
text-align: center;
padding: 3px 10px;
border:1px solid #3367d6;
border-radius: 3px;
box-shadow: 2px 2px 3px #022d72;
/* 오른쪽, 아래쪽, 번진 정도 */
}
a.btn-fill {
background-color: #3367d6;
color: #fff;
}
a.btn-empty {
background-color: #fff;
color: #3367d6
}
a.btn-fill-s, a.btn-empty-s {
text-align: center;
padding: 1px 10px;
border:1px solid #c4dafc
border-radius: 3px;
box-shadow: 2px 2px 3px #022d72;
font-size: 13px;
}
a.btn-fill-s {
background-color: #bacdfa;
}
a.btn-empty-s {
background-color: #fff;
}
.btnSet a:not(:first-child) {
margin-left: 3px;
}
a:hover { cursor:pointer; }
input {
height: 22px;
padding: 3px 5px;
font-size: 15px;
}
input[type=radio] {
width: 18px;
margin: 0 5px 3px;
vertical-align: middle;
}
table tr td label:not(:last-child) {
margin-right: 20px;
}
.w-pct60 { width: 60% }
.w-pct70 { width: 70% }
.w-pct80 { width: 80% }
.w-px40 { width: 40px }
.w-px60 { width: 60px }
.w-px80 { width: 80px }
.w-px100 { width: 100px }
.w-px120 { width: 120px }
.w-px140 { width: 140px }
.w-px160 { width: 160px }
.w-px180 { width: 180px }
.w-px200 { width: 200px }
.left { text-align: left }
.right { text-align: right }
.font-img { cursor: pointer; }
ul { list-style: none; padding: 0; }
#list-top{ width: 80%; padding: 20px 10%;}
#list-top ul { margin:0; display:flex; }
#list-top ul:last-child { float: right; }
#list-top div { width: 100%; }
#list-top ul li * { vertical-align:middle; }
input[name=title] { width:calc(100% - 14px) }
textarea[name=content] { width:calc(100% - 6px); height: 150px; resize: none;}
/* 파일 첨부 */
.file-img { width: 18px; height:18px; cursor:poinrter; }
#attach-file, #delete-file { display:none; }
▲common.css
/**
* 첨부파일 관련 처리
*/
/* 파일을 선택했을 때 파일명이 보이게 처리 */
$('#attach-file').on('change', function(){
$('#file-name').text( this.files[0].name );
$('#delete-file').css('display', 'inline');
});
$('#delete-file').on('click', function(){
$('#file-name').text('');
$('#delete-file').css('display', 'none');
$('#attach-file').val('');
});
▲file_attach.js
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%> <!-- 타일을 사용하기 위한 라이브러리 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${category eq 'cu' ? '고객 관리' : (category eq 'no' ? '공지사항' : (category eq 'bo' ? '방명록' : (category eq 'da' ? '공공 데이터' : (category eq 'join' ? '회원가입' : '') ) ) ) } ${empty category ? '' : ' : ' }IoT</title>
<!-- 브라우저 탭의 작은 아이콘 설정 -->
<link rel="icon" type="image/x-icon" href="img/icon.ico" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/js/all.min.js"></script>
<!-- cdnjs.com에서 가져온 fontawesome cdn 라이브러리 -->
<!-- 모든 화면에서 사용하기 위해 join.jsp에 있던 코드를 layout.jsp로 옮겨온다. -->
</head>
<body>
<!-- 각 jsp 파일의 인클루드 단을 없애도 된다. -->
<tiles:insertAttribute name="header" />
<!-- 각 jsp 파일의 div id="content" 부분을 없애도 된다. -->
<div id="content">
<tiles:insertAttribute name="content" />
</div>
<tiles:insertAttribute name="footer" />
</body>
</html>
▲layout.jsp
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hanul</groupId>
<artifactId>iot</artifactId>
<name>iot</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.2.2.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<!-- 스프링에서 JDBC를 사용하기 위한 dependency -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<!-- DBCP dependency -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.oracle.ojdbc/ojdbc8 -->
<!-- 오라클용 jdbc ojdbc8 -->
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<!-- Mybatis 프레임워크를 사용하기 위한 dependency -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<!-- MyBatis 스프링 dependency -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- 화면에 template를 지정하는 라이브러리 -->
<!-- https://mvnrepository.com/artifact/org.apache.tiles/tiles-jsp -->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.8</version>
</dependency>
<!-- boolean 타입 데이터를 문자 타입으로 자동 변환해주는 라이브러리 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
<!-- 이메일 전송 라이브러리 -->
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-email -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.5</version>
</dependency>
<!-- 파일 첨부(업로드) 라이브러리 -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.8</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
▲pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- context : 외부 파일을 사용 할 수 있도록 경로를 설정 -->
<context:property-placeholder location="classpath:data/db.properties" />
<!-- 빈을 등록해놓을 설정 파일 -->
<!-- id를 지정하면 다른 빈에서 참조할 수 있음 -->
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
<!-- property : 데이터를 담을 필드를 의미 -->
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<!-- myBatis 등록하는 빈 -->
<!-- DB연결, 쿼리문 역할 -->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dbcp"></property>
<property name="mapperLocations" value="classpath:sqlmap/*-mapper.xml"></property>
</bean>
<!-- Setter가 있다면 property로 필드에 데이터를 넣을 수 있지만 (자동 완성 기능으로 확인가능) -->
<!-- Setter가 없다면 생성자를 만들어서 데이터를 넣는다. -->
<bean class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="factory"/>
</bean>
<!-- 파일 업로드 객체 생성 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
</bean>
</beans>
▲default.xml
package common;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.MultiPartEmail;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@Service
public class CommonService {
public void sendEmail(String email, String name, HttpSession session) {
//1. 기본 이메일 전송 처리
//sendSimple(email, name);
//2. 첨부 파일 있는 이메일 전송 처리
//session이 있어야 파일 첨부가 가능
//sendAttach(email, name, session);
//3. HTML 태그 이메일 전송 처리
sendHtml(email, name, session);
};
private void sendSimple(String email, String name) {
SimpleEmail mail = new SimpleEmail();
mail.setHostName("smtp.naver.com"); //메일 전송 서버 지정, 네이버 메일 - 환경설정 - pop3 설정
mail.setCharset("utf-8"); //인코딩 설정
mail.setDebug(true); //메일 전송 과정 추적해서 콘솔에 띄워줌
mail.setAuthentication("아이디", "비밀번호"); //로그인하기 위해 정보 입력
mail.setSSLOnConnect(true); //입력한 정보로 로그인 요청
try {
mail.setFrom("보내는 메일", "관리자"); //보내는 사람 메일 / 이름 설정
mail.addTo(email, name); //받는 사람 메일 / 이름, 회원가입 페이지에에서 가져온다.
mail.addTo("받을 메일", "수신자"); //복수의 사람 지정 가능
mail.setSubject("회원가입 축하"); //메일 제목
mail.setMsg(name + "님! 가입을 축하드립니다!"); //메일 내용
mail.send(); //메일 발송
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private void sendAttach(String email, String name, HttpSession session) {
MultiPartEmail mail = new MultiPartEmail();
mail.setHostName("smtp.naver.com"); //메일 전송 서버 지정, 네이버 메일 - 환경설정 - pop3 설정
mail.setCharset("utf-8"); //인코딩 설정
mail.setDebug(true); //메일 전송 과정 추적해서 콘솔에 띄워줌
mail.setAuthentication("아이디", "비밀번호"); //로그인하기 위해 정보 입력
mail.setSSLOnConnect(true); //입력한 정보로 로그인 요청
try {
mail.setFrom("보내는 메일", "관리자"); //보내는 사람 메일 / 이름 설정
mail.addTo(email, name); //받는 사람 메일 / 이름, 회원가입 페이지에에서 가져온다.
mail.addTo("받을 메일", "수신자"); //복수의 사람 지정 가능
mail.setSubject("첨부 파일 테스트"); //메일 제목
mail.setMsg(name + "님! 가입을 축하드립니다!\n 첨부 파일 테스트"); //메일 내용
//파일 첨부하기
EmailAttachment file = new EmailAttachment();
//① 물리적 디스크내 파일 첨부
file.setPath("D:\\이력서-자소서-양식.hwp");
mail.attach(file);
//② 프로젝트 내의 파일 첨부
file = new EmailAttachment();
file.setPath(session.getServletContext().getRealPath("resources/images/logo.png"));
mail.attach(file);
//③ URL을 통해 파일 첨부
file = new EmailAttachment();
file.setURL(new URL("https://mvnrepository.com/assets/images/392dffac024b9632664e6f2c0cac6fe5-logo.png"));
mail.attach(file);
mail.send(); //메일 발송
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private void sendHtml(String email, String name, HttpSession session) {
HtmlEmail mail = new HtmlEmail();
mail.setHostName("smtp.naver.com"); //메일 전송 서버 지정, 네이버 메일 - 환경설정 - pop3 설정
mail.setCharset("utf-8"); //인코딩 설정
mail.setDebug(true); //메일 전송 과정 추적해서 콘솔에 띄워줌
mail.setAuthentication("아이디", "비밀번호"); //로그인하기 위해 정보 입력
mail.setSSLOnConnect(true); //입력한 정보로 로그인 요청
try {
mail.setFrom("보내는 메일", "관리자"); //보내는 사람 메일 / 이름 설정
mail.addTo(email, name); //받는 사람 메일 / 이름, 회원가입 페이지에에서 가져온다.
mail.addTo("받을 메일", "수신자"); //복수의 사람 지정 가능
mail.setSubject("HTML 메일 테스트");
StringBuffer msg = new StringBuffer();
msg.append("<html>");
msg.append("<body>");
msg.append("<a href='https://mvnrepository.com'><img src='https://mvnrepository.com/assets/images/392dffac024b9632664e6f2c0cac6fe5-logo.png' /></a>");
msg.append("<hr>");
msg.append("<h3>HTML 메일 테스트</h3>");
msg.append("<p>가입을 축하드립니다.</p>");
msg.append("<p>HTML 메일 테스트</p>");
msg.append("</body>");
msg.append("</html>");
mail.setHtmlMsg(msg.toString());
EmailAttachment file = new EmailAttachment();
file.setPath(session.getServletContext().getRealPath("resources/css/common.css"));
mail.attach(file);
file = new EmailAttachment();
file.setURL(new URL("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"));
mail.attach(file);
mail.send();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
//첨부 파일 업로드 처리////////////////////////////////////////////////////////
public String upload(String category, MultipartFile file, HttpSession session) {
//서버의 업로드할 물리적 위치
// workspace/.metadata/....../wtpwebapps/iot/resources
String resources = session.getServletContext().getRealPath("resources");
String upload = resources + "/upload";
//업로드할 파일의 형태 : .../upload/notice/2020/07/13/abc.txt
//String folder = upload + "/upload/2020/07/13";
String folder = upload + "/" + category + "/" + new SimpleDateFormat("yyyy/MM/dd").format(new Date());
//폴더가 없다면 폴더를 생성
File f = new File(folder);
if(!f.exists()) { f.mkdirs(); } //폴더가 존재하지 않으면 경로 생성
//동시 다발적 동일명의 파일 업로드를 위한 고유 ID 부여: afd324adfa_abc.txt
String uuid = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
try {
file.transferTo( new File(folder, uuid) );
} catch (Exception e) {
System.out.println(e.getMessage());
}
// /upload/.../asdfadsfsa_abc.txt ▶ 업로드한 파일의 경로를 반환
// ① folder.replace(resources, "")
// ② folder.substring(resources.length()) + "/" + uuid;
return folder.substring(resources.length()) + "/" + uuid;
}
}
▲CommonService.java
반응형
'취업성공패키지 SW 개발자 교육 > Spring' 카테고리의 다른 글
[Spring] 12. 웹사이트 만들기 ⑪ : 공지글 수정, 목록에서 첨부파일 다운로드, 페이징 밑작업 (0) | 2020.07.15 |
---|---|
[Spring] 11. 웹사이트 만들기 ⑩ : 파일 첨부, 업로드, 다운로드, 글 삭제 (0) | 2020.07.14 |
[Spring] 9. 웹사이트 만들기 ⑧ : 첨부 파일 메일, HTML 메일 발송, 공지사항 목록 조회 (1) | 2020.07.10 |
[Spring] 8. 웹사이트 만들기 ⑦ : 회원가입 완성, 축하 메일 발송 (0) | 2020.07.09 |
[Spring] 7. 웹사이트 만들기 ⑥ : 회원가입 양식 유효성 검사 (4) | 2020.07.08 |