스프링부트+jsp로 배달사이트 만들기-24 찜하기(비회원)

2021. 12. 10. 23:12스프링부트

비회원의 찜 목록 쿠키를 관리할 클래스를 util패키지에 생성합니다

CookieManager

public class CookieManager {

	public String findCookie(String cookieName) throws Exception {
		ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		Cookie[] cookies = attr.getRequest().getCookies();

		for (int i = 0; i < cookies.length; i++) {
			if (cookies[i].getName().equals(cookieName)) {
				return URLDecoder.decode(cookies[i].getValue(), "UTF-8");
			}
		}
		return null;
	}
	
	
	
		public void likes(long storeId) throws Exception  {
		final String LIKES_LIST = "LIKES_LIST";
		String cookie = findCookie(LIKES_LIST);
		List<Long> list = new ArrayList<>();
		
		if(cookie == null) {
			list.add(storeId);
			addCookie(LIKES_LIST, list.toString());
			System.out.println("찜 목록 = " + list);
			return;
		}
		
		StringTokenizer st = new StringTokenizer(cookie, ", ");
		
		while(st.hasMoreTokens()) {
			list.add(Long.parseLong(st.nextToken()));
		}
		
		if(list.contains(storeId)) {
			list.remove(storeId);
		} else {
			list.add(storeId);
		}
		
		if(list.size() == 0) {
			addCookie(LIKES_LIST, "");
		} else {
			addCookie(LIKES_LIST, list.toString());
		}
		
		System.out.println("찜 목록 = " + list);
	}
	
	
	public void addCookie(String name, String value) throws Exception {
		ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		Cookie cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8"));
		cookie.setMaxAge(60 * 60 * 24 * 30);
		attr.getResponse().addCookie(cookie);
	}
	
	
	
	
}

likes 메서드를 호출하면 findCookie메서드를 호출해 이름이 LIKES_LIST인 쿠키를 찾습니다

 

","를 구분자로 배열을 만들고 배열에 가게번호가 있다면 remove 없다면 add합니다

리스트를 다시 문자열로 변환후 addCookie를 호출합니다

addCookie는 리스트 [1, 2, 3]에서 replaceall로 괄호를 제거 후 쿠키에 저장합니다 => 1, 2, 3

 

컨트롤러에서 비회원시 호출할 메서드를 추가합니다

public class CookieManager {

	public String findCookie(String cookieName) throws Exception {
		ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		Cookie[] cookies = attr.getRequest().getCookies();

		for (int i = 0; i < cookies.length; i++) {
			if (cookies[i].getName().equals(cookieName)) {
				return URLDecoder.decode(cookies[i].getValue(), "UTF-8");
			}
		}
		return null;
	}
	
	
	
