- 가입하기
- 로그인 페이
- 검색페이지 및 즐겨찾기 추가/삭제
*코드는 추가/수정사항 위주로 게시했습니다.
Controller
HomeController
package com.example.client.controller; import com.example.client.service.MyFoodService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @Slf4j @RequiredArgsConstructor @RequestMapping("/home") @Controller public class HomeController { private final MyFoodService myFoodService; @GetMapping("/search") public void search(){ log.info("search in..."); } @GetMapping("/login") public void login(){ log.info("log in..."); } @GetMapping("/regist") public void regist(){ log.info("regist in..."); } } |
LoginApiController
package com.example.client.controller; import com.example.client.dto.LoginUserDto; import com.example.client.service.LoginUserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import java.util.Optional; @Slf4j @RequiredArgsConstructor @RequestMapping(path = "/apis") @RestController public class LoginApiController { private final LoginUserService loginUserService; @PostMapping("/login") public Optional<LoginUserDto> select(@RequestBody LoginUserDto loginUserDto){ return loginUserService.select(loginUserDto); } @PostMapping("/regist") public LoginUserDto add(@RequestBody LoginUserDto loginUserDto){ return loginUserService.add(loginUserDto); } } |
SearchController
package com.example.client.controller; import com.example.client.dto.MyFoodDto; import com.example.client.service.MyFoodService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @Slf4j @RequiredArgsConstructor @RequestMapping(path = "") @RestController public class SearchController { private final MyFoodService myFoodService; @GetMapping(path = "/myFood") public MyFoodDto get(@RequestParam String query){ return myFoodService.search(query); } } |
UserApiController
package com.example.client.controller; import com.example.client.dto.MyBookMarkDto; import com.example.client.dto.MyFoodDto; import com.example.client.service.MyBookMarkService; import com.example.client.service.MyFoodService; import com.example.client.service.UserService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import java.util.List; @Slf4j @RequiredArgsConstructor @RequestMapping(path = "/apis/user") @RestController public class UserApiController { private final UserService userService; private final MyFoodService myFoodService; private final MyBookMarkService myBookMarkService; @GetMapping("/search") public MyFoodDto search(@RequestParam String query){ log.info("query str = {}", query); return myFoodService.search(query); } @PostMapping("/bookmark") public MyBookMarkDto add(@RequestBody MyBookMarkDto myBookMarkDto){ log.info("myBookMark body = {}", myBookMarkDto); return myBookMarkService.add(myBookMarkDto); } @GetMapping("/bookmarkSelect") public List<MyBookMarkDto> selectAll(){ return myBookMarkService.selectAll(); } @GetMapping("/bookmarkDelete") public List<MyBookMarkDto> delete(@RequestParam Long idx){ return myBookMarkService.delete(idx); } } |
DTO
MyBookMarkDto
package com.example.client.dto; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor @Data @Builder public class MyBookMarkDto { private Long idx; private String title; private String category; private String roadAddr; private String homepage; } |
LoginUserDto
package com.example.client.dto; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor @Data @Builder public class LoginUserDto { private Long idx; private String account; private String pw; } |
Entity
LoginUserEntity
package com.example.client.entity; import com.example.client.listener.MyBookMarkEntityListener; import lombok.*; import lombok.extern.slf4j.Slf4j; import javax.persistence.*; @NoArgsConstructor @AllArgsConstructor @Table(name = "login_user_t") @Getter @Setter @Builder @Entity @ToString @Slf4j @Data @EntityListeners(value = {MyBookMarkEntityListener.class}) public class LoginUserEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long idx; @Column(unique = true, length = 20, nullable = false) private String account; @Column(length = 20, nullable = false) private String pw; } |
MyBookMarkEntity
package com.example.client.entity; import com.example.client.listener.MyBookMarkEntityListener; import lombok.*; import lombok.extern.slf4j.Slf4j; import javax.persistence.*; @NoArgsConstructor @AllArgsConstructor @Table(name = "mybookmark_t") @Getter @Setter @Builder @Entity @ToString @Slf4j @Data @EntityListeners(value = {MyBookMarkEntityListener.class}) public class MyBookMarkEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long idx; @Column(length = 20, nullable = false) private String title; @Column(length = 20, nullable = false) private String category; @Column(length = 100, nullable = false) private String roadAddr; @Column(length = 254, nullable = false) private String homepage; } |
Repository
LoginUserRepository
package com.example.client.repository; import com.example.client.entity.LoginUserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.Optional; @Repository public interface LoginUserRepository extends JpaRepository<LoginUserEntity, Long> { Optional<LoginUserEntity> findByAccountAndPw(String account, String pw); } |
MyBookMarkRepository
package com.example.client.repository; import com.example.client.entity.MyBookMarkEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface MyBookMarkRepository extends JpaRepository<MyBookMarkEntity, Long> { } |
Service
LoginUserService
package com.example.client.service; import com.example.client.dto.LoginUserDto; import com.example.client.dto.MyBookMarkDto; import com.example.client.entity.LoginUserEntity; import com.example.client.entity.MyBookMarkEntity; import com.example.client.repository.LoginUserRepository; import com.example.client.repository.MyBookMarkRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @Slf4j @RequiredArgsConstructor @Service public class LoginUserService { private final LoginUserRepository loginUserRepository; public Optional<LoginUserDto> select(LoginUserDto loginUserDto) { var entity = loginUserRepository.findByAccountAndPw(loginUserDto.getAccount(), loginUserDto.getPw()); return entity.map(e->entityToDto(e)); } public LoginUserDto add(LoginUserDto dto) { try{ var entity = loginUserRepository.save(dtoToEntity(dto)); //dto를 entity로 바꿔서 레퍼지토리에 먼저 저장 return entityToDto(entity); //entity를 다시 dto로 돌려놓고 리턴 } catch(DataIntegrityViolationException e){ log.info("duplicateKeyException -> {}", e.getMessage(), e); return null; } } private LoginUserEntity dtoToEntity(LoginUserDto dto){ return LoginUserEntity.builder() .account(dto.getAccount()) .pw(dto.getPw()) .build(); } private LoginUserDto entityToDto(LoginUserEntity entity){ return LoginUserDto.builder() .idx(entity.getIdx()) .account(entity.getAccount()) .pw(entity.getPw()) .build(); } } |
MyBookMarkService
package com.example.client.service; import com.example.client.component.NaverApis; import com.example.client.dto.MyBookMarkDto; import com.example.client.dto.MyFoodDto; import com.example.client.dto.naver.ReqImageDto; import com.example.client.dto.naver.ReqLocalDto; import com.example.client.entity.MyBookMarkEntity; import com.example.client.repository.MyBookMarkRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.List; import java.util.stream.Collectors; @Slf4j @RequiredArgsConstructor @Service public class MyBookMarkService { private final MyBookMarkRepository myBookMarkRepository; public MyBookMarkDto add(MyBookMarkDto dto) { var entity = myBookMarkRepository.save(dtoToEntity(dto)); //dto를 entity로 바꿔서 레퍼지토리에 먼저 저장 return entityToDto(entity); //entity를 다시 dto로 돌려놓고 리턴 } public List<MyBookMarkDto> selectAll(){ return myBookMarkRepository.findAll() .stream().map(m->entityToDto(m)).collect(Collectors.toList()); } public List<MyBookMarkDto> delete(Long idx){ myBookMarkRepository.deleteById(idx); return myBookMarkRepository.findAll() .stream().map(m->entityToDto(m)).collect(Collectors.toList()); } private MyBookMarkEntity dtoToEntity(MyBookMarkDto dto){ return MyBookMarkEntity.builder() .category(dto.getCategory()) .homepage(dto.getHomepage()) .roadAddr(dto.getRoadAddr()) .title(dto.getTitle()) .build(); } private MyBookMarkDto entityToDto(MyBookMarkEntity entity){ return MyBookMarkDto.builder() .idx(entity.getIdx()) .category(entity.getCategory()) .homepage(entity.getHomepage()) .roadAddr(entity.getRoadAddr()) .title(entity.getTitle()) .build(); } } |
HTML
Login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>로그인</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <h1>로그인</h1> <input id="id-box" type="text" placeholder="아이디를 입력해 주세요" /> <input id="pw-box" type="password" placeholder="패스워드를 입력해 주세요" /> <button id="login_btn">로그인</button> <button id="regist_btn">회원가입</button> </body> <script src="/js/login.js"></script> </html> |
Regist.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>회원가입</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <h1>회원가입</h1> <input id="id-box" type="text" placeholder="아이디를 입력해 주세요" /> <input id="pw-box" type="password" placeholder="패스워드를 입력해 주세요" /> <button id="regist_btn">회원가입</button> </body> <script src="/js/regist.js"></script> </html> |
Search.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>맛집</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <h1>지역검색</h1> <div> <button id="logout-btn">로그아웃</button><br /> <input id="search-box" type="text" placeholder="내용을 입력해 주세요" /> <button id="search-btn">검색</button> </div> <div> <div id="imageBox" style="visibility:hidden"> <img id="image" src="" style="width: 300px; height: 300px"/> </div> <div id="infoList" style="visibility:visible"> <ul> <li id="title">매장 이름: </li> <li id="category">카테고리: </li> <li id="addr">주소: </li> <li id="road-addr">도로명: </li> <li id="home-page-link" style="visibility:hidden"> <a href="" id="homepage">홈페이지</a> </li> </ul> </div> </div> <div> <button id="add-btn" type="button" style="visibility:hidden">즐겨찾기 추가</button> </div> <br /><br /> <div> <div>나의 리스트</div> <br /> <div id="my-list"></div> </div> </body> <script src="/js/home.js"></script> </html> |
JS
login.js
$(document).ready(function() { $("#login_btn").click(function() { let account = $("#id-box").val(); let pw = $("#pw-box").val(); if(account !== ""){ if(pw !== ""){ $.ajax({ url: "/apis/login", type: "post", accept: "application/json", contentType: "application/json; charset=utf-8", data: JSON.stringify({account: account, pw: pw.toString()}), dataType: "json", success: function(data) { console.log(data); if(data === null){ alert("입력한 정보와 일치하는 회원이 없습니다."); } else{ window.location.replace("http://localhost:8081/home/search"); } }, error: function(xhr, err) { alert("입력한 정보와 일치하는 회원이 없습니다."); } }); } else{ alert("비밀번호를 입력하세요!"); } } else{ alert("아이디를 입력하세요!"); } }); $("#regist_btn").click(function() { window.location.replace("http://localhost:8081/home/regist"); }); }); |
regist.js
$(document).ready(function() { $("#regist_btn").click(function() { let account = $("#id-box").val(); let pw = $("#pw-box").val(); if(account !== ""){ if(pw !== ""){ $.ajax({ url: "/apis/regist", type: "post", accept: "application/json", contentType: "application/json; charset=utf-8", data: JSON.stringify({account: account, pw: pw.toString()}), dataType: "json", success: function(data) { console.log(data); alert("회원가입이 완료 되었습니다."); window.location.replace("http://localhost:8081/home/login"); }, error: function(xhr, err) { alert("중복된 아이디 입니다."); } }); } else{ alert("비밀번호를 입력하세요!"); } } else{ alert("아이디를 입력하세요!"); } }); }); |
home.js
$(document).ready(function() { $.get("/apis/user/bookmarkSelect", function(data){ $.each(data, function(index, item) { $("#my-list").append( `<div id="markList${item.idx}" >${item.idx}. ${item.title} ${item.category} ${item.roadAddr} <a href=${item.homepage}>홈페이지</a><button id="del-btn${item.idx}">삭제</button></div>` ); $("#del-btn"+item.idx).click(function() { let idx = item.idx; console.log(idx); $.get("/apis/user/bookmarkDelete?idx="+idx, function(data) { $("#markList"+idx).remove(); }) }); }); }); $("#search-btn").click(function() { let query = $("#search-box").val(); $.get("/apis/user/search?query="+query, function(data){ if(data.title !== "NULL"){ let title = data.title; let category = data.category; let addr = data.addr; let roadAddr = data.roadAddr; let homepage =data.homepage; let imgUrl = data.imgUrl; $("#image").attr("src", imgUrl); $('#title').text("매장 이름: " + title); $('#category').text("카테고리: " + category); $('#addr').text("주소: " + addr); $('#road-addr').text("도로명: " + roadAddr); $("#homepage").attr("href", homepage); $("#add-btn").attr("style", "visibility:visible"); $("#add-btn").attr("data-title", title); $("#add-btn").attr("data-category", category); $("#add-btn").attr("data-roadAddr", roadAddr); $("#add-btn").attr("data-homepage", homepage); $("#imageBox").attr("style", "visibility:visible"); $('#home-page-link').attr("style", "visibility:visible") } else{ alert("검색된 결과가 없습니다."); } console.log("data=" + data); }); }); $("#add-btn").click(function() { let title = $('#add-btn').attr("data-title"); let category = $('#add-btn').attr("data-category"); let roadAddr = $('#add-btn').attr("data-roadAddr"); let homepage = $('#add-btn').attr("data-homepage"); $.ajax({ url: "/apis/user/bookmark", type: "post", accept: "application/json", contentType: "application/json; charset=utf-8", data: JSON.stringify({title : title, category: category, roadAddr: roadAddr, homepage: homepage}), dataType: "json", success: function(data) { $("#my-list").append( `<div id="markList${data.idx}">${data.idx}. ${data.title} ${data.category} ${data.roadAddr} <a href=${data.homepage}>홈페이지</a><button id="del-btn${data.idx}" data-idx=${data.idx}>삭제</button></div>` ); $("#del-btn"+data.idx).click(function() { let idx = data.idx; console.log(idx); $.get("/apis/user/bookmarkDelete?idx="+idx, function(data) { $("#markList"+idx).remove(); }) }) }, error: function(xhr, err) { } }); }); $("#logout-btn").click(function() { window.location.replace("http://localhost:8081/home/login"); }) }); |