오늘 할 거
- 읽음 수 올리기
툴바에 대해...
<script type="text/javascript">
$(document).ready(function() {
$('#summernote').summernote({
height: 600, // 에디터 높이
lang: 'ko-KR', // default: 'en-US'
placeholder: "write here...",
fontNames : ['D2Coding', 'Arial Black', 'Comic Sans MS', 'Courier New'], // 폰트 나열
toolbar: [
// [groupName, [list of button]]
['style', ['bold', 'italic', 'underline', 'clear']],
/* ['font', ['strikethrough', 'superscript', 'subscript']], */
['fontname', ['fontname','fontsize', 'color']],
['para', ['ul', 'ol', 'paragraph']],
/* ['height', ['height']] */
['table', ['table','link', 'picture', 'video']],
['view', ['fullscreen', 'codeview', 'help']]
]
});
});
</script>
위 모양이었는데
툴바의 table 부분 한줄로 묶어서 보여주려면
<script type="text/javascript">
$(document).ready(function() {
$('#summernote').summernote({
height: 600, // 에디터 높이
lang: 'ko-KR', // default: 'en-US'
placeholder: "write here...",
fontNames : ['D2Coding', 'Arial Black', 'Comic Sans MS', 'Courier New'], // 폰트 나열
toolbar: [
// [groupName, [list of button]]
['style', ['bold', 'italic', 'underline', 'clear']],
/* ['font', ['strikethrough', 'superscript', 'subscript']], */
['fontname', ['fontname','fontsize', 'color']],
['para', ['ul', 'ol', 'paragraph']],
/* ['height', ['height']] */
['table', ['table','link', 'picture', 'video', 'fullscreen', 'codeview', 'help']]
]
});
});
</script>
BoardService
public BoardDTO detail(int no) {
//2024-02-22 psd 요구사항 확인
//로그인 했어? -> 읽음 수 올리기
if (util.getSession().getAttribute("mid") != null) {
//DTO 객체 만들기 = 번호 + 아이디
BoardDTO dto = new BoardDTO();
dto.setBoard_no(no);
dto.setMid(String.valueOf(util.getSession().getAttribute("mid")));
//이미 읽은 사람은 조회수 안 올리기
int result = boardDAO.alreadyRead(dto);
if(result == 0) {
boardDAO.viewCount(dto);
}
}
return boardDAO.detail(no);
}
BoardDAO
public int viewCount(BoardDTO dto) {
return sqlSession.insert("board.viewCount", dto);
}
public int alreadyRead(BoardDTO dto) {
return sqlSession.selectOne("board.viewCheck", dto);
}
board-mapper.xml
<insert id="viewCount" parameterType="boardDTO">
INSERT INTO visitcount (board_no, mno)
VALUES (#{board_no}, (SELECT mno FROM member WHERE mid=#{mid}))
</insert>
<select id="viewCheck" parameterType="boardDTO" resultType="Integer">
SELECT COUNT(*)
FROM visitcount
WHERE board_no=#{board_no} AND mno=(SELECT mno FROM member WHERE mid=#{mid})
</select>
dynamic query는 select 결과 있을 때, 없을 때 쓰는 게 좋다...
public BoardDTO detail(int no) {
if (util.getSession().getAttribute("mid") != null) {
//DTO 객체 만들기 = 번호 + 아이디
BoardDTO dto = new BoardDTO();
dto.setBoard_no(no);
dto.setMid(String.valueOf(util.getSession().getAttribute("mid")));
//이미 읽은 사람은 조회수 안 올리기
boardDAO.viewCount(dto);
}
return boardDAO.detail(no);
}
<insert id="viewCount" parameterType="boardDTO">
<selectKey keyProperty="board_count" resultType="Integer" order="BEFORE">
SELECT COUNT(*)
FROM visitcount
WHERE board_no=#{board_no} AND mno=(SELECT mno FROM member WHERE mid=#{mid})
</selectKey>
<if test="board_count == '0'">
INSERT INTO visitcount (board_no, mno)
VALUES (#{board_no}, (SELECT mno FROM member WHERE mid=#{mid}))
</if>
</insert>
if 아닐 때 실행할 쿼리가 없어서 안되는...
임시로 10번 글에 저장하는 쿼리로 해서 실행함
if test에 들어가는 board_count는 dto에 있는 거
<insert id="viewCount" parameterType="boardDTO">
<selectKey keyProperty="board_count" resultType="Integer" order="BEFORE">
SELECT COUNT(*)
FROM visitcount
WHERE board_no=#{board_no} AND mno=(SELECT mno FROM member WHERE mid=#{mid})
</selectKey>
<if test="board_count == 0">
INSERT INTO visitcount (board_no, mno)
VALUES (#{board_no}, (SELECT mno FROM member WHERE mid=#{mid}))
</if>
<if test="board_count != 0">
INSERT INTO visitcount (board_no, mno)
VALUES (10, (SELECT mno FROM member WHERE mid=#{mid}))
</if>
</insert>
<insert id="viewCount" parameterType="boardDTO">
<selectKey keyProperty="board_count" resultType="Integer" order="BEFORE">
SELECT COUNT(*)
FROM visitcount
WHERE board_no=#{board_no} AND mno=(SELECT mno FROM member WHERE mid=#{mid})
</selectKey>
<if test="board_count == 0">
INSERT INTO visitcount (board_no, mno)
VALUES (#{board_no}, (SELECT mno FROM member WHERE mid=#{mid}))
</if>
<if test="board_count != 0">
SELECT COUNT(*) FROM dual
</if>
</insert>
p446 AOP 스프링 3가지..? 중 하나
p487 파일 업로드
DB 암호화, 시큐리티...
가입하기, 이메일인증...
로그인 안했으면 댓글쓰기 창과 하트 버튼 기능 없애기
책 p366, p373. 경로 변수
Path Variable 사용법
menu.jsp
<li class="nav-item"><a class="nav-link" href="myInfo@${sessionScope.mid } }">Hello, ${sessionScope.mname }!</a></li>
@
기준으로 자를 것. (위 링크에서는 /
기준으로 나눔)
pom.xml에 이메일
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-email -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.5</version>
</dependency>
outlook에서 msn 이메일 하나 만들기 (이거용) -> 이 이메일은 절대 깃허브 올리지 말기
naver, google 이메일 막힘? (사람이 보내는건 되는데 기계가 보내는건 막았다?)
outlook 이메일 사이트
SMTP, 포트번호 25
앱 및 장치에서 Outlook의 메시지를 삭제하도록 허용... (삭제는 안하고 메일만 보낼거라 안해도 된다)
여기 아래 숫자들 쓸 거
pom 연결되면 임포트 된다
import org.apache.commons.mail.SimpleEmail;
public void sendEmail(String email, String title, String key) throws EmailException {
//mail 보내기 -> 지금은 controller에다 치지만 util로 보낼 것.
String emailAddr = MailInfo.emailId;//이메일 주소 MailInfo.emailId <- 여기 변수로 보내는 사람 이메일주소
String name = "하츄초콜릿";//보내는 사람 이름
String passwd = MailInfo.emailPw;//암호 MailInfo.emailPw
String hostName ="smtp-mail.outlook.com"; //SMTP server name
int port = 587; //포트 번호
SimpleEmail simpleEmail = new SimpleEmail(); // 전송할 메일
simpleEmail.setCharset("UTF-8"); //언어셋 설정
simpleEmail.setDebug(true); //화면 상에 메일 잘 가고 있는지 보여줌
simpleEmail.setHostName(hostName);
simpleEmail.setAuthentication(emailAddr, passwd);
simpleEmail.setSmtpPort(port);
simpleEmail.setStartTLSEnabled(true); //startTLS로 암호화하고 있다
simpleEmail.setFrom(emailAddr, name);
simpleEmail.addTo(email); //받는 사람 (우리 사이트에 가입한 회원)
simpleEmail.setSubject(title); //제목
simpleEmail.setMsg("인증번호는 [" + key + "] 입니다"); //본문 내용 text (우리 상황에선 text)
simpleEmail.send(); //전송하기
}
타이머 내려가는동안 뜨는... 알림창 있더라
//이거 만들어야 Toast가 된다.
const Toast = Swal.mixin({
toast: true,
position: 'center-center',
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
}
});
function emailAuth() {
$.ajax({
url: './emailAuth', //ajax용 rest controller에 만들자.
type: 'post',
dataType: 'text',
//data: , //데이터 안 보내고 동작만 시킬 것
success: function(result){
if(result == 1) {
Swal.fire("이메일을 발송했습니다.", "결과 : " + result, "success");
} else {
Toast.fire('통신문제', '통ㅇ신문제가 발생햇습니다.', 'info');
//Swal.fire("이메일 발송 실패!", "문제가 발생했습니다.", "info");
}
},
error: function(request, status, error){
//접속불가거나 스테이터스나 에러
Swal.fire("통신 실패", "문제가 발생했습니다 : " + error, "error");
}
});
}
파일 이름을... RestController.java로 하면 안된다. 어노테이션이랑 겹쳐서,,
@RestController
어노테이션 붙이면
그 아래 메소드들은 @ResponseBody
를 뺄 수 있다. 어차피 다 Rest라서
(비동기통신 몰아넣는 파일용. API들 다 이렇게. json이나 xml이나...)
얘네는 view가 없다.
- ajax로 한 거
RestController(이름은 RestFullController로 바꿈) -> RestService -> RestDAO -> rest-mapper.xml로 가도록...
public class RestFullController {
@Autowired
private BoardService boardService;
@Autowired
private RestService restService; //REST service 다 몰아두자.
// 전에 했던 거
@PostMapping("/restDetail")
public BoardDTO restDetail(@Param("no") int no) {
//System.out.println("restDetail : " + no);
BoardDTO detail = boardService.detail(no); //dto는 autowired 안씀(어노테이션 없어서 그런가)
System.out.println(detail.getBoard_title());
//System.out.println(detail.getBoard_content());
return detail;
}
@PostMapping("/emailAuth")
public int emailAuth() {
//로그인 검사, key 저장 등 service에서 한다.
return restService.sendEmail();
}
}
@Service
public class RestService {
@Autowired
private RestDAO restDAO;
@Autowired
private Util util;
public int sendEmail() {
//로그인검사 controller 말고 service에서
if(util.getSession().getAttribute("mid") != null) {
//메일 발송 + key 데이터베이스에 저장
String email = getEmail(String.valueOf(util.getSession().getAttribute("mid")));
//인증번호 생성
String key = util.createKey();
MemberDTO dto = new MemberDTO();
dto.setMemail(email);
dto.setMkey(key);
dto.setMid(String.valueOf(util.getSession().getAttribute("mid")));
restDAO.setKey(dto); //db에 키 저장하기
//util.sendEmail(email, key); //너무 보내면 차단되니까 진짜 보내지는 않고...
return 1;
} else {
return 0;
}
}
//sendEmail()에서 쓸려고 만든...
private String getEmail(String id) {
return restDAO.getEmail(id);
}
}
@Repository
public class RestDAO {
@Autowired
private SqlSession sqlSession;
public String getEmail(String id) {
return sqlSession.selectOne("rest.getEmail", id);
}
public void setKey(MemberDTO dto) {
sqlSession.update("rest.setKey", dto);
}
}
<mapper namespace="rest">
<select id="getEmail" parameterType="String" resultType="String">
SELECT memail FROM member WHERE mid=#{id}
</select>
<update id="setKey" parameterType="memberDTO">
UPDATE member SET mkey=#{mkey} WHERE memail=#{memail} AND mid=#{mid}
</update>
</mapper>
크