본문 바로가기
개발 공부 Today I Learned

[국비 63일차 TIL] spring 조회수, 좋아요 버튼, myinfo, 이메일 인증

by 개발자신입 2024. 2. 22.
반응형

20240222 

조회수 올리기
좋아요 버튼
myinfo
이메일 인증번호 보내기


BoardService.java

‌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) util.getSession().getAttribute("mid")); // if문으로 다시 물어보기 ​​​​​​​​​​​​​​​​​​​ ‌‌} ‌‌// 컨트롤러에는 int reNo, 서비스에는 int no (데이터 타입을 확인해야함) ‌‌return boardDAO.detail(no); }

 

countUP 메소드 생성

-> countUP()을 BoardDAO에 create (그냥 만드는건가...?)

BoardDAO.java

countUP은 return이 없음

‌public void countUP(BoardDTO dto) { ‌‌sqlSession.insert("board.countUP", dto); }

 

-> countUP()을 board-mapper.xml에 insert문으로

board-mapper.xml

‌<insert id="countUP" parameterType="boardDTO"> ‌‌INSERT INTO visitcount (board_no, mno) ‌‌VALUSE (${board_no}, (SELECT mno FROM member WHERE mid=#{mid})) ‌</insert>

 

->  BoardService if문boardDAO.countUP(dto); 추가 

BoardService.java

‌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) util.getSession().getAttribute("mid")); // if문으로 읽었는지 다시 물어보기 ‌‌‌boardDAO.countUP(dto); // 다이나믹 코드..? ‌‌} ‌‌return boardDAO.detail(no); }

 

board-mapper.xml

‌<!-- 2024-02-22 --> ​​​<insert id="countUP" 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> </mapper>

 

BoardDTO.java

board_write, mid 추가

import lombok.Data; @Data public class BoardDTO { ‌private int board_no, board_count, comment; ‌private String board_title, mname, board_write, board_date, board_content, board_ip, mid; }

좋아요 버튼 만들기


detail.jsp

ip, date, like 앞에 아이콘 이미지 넣어주기.

<div class="text-end"> ‌<div> ‌​​​​<img alt="ip" src="./assets/img/ip-address.png"> ${c.cip } |  ​​​​​​​​<img alt="date" src="./assets/img/clocky.png"> ${c.cdate } |  ‌<img alt="like" src="./assets/img/likey.png" onclick="like(${c.no })"> ${c.clike } ​​​​</div> </div>

 

like() function

클릭하면 alert 팝업 뜨도록 Swal.fire();

function like(cno){ ‌Swal.fire("좋아요", "하트하트", "success"); ‌setTimeout(function(){ ‌‌location.href="./likeUp?no=${detail.board_no}&cno="+cno; }, 2000); }

 

Util.java

// 2024-02-22 숫자인지 검사하는 메소드 public boolean intCheck(String str) { ‌​​​​​​try { ‌​​​​​​​​​​Integer.parseInt(str); ‌​​​​​​​​​​return true; ‌​​​​​​​} catch (Exception e) { ‌​​​​​​​​​​return false; ‌​​​​​​​} ‌​​​​} public int str2Int2(String str) { ‌‌return Integer.parseInt(str.replaceAll("[^0-9]", "")); ‌​​}

BoardController.java

‌‌// 2024-02-22 요구사항 확인 psd ‌‌// return값이 오면 다시 내 글로 돌아가기 ​​​​​​​​ ‌‌@GetMapping("/likeUp") ‌‌public String likeUp(@RequestParam("no") String no, @RequestParam("cno") String cno) { // CommentDTO에 있음: 글 no, 댓글 cno ‌‌‌System.out.println(no); ‌‌‌System.out.println(cno); ‌‌‌if(util.intCheck(no) && util.intCheck(cno)) { ‌‌‌‌CommentDTO dto = new CommentDTO(); ‌‌‌‌dto.setBoard_no(util.str2Int(no)); ‌‌‌‌dto.setNo(util.str2Int(cno)); ‌‌‌‌ ‌‌‌‌boardService.likeUp(dto); ‌‌‌‌‌‌‌ ‌‌‌‌return "redirect:/detail?no="+dto.getBoard_no(); ‌‌‌} else { ‌‌‌‌return "redirect:/error"; ‌‌‌} ‌‌}

 

likeUp() 메소드 생성

-> likeUp() 만들기  : BoardService, BoardDAO

 

BoardService.java

‌public int likeUp(CommentDTO dto) { ‌‌return boardDAO.liekUp(dto); }

BoardDAO.java

‌public int liekUp(CommentDTO dto) { ‌‌return sqlSession.update("board.likeUp", dto); }

board-mapper.xml