	public void likes(long storeId) throws Exception  {
		final String likesList = "LIKES_LIST";
		String cookie = findCookie(likesList);
		List<Long> list = new ArrayList<>();
		
		if(cookie == null) {
			list.add(storeId);
			addCookie(likesList, list.toString());
			System.out.println("찜 목록 = " + list);
			return;
		}
		
		StringTokenizer st = new StringTokenizer(cookie, ", ");
		
		while(st.hasMoreTokens()) {
			list.add(Long.parseLong(st.nextToken()));
		}
		
		if(list.contains(storeId)) {
			list.remove(storeId);
		} else {
			list.add(storeId);
		}
		
		if(list.size() == 0) {
			addCookie(likesList, "");
		} else {
			addCookie(likesList, list.toString());
		}
		
		System.out.println("찜 목록 = " + list);
	}
	
	
	public void addCookie(String name, String value) throws Exception {
		ServletRequestAttributes attr = (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		value = value.replaceAll("[\\[\\]]", "");
		Cookie cookie = new Cookie(name, URLEncoder.encode(value, "UTF-8"));
		cookie.setMaxAge(60 * 60 * 24 * 30);
        cookie.setPath("/");
		attr.getResponse().addCookie(cookie);
	}
}

 

 

하트표시를 위해 storeDetail메서드의 비회원 부분을 추가합니다

@GetMapping("/store/detail/{id}")
	public String storeDetail(@PathVariable long id, Model model, @AuthenticationPrincipal LoginService user) throws Exception {
		long userId = 0;
		if(user != null) {
			userId = user.getUser().getId();
		} else {
			CookieManager cm = new CookieManager();
			String likesList  = cm.findCookie("LIKES_LIST");
			if(likesList == null ) {
				model.addAttribute("isLikes", false);
			} else {
				String[] arr = likesList.split(", ");
				boolean isLikes = Arrays.asList(arr).contains(id+"");
				model.addAttribute("isLikes", isLikes);
			}
		}
		
		StoreDetail storeDetail = storeService.storeDetail(id, userId);
		model.addAttribute("store", storeDetail);
		return "store/detail";
	}

배열에 가게번호가 있다면 true 없다면 false를 화면에 전달합니다

 

StoreDetail.jsp에서 하트표시 if문에 isLikes를 추가합니다

 

 

 

찜한 가게 목록을 불러올 컨트롤러에 비회원용 코드를 추가합니다

// 찜한 가게 목록
@GetMapping("/likes/store")
public String likes(Model model, @AuthenticationPrincipal LoginService user) throws Exception {
    long userId = 0;
    List<Store> likesList = new ArrayList<>();
    if (user == null) {
        CookieManager cm = new CookieManager();
        String likes = cm.findCookie("LIKES_LIST");
        
        if(likes != null && !"".equals(likes)) {
            likesList = storeService.likesListNonUser(likes);
        }
        
    } else {
        userId = user.getUser().getId();
        likesList = storeService.likesList(userId);
    }
    model.addAttribute("likesList", likesList);
    return "/store/likes";
}

 

StoreService

List<Store> likesListNonUser(String likes);

 

StoreServiceImp

@Override
public List<Store> likesListNonUser(String likes) {
	return storeDAO.likesListNonUser(likes);
}

 

StoreDAO

List<Store> likesListNonUser(String likes);

 

StoreDAOImp

@Override
public List<Store> likesListNonUser(String likes) {
    return sql.selectList("store.likesListNonUser", likes);
}

 

StoreMapper

<select id="likesListNonUser" resultType="Store">
    WITH R_COUNT AS (
       SELECT  R.STORE_ID 
               ,ROUND(R.SCORE, 1) SCORE
               ,R.REVIEW_COUNT
               ,R.BOSS_COMMENT_COUNT 
       FROM 
               (SELECT STORE_ID
                       ,AVG(SCORE) SCORE
                       ,COUNT(REVIEW_CONTENT) REVIEW_COUNT
                       ,COUNT(BOSS_COMMENT) BOSS_COMMENT_COUNT 
               FROM    BM_REVIEW GROUP BY STORE_ID ) R  
   ),
   STORE AS (
       SELECT  	S.*
                   ,T.*
                   ,CASE WHEN MOD(24 - S.OPENING_TIME + S.CLOSING_TIME, 24) != 0 THEN MOD(24 - S.OPENING_TIME + S.CLOSING_TIME, 24) ELSE 24 END BS_TIME
       FROM		BM_STORE S
       LEFT JOIN 	R_COUNT T
       ON	 		S.ID = T.STORE_ID
       WHERE 		ID IN(${likes })
   )
   
   SELECT * FROM
       (SELECT 	C.*
                   ,'true' IS_OPEN
       FROM    	STORE C 
       WHERE    	(TO_CHAR(SYSTIMESTAMP, 'HH24') 
       BETWEEN 	OPENING_TIME 
       AND     	OPENING_TIME + BS_TIME)
   UNION ALL
       SELECT  	C.*
                   ,'false' IS_OPEN 
       FROM    	STORE C 
       WHERE 	  	(TO_CHAR(SYSTIMESTAMP, 'HH24') 
       NOT BETWEEN OPENING_TIME 
       AND     	OPENING_TIME + BS_TIME )
       ) 
   </select>

likesList쿼리에서 BM_LIKES테이블과 조인 하는 부분을 WHERE  ID IN(${likes })으로 변경했습니다