​​​<update id="likeUp" parameterType="commentDTO"> ‌‌UPDATE comment SET clike = clike + 1 WHERE cno=#{no} ​​​</update>

 


마이페이지, 이메일, 인증번호


menu.jsp

@${sessionScope.mid} : /myInfo@로그인아이디

 

 

@PathVariable 이란?

REST API에서 URI에 변수가 들어가는걸 실무에서 많이 볼 수 있다.

예를 들면, 아래 URI에서 밑줄 친 부분이 @PathVariable로 처리해줄 수 있는 부분이다.

localhost:8080/api/user/1234

bugs.co.kr/album/4062464

 

<li class="nav-item"><a class="nav-link" href="./myInfo@${sessionScope.mid }">${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>

 

LoginController.java

‌// http://172.30.1.150/myInfo@test6 ‌@GetMapping("/myInfo@{id}") // @뒤 id를 경로 변수로 씀 ‌public String myInfo(@PathVariable("id") String id) { ‌‌// System.out.println("id : "+id); ‌‌return "myinfo"; }

 

-> myinfo.jsp 생성

myinfo.jsp

인증번호 이메일로 발송하기와 버튼 form 만들기

‌<!-- LOGIN --> ‌<section class="page-section" id="my-info"> ‌‌<div class="d-flex justify-content-center"> ‌‌‌<div class="text-center"> ‌‌‌‌<div> ‌‌‌‌‌등록한 email로 인증번호가 발송되었습니다. ‌‌‌‌‌email을 확인 후 인증번호를 입력하세요. ‌‌‌‌‌<form action=""> ‌‌‌‌‌‌<input type="number" name="number"> ‌‌‌‌‌‌<button>인증하기</button> ‌‌‌‌‌</form> ‌‌‌‌</div> ‌‌‌</div> ‌‌</div> ‌</section>

 

LoginController.java

simpleEmail.setFrom(emailAddr, name); 이 부분에서 throws EmailException 설정해야함.

‌// http://172.30.1.150/myInfo@test6 ‌@GetMapping("/myInfo@{id}") // @뒤 id를 경로 변수로 씀 ‌public String myInfo(@PathVariable("id") String id) throws EmailException { // System.out.println("id : "+id); ‌‌ ‌‌// 메일 보내기.. ‌‌String emailAddr = "아이디@outlook.kr"; // 이메일 주소 ‌‌String name = "보내는 사람 이름"; ‌‌String passwd = "비번"; ‌‌String hostName = "smtp-mail.outlook.com"; ‌‌int port = 587; ‌‌ ‌‌SimpleEmail simpleEmail = new SimpleEmail(); // 전송할 메일 ‌‌simpleEmail.setCharset("UTF-8"); ‌‌simpleEmail.setDebug(true); ‌‌simpleEmail.setHostName(hostName); // 보내는 서버 설정 = 고정 ‌‌simpleEmail.setAuthentication(emailAddr, passwd); // 보내는 사람 인증 = 고정 ‌‌simpleEmail.setSmtpPort(port); // 사용할 port번호 ‌‌simpleEmail.setStartTLSEnabled(true); // 인증방법 = 고정 ‌‌simpleEmail.setFrom(emailAddr, name); // 보내는 사람 email, 이름 ‌‌simpleEmail.addTo("받는사람@메일.com"); // 받는사람 ‌‌simpleEmail.setSubject("15번 페이지 인증번호입니다."); // 제목 ‌‌simpleEmail.setMsg("인증번호는 [2077] 입니다."); // 내용 text ‌‌simpleEmail.send(); ‌‌ ‌‌return "myinfo"; } }

Util.java

메일 보내는 서식 Util.java로 옮기기

‌// 메일보내기 ‌public void sendEmail(String email, String key) throws EmailException { ‌‌ ‌‌String emailAddr = "------@outlook.kr"; // 이메일 주소 ‌‌String name = "보내는 사람 이름"; ‌‌String passwd = ""; ‌‌String hostName = "smtp-mail.outlook.com"; ‌‌int port = 587; ‌‌ ‌‌SimpleEmail simpleEmail = new SimpleEmail(); // 전송할 메인 ‌‌simpleEmail.setCharset("UTF-8"); ‌‌simpleEmail.setDebug(true); ‌‌simpleEmail.setHostName(hostName); // 보내는 서버 설정 = 고정 ‌‌simpleEmail.setAuthentication(emailAddr, passwd); // 보내는 사람 인증 = 고정 ‌‌simpleEmail.setSmtpPort(port); // 사용할 port번호 ‌‌simpleEmail.setStartTLSEnabled(true); // 인증방법 = 고정 ‌‌simpleEmail.setFrom(emailAddr, name); // 보내는 사람 email, 이름 ‌‌simpleEmail.addTo(email); // 받는사람 ‌‌simpleEmail.setSubject("15번 사이트 인증번호입니다!"); // 제목 ‌‌simpleEmail.setMsg("인증번호는 [" + key + "] 입니다."); // 내용 text ‌‌simpleEmail.send(); }

 

 

-> LoginController에 적었던 메일 보내기 서식을 util에 저장한 후 불러서 사용

 

util.sendEmail("가입한 사람의 email", "인증번호");

@GetMapping("/myInfo@{id}") // @뒤 id를 경로 변수로 씀 public String myInfo(@PathVariable("id") String id) throws EmailException { ‌‌ ‌‌util.sendEmail("가입한 사람의 email", "인증번호"); ‌‌return "myinfo"; } }

 

-> Util (내꺼) import 하기

@Autowired private Util util;

 

LoginController.java

메일 보내기 코드를 util로 옮긴 후의 코드임.

util.sendEmail(email, key); 이거만 불러오면 되므로 간단해짐..

‌@Autowired ‌private Util util; ‌// http://172.30.1.150/myInfo@test6 ‌@GetMapping("/myInfo@{id}") // @뒤 id를 경로 변수로 씀 ‌public String myInfo(@PathVariable("id") String id) throws EmailException { ‌‌String email = loginService.getEmail((String) util.getSession().getAttribute("mid")); ‌‌ ‌‌util.sendEmail("이메일주소", "인증번호"); ‌‌return "myinfo"; }

 

getEmail 메소드 생성

-> getEmail을 LoginService, LoginDAO에 만들어주기

 

LoginService.java

- 서비스에 만들어 둔 getEmail은 나중에 Rest로 옮김.

public String getEmail(String email) { ‌‌return loginDAO.getEmail(email); }

LoginDAO.java

public String getEmail(String id){ return sqlSession.selectOne("login.getEmail", id); }

login-mapper.xml

<select id="getEmail" parameterType="String" resultType="String"> ‌SELECT memail FROM member WHERE mid=#{id} </select>

 

LoginController.java

‌@GetMapping("/myInfo@{id}") // @뒤 id를 경로 변수로 씀 ‌public String myInfo(@PathVariable("id") String id) throws EmailException { ‌‌ ‌‌String email = loginService.getEmail((String) util.getSession().getAttribute("mid")); ‌‌String key = util.createKey(); ‌‌util.sendEmail(email, "인증번호"); ‌‌return "myinfo"; } }

createKey 생성

-> createKey을 Util에 생성 : 인증번호를 랜덤으로 보내기 위해.

‌public String createKey() { ‌‌Random r = new Random(); ‌‌r.setSeed(System.currentTimeMillis()); ‌‌String key = r.nextInt(10) + "" + r.nextInt(10) + r.nextInt(10) + r.nextInt(10); ‌‌return key; }

 

-> createKey 생성 후에 컨트롤러에서 변수명 변경하기

LoginController.java

util.sendEmail 변수 변경 : util.sendEmail(email, key);

 

-> DB에 key 생성 (mkey)

`mkey` VARCHAR(10) NULL DEFAULT NULL COLLATE

 

LoginController.java

‌@GetMapping("/myInfo@{id}") // @뒤 id를 경로 변수로 씀 ‌public String myInfo(@PathVariable("id") String id) throws EmailException { // System.out.println("id : "+id); ‌‌ ‌‌// 로그인 여부 확인하기 ‌‌if(util.getSession().getAttribute("mid") != null) { ‌‌‌ ‌‌‌// 인증 요청하기 = Ajax용으로 빼두기 ‌‌‌// loginService.myInfo(); ‌‌‌ ‌‌‌return "myinfo"; ‌‌} else { ‌‌‌return "redirect:/login?error=error"; ‌‌} } }

 

myinfo.jsp

‌<!-- LOGIN --> ‌<section class="page-section" id="my-info"> ‌‌<div class="d-flex justify-content-center"> ‌‌‌<div class="text-center"> ‌‌‌ ‌‌‌‌<button onclick="emailAuth()">인증번호 요청하기 😱</button> ‌‌‌‌ ‌‌‌‌<div> ‌‌‌‌‌등록한 email로 인증번호가 발송되었습니다.<p> ‌‌‌‌‌email을 확인 후 인증번호를 입력하세요. ‌‌‌‌‌<form action=""> ‌‌‌‌‌‌<input type="number" name="number"> ‌‌‌‌‌‌<button>인증하기</button> ‌‌‌‌‌</form> ‌‌‌‌</div> ‌‌‌</div> ‌‌</div> ‌</section>

 

 

emailAuth() 메소드 생성

-> 버튼 emailAuth() function 만들어주기 (Ajax사용을 위해 jQuery 스크립트 추가하기)

 

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" ‌crossorigin="anonymous" referrerpolicy="no-referrer"> </script>
<script type="text/javascript"> function emailAuth(){ ‌$.ajax({ ‌‌url : './emailAuth', ‌‌type : 'post', ‌‌dataType : 'text', ‌‌success : function(result){ ‌‌‌if(result == 1){ ‌‌‌‌Swal.fire("전송했습니다.", "결과 : " + result, "success"); ‌‌‌} else { ‌‌‌‌Swal.fire("긴급상황", "문제가 발생했습니다.", "Info"); ‌‌‌} ‌‌}, ‌‌error : function(request, status, error){ ‌‌‌‌Swal.fire("훠우~", "문제가 발생했네요~" + error, "Error"); ‌‌} }); } </script>

-> Ajax 용도 코드(비동기 통신 코드)는 RestFullController.java에 입력해주기.

 

* 여기에서부터 갑자기 Rest로 넘어감. 기존에 썼던 코드도 Rest로 옮긴 것들이 많다. 


RestFullController.java

‌@PostMapping("/emailAuth") ‌public @ResponseBody int emailAuth() { ‌‌return 1; }

 

@Controller 를 @RestController 로 변경하기 => @ResponseBody를 빼고 동작 하게 함.

 

RestService.java

RestFullController에 RestService 생성하기 -> class파일까지 생성

@Autowired private RestService restService;

 

RestFullController.java

전체코드

@RestController public class RestFullController { ‌@Autowired ‌private BoardService boardService; ‌@Autowired ‌private RestService restService; // 없어서 생성함 ‌@Autowired ‌private Util util; ‌@PostMapping("/restDetail") ‌public BoardDTO restDetail(@Param("no") int no) { // 결과는 body에 출력해 (view를 안 보여주게) ‌‌BoardDTO detail = boardService.detail(no); // detail에 담겨서 옵니다. ‌‌return detail; } ‌@PostMapping("/emailAuth") ‌public int emailAuth() { ‌‌return restService.sendEmail(); // ajax로 버튼 눌렀을 때 여기 옴. -> 서비스에서 기능 만들어주기 } }

 

RestService.java

LoginService에서 getEmail 메소드 가져옴.

@Service public class RestService { ‌@Autowired ‌private Util util; ‌public int sendEmail() { ‌‌if(util.getSession().getAttribute("mid") != null) { ‌‌‌return 1; ‌‌} else { ‌‌‌return 0; ‌‌} } ‌// 로그인서비스에서 가져옴 ‌public String getEmail(String email) { ‌‌return restDAO.getEmail(email); // 사용자 이메일 알아오는 작업? } }

 

-> getEmail을 RestDAO에 생성

RestDAO.java

LoginDAO에서 getEmail 메소드 옮겨옴.

public String getEmail(String id) { ‌‌return sqlSession.selectOne("login.getEmail", id); }

 

-> RestDAO 생성 후, 서비스에 @autowired로 RestDAO 받기

RestService.java

@Service public class RestService { @Autowired private Util util; @Autowired private RestDAO restDAO;

MemberDTO.java

새로 생성해주기

@Data public class MemberDTO { ‌private int mno, mgrade, mcount; ‌private String mid, mpw, mname, mdate, memail, mkey; }

RestService.java

‌public int sendEmail() { ‌‌if(util.getSession().getAttribute("mid") != null) { ‌‌‌// 메일 발송 + key 데이터베이스 저장 ‌‌‌String email = getEmail((String) util.getSession().getAttribute("mid")); ‌‌‌String key = util.createKey(); ‌‌‌ ‌‌‌MemberDTO dto = new MemberDTO(); ‌‌‌dto.setMemail(email); ‌‌‌dto.setMkey(key); ‌‌‌dto.setMid((String) util.getSession().getAttribute("mid")); ‌‌‌restDAO.setkey(dto); // db에 키 저장 ‌‌‌ ‌‌‌return 1; ‌‌} else { ‌‌‌return 0; ‌‌} }

 

-> setkey를 RestDAO에 생성

‌public int setKey(MemberDTO dto) { ‌‌return sqlSession.update("rest.setKey", dto); }

mybatis-config.xml

<typeAlias type="org.-----.dto.MemberDTO" alias="memberDTO"/>

 

rest-mapper.xml

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ​​"https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="rest"> ‌<!-- 2024-02-22 --> ‌<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} AND mid=#{mid} AND memail=#{memail} ‌</update> ​​​​ </mapper>

 

반응형

댓글