<input type="text" value="${empty WtoNotiYData.deepAnalCrltnYmd ? now:WtoNotiYData.deepAnalCrltnYmd}" name="deepAnalCrltnYmd" id="deepAnalCrltnYmd"/>

JSTL에서 value에 값을 나타낼때 mv로 이용해서 가져오는 값이 null인 경우가 아닌경우에 값을 달리 보여주게하고싶은데

<c:if> 나 <c:choose>를 사용하지 않고 삼항연사자를 이용해서도 값을 표시할 수 있다.

'Board > 게시판 만들기(jsp)' 카테고리의 다른 글

게시판 검색 기능  (0) 2022.12.14
파일 업로드  (0) 2022.12.07
아이디 중복체크(Ajax)  (2) 2022.12.06
로그인/로그아웃 기능 구현하기(세션)  (0) 2022.12.05
게시판 페이징  (0) 2022.12.02

게시판 댓글입력시 줄바꿈 처리하게되면 데이터에 줄바꿈이 된 상태로 삽입이된다.

 

하지만 view단에서 뿌려줄때는 줄바꿈 처리가 되지않은 채로 출력이된다.

 

 

\r\n &rarr; <br> 치환

뿌려주려는 내용을 가져와 replace함수로 변경하여 저장하게끔한다.

 

 

 

 

입력 후 댓글 리스트와 댓글 수정창에도 줄바꿈 처리가 된것으 확인할 수 있다.

 


댓글 수정창에 보이는 <br>태그를 가리기 위해 개행문자로 치환한다.

<br>태그 대신 \r\n으로 개행처리가 된 것을 확인할 수 있다.

 

 

댓글 수정을 위해 수정하고자 하는 내용을 가져와 <br>로 치환해준다.

 

처음 입력한 댓글

 

수정 댓글

 

수정완료 댓글

 

 

<a class="dropdown-item" id="reportBtn" href="#">신고하기</a>

 

//신고팝업창 띄우기
    $(function(){
        let popuptestbtn = document.querySelector("#reportBtn");
        popuptestbtn.onclick = function(){
            let popOption = "width = 568px, height=558px, scrollbars=no";
            let openUrl = "<%=request.getContextPath()%>/community/popup.do";
            window.open(openUrl,"",popOption);
        }
    });

VO

package project.healingcamp.vo;

public class LikeVO {

	private int like_no;
	private int likeNum; //좋아요 체크 유무 - 좋아요 체크  :1 , 좋아요 미체크 :0
	private int bidx;
	private int uidx;
	private String id;
}

getter, setter 생성

 

Mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
  <mapper namespace="project.healingcamp.mapper.likeMapper">

	<!-- 좋아요 체크 확인 -->
	<select id="likeCount" parameterType="likeVO" resultType="int">
		SELECT COUNT(*) 
		  FROM liketable 
		 WHERE bidx = #{bidx} AND id = #{id}
	</select>

	<!-- 좋아요 +1 -->
	<insert id="likeUp" parameterType="likeVO">
		INSERT into liketable(
			like_no,
			bidx,
			id,
			likenum
		)VALUES(
			like_no_seq.nextval,
			#{bidx},
			#{id},
			1
		)
		
	</insert>
	
	<!-- 좋아요 -1 -->
	<delete id="likeDown" parameterType="likeVO">
		DELETE liketable 
		 WHERE bidx = #{bidx} 
		   AND id= #{id}
	</delete>
  </mapper>

 

DAO

package project.healingcamp.dao;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import project.healingcamp.vo.LikeVO;

@Repository
public class LikeDAO {
	
	@Autowired
	private SqlSession sqlSession; 
	
    //좋아요 체크 확인
	public int likeCount(LikeVO likeVO) {
		return sqlSession.selectOne("project.healingcamp.mapper.likeMapper.likeCount", likeVO);
	}
	
    //좋아요 +1
	public int likeUp(LikeVO likeVO) {
		return sqlSession.insert("project.healingcamp.mapper.likeMapper.likeUp", likeVO);
	}
	
    //좋아요 -1
	public int likeDown(LikeVO likeVO) {
		return sqlSession.delete("project.healingcamp.mapper.likeMapper.likeDown", likeVO);
	}

 

Service / ServiceImpl

package project.healingcamp.service;

import project.healingcamp.vo.LikeVO;

public interface LikeService {
	
	public int likeUp(LikeVO likeVO);
	public int likeCount(LikeVO likeVO);
	public int likeDown(LikeVO likeVO);

}
package project.healingcamp.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import project.healingcamp.dao.Community_BoardDAO;
import project.healingcamp.dao.LikeDAO;
import project.healingcamp.vo.LikeVO;

@Service
public class LikeServiceImpl implements LikeService{

	@Autowired
	private LikeDAO likeDAO;
	
	@Autowired
	private Community_BoardDAO cboardDAO;

	@Override
	public int likeCount(LikeVO likeVO) {
		return likeDAO.likeCount(likeVO);
	}
	
	@Override
	public int likeUp(LikeVO likeVO) {
		return likeDAO.likeUp(likeVO);
	}

	@Override
	public int likeDown(LikeVO likeVO) {
		return likeDAO.likeDown(likeVO);
	}

	
}

 

Controller

boardController - 게시글 상세페이지

좋아요체크 여부를 상세페이지에 뿌려준다.

//게시글 상세보기 이동
	@RequestMapping(value="/community_view.do",method=RequestMethod.GET)
	public String community_view(int bidx,Model model,ReplyVO replyVO,HttpSession session) {
		
		//호출된 결과를 vo에 담음
		Community_BoardVO vo = cboardService.selectByBidx(bidx);
		//조회수 증가
		cboardService.hitCount(bidx);
		//로그인정보
		UserVo login = (UserVo)session.getAttribute("login");
		
		//좋아요 클릭 체크
		LikeVO likeVO = new LikeVO();
		likeVO.setBidx(bidx);
		
		if(login != null) { 
			likeVO.setId(login.getId()); //로그인했을시에는 로그인된 아이디
		}else {
			likeVO.setId(""); //미로그인시에는 빈값을 넘김
		}
		
		//model에 vo를 담아 화면에 넘김
		model.addAttribute("vo",vo);
		model.addAttribute("likeCount",likeService.likeCount(likeVO));
		
		return "community/community_view";

 

 

likeController

package project.healingcamp.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import project.healingcamp.service.LikeService;
import project.healingcamp.vo.LikeVO;

@RequestMapping(value="/community")
@Controller
public class LikeController {
	
	@Autowired
	private LikeService likeService;
	
    //좋아요 여부 확인
	@RequestMapping(value="/likeCount.do",method=RequestMethod.POST)
	@ResponseBody
	public int likeCount(LikeVO likeVO) {
		int result = likeService.likeCount(likeVO);
		return result;
	}
	
	//좋아요 +1
	@RequestMapping(value="/likeUp.do",method=RequestMethod.POST)
	@ResponseBody
	public void likeUp(LikeVO likeVO) {
		likeService.likeUp(likeVO);
	}
	
	//좋아요 -1
	@RequestMapping(value="/likeDown.do",method=RequestMethod.POST)
	@ResponseBody
	public void likeDown(LikeVO likeVO) {
		likeService.likeDown(likeVO);
	}

}

 

 

javascript

//좋아요
   		$(".empathy").hover(
    		function(){//하트 마우스 올라왔을때
    			$(this).attr('src','./../resources/upload/like_color_change.jpg');
    		},
    		function(){//하트 마우스 벗어났을때
    			$(this).attr('src','./../resources/upload/like.jpg');
    		}
    	);
   		
   		var bidx = ${vo.bidx};	//게시글 번호
		var id = "${login.id}"; //회원아이디
		var likeCount = ${likeCount}; //좋아요 수
		
		if(likeCount == 1){ //likeCount이 1일때 꽉찬하트
			$(".empathy").attr('src','./../resources/upload/like_color_change.jpg');
			$(".empathy").unbind('mouseenter mouseleave'); //좋아요 on 일때 hover기능 unbind
		}else{//likeCount이 0일때 빈하트
			$(".empathy").attr('src','./../resources/upload/like.jpg');
		}
		
		//좋아요 버튼 클릭
		$(".empathy").on("click",function(){
			if(login == ""){
				alert("로그인 후 이용해주세요.");
			}else{
				//좋아요 체크여부
				$.ajax({
					url:"likeCount.do",
					type:"post",
					data:{"bidx":bidx,"id":id},
					success:function(result){
						
						if(result == 1){//좋아요 체크시 좋아요 취소
							$.ajax({
								url:"likeDown.do",
								type:"post",
								data:{"bidx":bidx,"id":id},
								context:this,
								success:function(result){
									alert("좋아요취소 성공!");
									console.log("좋아요 체크?"+likeCount);
									
								},error:function(){
									alert("error");
								}
							});
							$(".empathy").attr('src','./../resources/upload/like.jpg'); 
							
						}else if(result == 0){
							$.ajax({
								url:"likeUp.do",
								type:"post",
								data:{"bidx":bidx,"id":id},
								context:this,
								success:function(result){
									alert("좋아요성공!");
									console.log("좋아요 체크?"+likeCount);
									
								},error:function(){
									alert("error");
								}
							});
							$(".empathy").attr('src','./../resources/upload/like_color_change.jpg');
							$(".empathy").unbind('mouseenter mouseleave'); //좋아요 on 일때 hover기능 unbind
						}
					},error:function(){
						alert("error");
					}
				});
			}
		});

게시글 좋아요버튼을 클릭했을때 로그인한 유저가 클릭한 게시글의 좋아요가 유지될수 있게 해야했는데

로그인한 값을 넘겨서 좋아요 여부를 확인했더니 로그인 하지 않을시엔 null예외가 발생해서 게시글 상세페이지를 볼수없었다. 

단순히 그냥 로그인 값이 null인 경우와 아닌경우 값을 다르게 넘겨주면 되는 간단한 문제였다.

 

 

좋아요 클릭 시 하트의 색깔이 바뀐다.

 

이제 좋아요 총갯수를 뷰에 뿌려주는 것과 리스트목록에서 좋아요 버튼 클릭하는 것만 남음!!

 

 


좋아요 버튼 클릭시 좋아요 수 카운팅 하기

 

boardMapper

좋아요 클릭시 좋아요 수 카운팅 해주는 매퍼 작성

<!-- 	좋아요수 카운팅 +1 -->
	<update id="addLikeCnt" parameterType="int">
		UPDATE boardtable
		   SET likes = likes + 1
		 WHERE bidx = #{bidx}
	</update>
	
<!-- 	좋아요수 카운팅 -1 -->
	<update id="removeLikeCnt" parameterType="int">
		UPDATE boardtable
		   SET likes = likes - 1
		 WHERE bidx = #{bidx}
	</update>

boardDAO

public int addLikeCnt(int bidx) {
		return sqlSession.update("project.healingcamp.mapper.communityMapper.addLikeCnt", bidx);
	}
	public int removeLikeCnt(int bidx) {
		return sqlSession.update("project.healingcamp.mapper.communityMapper.removeLikeCnt", bidx);
	}

 

likeServiceImpl

	@Override
	public int likeUp(LikeVO likeVO) {
		cboardDAO.addLikeCnt(likeVO.getBidx());
		return likeDAO.likeUp(likeVO);
	}

	@Override
	public int likeDown(LikeVO likeVO) {
		cboardDAO.removeLikeCnt(likeVO.getBidx());
		return likeDAO.likeDown(likeVO);
	}

좋아요 클릭 시 좋아요 +1

좋아요 취소시 좋아요 -1 카운팅 된다.

 


ajax로 좋아요 총 갯수 업데이트

 

Mapper

해당 게시글의 좋아요 총 갯수를 조회하는 쿼리 작성

총 좋아요 갯수를 변수로 가지고 있는 boardVO를 반환값으로 지정한다.

<!-- 게시글의 좋아요 총 갯수 -->
	<select id="likeNum" parameterType="int" resultType="cboardVO">
		SELECT likes 
		  FROM boardtable 
		 WHERE bidx = #{bidx}
	</select>

 

DAO

반환 타입 boardVO 반환값 boardVO

//좋아요 +1 / 좋아요 누른 후 총 갯수
	public Community_BoardVO likeUp(LikeVO likeVO) {
		
		Community_BoardVO cboardVO = new Community_BoardVO();
		cboardVO.setBidx(likeVO.getBidx());
		
		//좋아요 +1
		sqlSession.update("project.healingcamp.mapper.likeMapper.addLikeCnt", cboardVO); 
		//로그인한 회원+게시글
		int result = sqlSession.insert("project.healingcamp.mapper.likeMapper.likeUp", likeVO); 
		
		if(result == 1) {
			// 좋아요 총 갯수
			cboardVO = sqlSession.selectOne("project.healingcamp.mapper.likeMapper.likeNum", cboardVO); 
		}
		return cboardVO;
	}
	
	//좋아요 -1 / 좋아요 취소 후 총 갯수
	public Community_BoardVO likeDown(LikeVO likeVO) {
		Community_BoardVO cboardVO = new Community_BoardVO();
		cboardVO.setBidx(likeVO.getBidx());
		
		//좋아요 -1
		sqlSession.update("project.healingcamp.mapper.likeMapper.removeLikeCnt", cboardVO);
		//좋아요 삭제
		int result = sqlSession.delete("project.healingcamp.mapper.likeMapper.likeDown", likeVO);
		
		if(result == 1) {
			// 좋아요 총 갯수
			cboardVO = sqlSession.selectOne("project.healingcamp.mapper.likeMapper.likeNum", cboardVO); 
		}
		return cboardVO;
	}

 

Service/ServiceImpl

//Service
//좋아요 +1
public Community_BoardVO likeUp(LikeVO likeVO);
//좋아요 -1
public Community_BoardVO likeDown(LikeVO likeVO);


//ServiceImpl
//좋아요 +1
@Override
	public Community_BoardVO likeUp(LikeVO likeVO) {

		Community_BoardVO cboardVO = new Community_BoardVO();
		cboardVO = likeDAO.likeUp(likeVO);
		return cboardVO;
	}

//좋아요 -1
@Override
public Community_BoardVO likeDown(LikeVO likeVO) {
    Community_BoardVO cboardVO = new Community_BoardVO();
    cboardVO = likeDAO.likeDown(likeVO);
    return cboardVO;
}

 

Controller

	//좋아요 +1
	@RequestMapping(value="/likeUp.do",method=RequestMethod.POST)
	@ResponseBody
	public Community_BoardVO likeUp(LikeVO likeVO) {
		Community_BoardVO cboardVO = new Community_BoardVO();
		cboardVO = likeService.likeUp(likeVO);
		return cboardVO;
	}
	
	//좋아요 -1
	@RequestMapping(value="/likeDown.do",method=RequestMethod.POST)
	@ResponseBody
	public Community_BoardVO likeDown(LikeVO likeVO) {
		Community_BoardVO cboardVO = new Community_BoardVO();
		cboardVO = likeService.likeDown(likeVO);
		return cboardVO;
	}

 

javascript

//좋아요 버튼 클릭
		$(".empathy").on("click",function(){
			if(login == ""){
				alert("로그인 후 이용해주세요.");
			}else{
				//좋아요 체크여부
				$.ajax({
					url:"likeCount.do",
					type:"post",
					data:{"bidx":bidx,"id":id},
					success:function(result){
						
						if(result == 1){//좋아요 체크시 좋아요 취소
							$.ajax({
								url:"likeDown.do",
								type:"post",
								data:{"bidx":bidx,"id":id},
								success:function(data){
									$("#likeCnt").html(data.likes+"공감");
								},error:function(){
									alert("error");
								}
							});
							$(".empathy").attr('src','./../resources/upload/like.jpg'); 
							
						}else if(result == 0){
							$.ajax({
								url:"likeUp.do",
								type:"post",
								data:{"bidx":bidx,"id":id},
								success:function(data){
									$("#likeCnt").html(data.likes+"공감");
								},error:function(){
									alert("error");
								}
							});
							$(".empathy").attr('src','./../resources/upload/like_color_change.jpg');
							$(".empathy").unbind('mouseenter mouseleave'); //좋아요 on 일때 hover기능 unbind
						}
					},error:function(){
						alert("error");
					}
				});
			}
		});

자바스크립트는  success 되었을 때 좋아요 갯수를 화면에 뿌려주는 코드만 추가하였다.

$("#likeCnt").html(data.likes+"공감");

 

 

 

 

정리가 약간 안되어있지만 어쨌든 좋아요기능 끝~~~~

나중에 시간 날 때 꼭 다시 정리하리라....

 

 

 

 

KakaoTalk_20230202_174032677.mp4
2.91MB

//좋아요 버튼 클릭
		let num = 0;
		$(".empathy").on("click",function(e){
			if(num == 0){ //num이 0일때 좋아요 후  num 1로 변경
				$(this).attr('src','./../resources/upload/like_color_change.jpg');
				$(this).unbind('mouseenter mouseleave');//좋아요 on 일때 hover기능 unbind
				num = 1;
			}else{//num이 1일때 좋아요 취소 후 num 0으로 변경
				$(this).attr('src','./../resources/upload/like.jpg');
				num = 0;
			}
		});	
		
		//좋아요
	  		$(".empathy").hover(
	   		function(){//하트 마우스 올라왔을때
	   			$(this).attr('src','./../resources/upload/like_color_change.jpg');
	   		},
	   		function(){//하트 마우스 벗어났을때
	   			$(this).attr('src','./../resources/upload/like.jpg');
	   		}
	   	);

$(this).unbind('hover');   -- 작동 X

$(this).unbind('mouseenter mouseleave'); -- 작동 O

 

 

 

 

참고 링크

https://mytory.net/archives/660

 

[jQuery] hover 이벤트 언바인드 unbind 하기

jQuery에서 hover 이벤트(혹은 함수)는 꽤 유용하다. 인자값을 funtion 두 개 받는데, 마우스를 올리면 앞의 것이, 마우스를 빼면 뒤의 것이 실행된다. 말 그대로 hover 효과를 내는 것이다. 그러나 이걸

mytory.net

 

 

댓글 작성 Mapper
<!--   	댓글 작성 -->
  	<insert id="reply_Insert" parameterType="replyVO">
  		INSERT INTO replytable(
		  			reply_idx
		  		   ,reply_content
		  		   ,id
		  		   ,reply_wdate
		  		   ,reply_ip
		  		   ,bidx
		  		   ,uidx
		  		   ,board_type
		  		   ,rparent
		  	)VALUES(
		  		   reply_idx_seq.nextval
		  		  ,#{reply_Content}
		  		  ,#{id}
		  		  ,SYSDATE
		  		  ,#{reply_Ip}
		  		  ,#{bidx}
		  		  ,#{uidx}
			  	  ,#{board_type}
			  	  ,reply_idx_seq.nextval
		  	)
		  			
  	</insert>

 

 

댓글 목록 Mapper
<!--   커뮤니티 댓글 목록 -->
  	<select id="reply_list" resultType="replyVO" parameterType="int">
  		SELECT reply_idx
			  ,reply_content
			  ,id
			  ,reply_wdate
			  ,bidx
			  ,uidx
			  ,rdepth
			  ,rparent
		  FROM replytable
		 WHERE bidx = #{bidx}
		   AND board_type = 0
		 ORDER BY rparent asc, reply_wdate asc
  	</select>

 

대댓글을 달은 댓글 밑에 대댓글 리스트를 작성 순서대로 출력하려면 부모댓글과 작성날짜를 정렬했어야했다.

 

댓글 삭제 Mapper
<!-- 댓글 삭제 -->
	<delete id="deleteByReply" parameterType="replyVO">
		DELETE replytable 
		 WHERE reply_idx = #{reply_Idx} 
	</delete>

 

댓글 수정 Mapper
<!-- 	댓글 수정 -->
	<update id="updateByReply" parameterType="replyVO">
		UPDATE replytable 
		   SET reply_content = #{reply_Content} 
		 WHERE reply_idx = #{reply_Idx}
	</update>
대댓글 작성 Mapper
<!-- 	대댓글 작성 -->
	<insert id="re_replyInsert" parameterType="replyVO">
		INSERT into replytable (
					 reply_idx
					,reply_content
					,id
					,reply_wdate
					,reply_ip
					,bidx
					,uidx
					,board_type
					,rdepth
					,rparent
					)
			VALUES (
					reply_idx_seq.nextval
					,#{reply_Content}
					,#{id}
					,SYSDATE
					,#{reply_Ip}
					,#{bidx}
					,#{uidx}
					,0
					,1
					,#{rparent}
					)
	</insert>

대댓글과 댓글의 구분을 위해 대댓글 입력시 rdepth를 1로 입력했다.

 

DAO
@Repository
public class ReplyDAO {

	@Autowired
	private SqlSession sqlSession;
	
	//댓글작성
	public int reply_Insert(ReplyVO replyVO) {
		return sqlSession.insert("project.healingcamp.mapper.replyMapper.reply_Insert", replyVO);
	}
	
	//커뮤니티 댓글 목록
	public List<ReplyVO> reply_list(int bidx){
		return sqlSession.selectList("project.healingcamp.mapper.replyMapper.reply_list",bidx);
	}
	
	//상담사 게시판 댓글 목록
	public List<ReplyVO> counseller_reply_list(int bidx){
		return sqlSession.selectList("project.healingcamp.mapper.replyMapper.counseller_reply_list",bidx);
	}
	
	//댓글 삭제
	public int deleteByReply(ReplyVO replyVO) {
		return sqlSession.delete("project.healingcamp.mapper.replyMapper.deleteByReply", replyVO);
	}
	
	//댓글 수정
	public int updateByReply(ReplyVO replyVO) {
		return sqlSession.update("project.healingcamp.mapper.replyMapper.updateByReply", replyVO);
	}
	
	//대댓글 작성
	public int re_replyInsert(ReplyVO replyVO) {
		return sqlSession.insert("project.healingcamp.mapper.replyMapper.re_replyInsert",replyVO);
	}
	
	
}

 

Service(interface)
public interface ReplyService {
	
    //댓글 작성
	int reply_Insert(ReplyVO replyVO);
    
    //댓글리스트
	List<ReplyVO> reply_list(int bidx);
    
    //댓글 삭제
	int deleteByReply(ReplyVO replyVO);
    
    //댓글 수정
	int updateByReply(ReplyVO replyVO);
    
    //대댓글 작성
	int re_replyInsert(ReplyVO replyVO);
}

 

Service
@Service
public class ReplyServiceImpl implements ReplyService {
	
	@Autowired
	private ReplyDAO replyDAO;
	
	@Autowired
	private Community_BoardDAO cboardDAO;

	//댓글 작성
	//Community_BoardDAO 사용을 위한 트랜잭션
	@Transactional
	@Override
	public int reply_Insert(ReplyVO replyVO) {
		cboardDAO.addReplyCnt(replyVO.getBidx()); // 댓글 작성시 댓글 카운트 +1
		return replyDAO.reply_Insert(replyVO);
	}

	//댓글 리스트
	@Override
	public List<ReplyVO> reply_list(int bidx) {
		List<ReplyVO> reply_list = replyDAO.reply_list(bidx);
		return reply_list;
	}

	//댓글 삭제
	@Transactional
	@Override
	public int deleteByReply(ReplyVO replyVO) {
		cboardDAO.removeReplyCnt(replyVO.getBidx()); //댓글 삭제 댓글카운트 -1
		return replyDAO.deleteByReply(replyVO);
	}

	//댓글 수정
	@Override
	public int updateByReply(ReplyVO replyVO) {
		return replyDAO.updateByReply(replyVO);
	}

	//대댓글 작성
	@Transactional
	@Override
	public int re_replyInsert(ReplyVO replyVO) {
		cboardDAO.addReplyCnt(replyVO.getBidx()); // 대댓글 작성시 카운트+1
		return replyDAO.re_replyInsert(replyVO);
	}

 

VO
public class ReplyVO {
	
	private int reply_Idx; //댓글 번호
	private String reply_Content; //댓글 내용
	private String id; //댓글 작성한 아이디
	private String reply_Wdate; //댓글 작성 날짜
	private String reply_Ip; //댓글 작성 ip
	private int bidx; //댓글 작성한 게시글 번호
	private int uidx; //댓글 작성한 회원의 uidx
	private int board_type; //게시판 유형
	private int rdepth; //댓글 - rdepth:0 , 대댓글 - rdepth:1
	private int rparent; //부모 댓글

getter / setter 생성

 

Controller
	//댓글 작성
	@RequestMapping(value="/community_write.do",method=RequestMethod.POST)
	public String community_write(Community_BoardVO cboardVO,HttpSession session,HttpServletRequest request) {
		
		UserVo login = (UserVo)session.getAttribute("login");
		
		cboardVO.setId(login.getId());			
		cboardVO.setUidx(login.getUidx());
		cboardVO.setIp(request.getRemoteAddr());
		
		//게시글 작성
		cboardService.insert(cboardVO);
		//최근작성한 게시글의 bidx
		int bidx = cboardService.maxBidx();
		
		return "redirect:community_view.do?bidx="+bidx;
	}
    
    //댓글 리스트
	@RequestMapping(value="/community_replyList.do",method=RequestMethod.GET)
	@ResponseBody
	public List<ReplyVO> community_view(int bidx) {
		
		//댓글 리스트
		List<ReplyVO> reply_list = replyService.reply_list(bidx);
		
		return reply_list;
	}
    
   //댓글 삭제
	@RequestMapping(value="/community_reply_delete.do",method=RequestMethod.POST)
	@ResponseBody
	public String community_reply_delete(ReplyVO replyVO) {
		replyService.deleteByReply(replyVO);
		
		return "1";
	}
	
	//댓글 수정
	@RequestMapping(value="/community_reply_update.do",method=RequestMethod.POST)
	@ResponseBody
	public String community_reply_update(@RequestBody ReplyVO replyVO) {
		replyService.updateByReply(replyVO);
		
		return "1";
	}
	
	//댓글 신고 팝업창
	@RequestMapping(value="/reply_popup.do",method=RequestMethod.GET)
	public String reply_popup() {
		return "community/reply_popup";
	}
	
	
	//대댓글 작성
	@RequestMapping(value="community_re_reply.do",method=RequestMethod.POST)
	@ResponseBody
	public String re_replyInsert(@RequestBody ReplyVO replyVO, HttpSession session, HttpServletRequest request,Community_BoardVO cboardVO) {
		
		//로그인 정보
		UserVo login = (UserVo)session.getAttribute("login");
		
		replyVO.setId(login.getId()); //대댓글 작성자 아이디
		replyVO.setUidx(login.getUidx()); //대댓글 작성자 uidx
		replyVO.setReply_Ip(request.getRemoteAddr()); //ip
		
		replyService.re_replyInsert(replyVO);
		
		return "1";
		
	}

 

 

 

JavaScript
댓글 작성
//로그인 정보
var login = "${login}";
   		
//현재 로그인한아이디
var id = '<%=session.getAttribute("id")%>'; 

// 댓글 작성 버튼 클릭
$(document).on("click","#reply_btn",function(){
    //댓글 입력값
    var reply = $("textarea[name=reply_Content]").val();
    //로그인 여부
    if(login == ""){
        alert("로그인 후 이용해주세요");
        return false;
    }
    //댓글 작성여부
    else if(reply == ""){
        alert("댓글을 입력해주세요.");
        return false;
    }
    
    //댓글작성
   			$.ajax({
	    		type:"post",
	    		url:"community_reply_insert.do",
	    		data:$("#commentForm").serialize(),
	    		dataType:"text",
	    		success:function(data){
	    			if(data == "success"){
		    			$("#reply").val("");
	    				getCommentList(); //댓글 작성 완료시 댓글 목록함수 호출
	    			}
	    		},error:function(){
	    			alert("error");
	    		}
	    	});
   		});
   		
   		//초기페이지 로딩시 댓글 불러오기
   		$(function(){
   			getCommentList();
});

 

댓글 목록
//댓글목록
   		function getCommentList(){
   			
   			//작성하려는 댓글의 게시물 번호
   			var bidx = $("input[name=bidx]").val();
   			
   			$.ajax({
   				type:"get",
   				url:"community_replyList.do",
				data:"bidx="+bidx,
   				success : function(result){
   					var html="";
   					if(result.length > 0){
   						for(i = 0; i < result.length; i++){
   						
	   					var reply_Idx = result[i].reply_Idx; //댓글번호
	   					var bidx = result[i].bidx; // 댓글이 달린  게시글 번호
	   					var reply_Content = result[i].reply_Content; //댓글 내용
	   					var writer = result[i].id //댓글 작성자
	   					var rdepth = result[i].rdepth //댓글깊이 
	   					var rparent = result[i].rparent; 
	   					console.log(rparent);
	   					
	   						html += "<div class='reply_area"+rparent+"'>";
	   						if(reply_Content == ""){ //삭제된 댓글일때
	   							html += "<dlv>";
	   							html += "<div>삭제된 댓글입니다.</div>"
	   							html += "</dlv>";
	   						}else{
		   						if(rdepth == 0){//댓글일때
		   						    html += "<div class='reply_box'>";
		   						    html += 	"<div class='reply_box_wrapper"+reply_Idx+"'>"; //댓글 수정 버튼 클릭시 수정 창으로 바뀌는 부분(수정하려는 댓글의 idx)
		   						    html += 		"<div class='reply_info_wrapper'>";
		   						    html += 			"<ul class='reply_info'>";
		   						    html += 				"<li class='id'>"+result[i].id+"</li>";
		   						    html += 				"<li class='wdate'>"+result[i].reply_Wdate+"</li>";
		   						    
		   						    if(id == result[i].id){ //현재 로그인된 아이디일시 댓글수정가능 
		   						        html += 			"<li class='commentModify' onclick='commentModify("+reply_Idx+",\""+reply_Content+"\",\""+writer+"\");'>댓글수정</li>";
		   						    }else{
		   						        html += 			"<li class='re_reply' onclick='re_reply("+reply_Idx+","+bidx+")'>답글쓰기</li>";
		   						    }
		   						    
		   						    if(id == result[i].id){//현재 로그인된 아이디일시 댓글삭제가능 
		   						        html += 			"<li class='delete' onclick='deleteReply("+reply_Idx+","+bidx+");'>삭제</li>";
		   						    }else{
		   						        html += 			"<li class='report' onclick='reportReply()'>신고</li>";
		   						    }
		   						    
		   						    html += 			"</ul>"; //.reply_info
		   						    html += 		"</div>"; //.reply_info_wrapper
		   						    html += 		"<div class='reply_view_wrapper'>";
		   						    html += 			"<div class='reply_view'>"+result[i].reply_Content+"</div>";
		   						    html += 		"</div>"; //.reply_view_wrapper
		   						    html += 	"</div>"; //.reply_box_wrapper
		   						    html += "</div>"; //.reply_box
		   						    html += "<div class='re_reply_area"+reply_Idx+"'></div>"; //답글작성이 들어갈 칸
		   						    
		   						}else{//대댓글일때
			   						html += "<div class='re_reply_box'>";
			   					 	html += 	"<div class='reply_box_wrapper"+reply_Idx+"'>"; //답글 수정 버튼 클릭시 수정 창으로 바뀌는 부분(수정하려는 답글의 idx)
		   		   					html += 	"<span class='reply_ico'>└</span>";
		   		   					html += 	"<div class='reply_info_wrapper' >";
		   		   					html += 		"<ul class='reply_info'>";
		   		   					html += 			"<li class='id'>"+result[i].id+"</li>";
			   		   				html += 			"<li class='wdate'>"+result[i].reply_Wdate+"</li>";
		   							
		   							if(id == result[i].id){
			   							html += 		"<li class='commentModify' onclick='commentModify("+reply_Idx+",\""+reply_Content+"\",\""+writer+"\");'>댓글수정</li>";
		   							}else{
		   								html += 		"<li class='re_reply' onclick='re_reply("+reply_Idx+","+bidx+")'>답글쓰기</li>";
		   							}
		   							
		   							if(id == result[i].id){
		   								html += 		"<li class='delete' onclick='deleteReply("+reply_Idx+","+bidx+");'>삭제</li>";
		   							}else{
			   							html += 		"<li class='report' onclick='reportReply()'>신고</li>";
		   							}
		   							html += 		"</ul>"; //.reply_info
		   							html += 	"</div>"; //.reply_info_wrapper
		   		   					html += 	"<div class='reply_view_wrapper'>";
		   		   					html += 		"<div class='reply_view'>"+result[i].reply_Content+"</div>";
		   		   					html += 	"</div>"; //.reply_view_wrapper
		   		   					html += 	"</div>"; //.reply_box_wrapper
		   		   					html += "</div>"; //.re_reply_box
			   					}
	   						}
		   					html += "</div>"; //.reply_area
   						}
   					}else{
   						html += "<div>등록된 댓글이 없습니다.</div>";
   					}
   					
   					$("#reply_wrapper").html(html);
   					
   				},error:function(){
   					alert("error");
   				}
   			});
   		}

 

댓글 삭제
//댓글 삭제
   		function deleteReply(reply_Idx,bidx){
   			var ans = confirm("선택하신 댓글을 삭제하시겠습니까?");
   			if(!ans){return false;}
   			
   			$.ajax({
   				type:"post",
   				url:"community_reply_delete.do",
   				data:{"reply_Idx":reply_Idx,"bidx":bidx},
   				success:function(data){
   					if(data == 1){
   						alert("삭제가 완료되었습니다.");
   						location.reload();
   					}
   				},error:function(){
   					alert("댓글 삭제 실패");
   				}
   			});
   		}

 

댓글 수정
		//댓글 수정창띄우기
		function commentModify(reply_Idx,reply_Content,writer){
			
			var comment = ""
				comment +="<div class='reply_info_wrapper' >";
				comment +=	"<ul class='reply_info'>";
				comment +=		"<li class='id'>"+writer+"</li>";
				comment +=		"<li class='commentModify' onclick='updateBtn("+reply_Idx+",\""+reply_Content+"\");'>댓글수정</li>";
				comment +=		"<li class='cancel' onclick='getCommentList();'>취소</li>";
				comment +=	"</ul>";
				comment +="</div>"; //취소버튼 클릭시 댓글 목록리스트 함수 실행
				comment +="<div class='reply_view_wrapper'>";
				comment +=	"<textarea id='reply_Edit_Content' name='reply_Content' style='width:100%;'>"+reply_Content+"</textarea>";
				comment +="</div>";
			
			$(".reply_box_wrapper"+reply_Idx).replaceWith(comment);
		}
   		
   		//댓글 수정
   		function updateBtn(reply_Idx,reply_Content){
   			var reply_Content = $("textarea[name='reply_Content']").val(); //수정된 댓글 내용
   			
   			if(reply_Content == ""){
   				alert("내용을 입력해주세요.");
   			}else{
	   			$.ajax({
	   				url:"community_reply_update.do",
	   				type:"post",
	   				data:JSON.stringify({ "reply_Idx":reply_Idx ,"reply_Content":reply_Content}),
	   				dataType:"json",
	   				contentType : "application/json;charset=UTF-8",
	   				success:function(result){
	   					if(result == 1){
		   					alert("댓글 수정이 완료되었습니다.");
		   					getCommentList();//댓글 수정완료시 댓글 목록리스트 함수 실행
	   					}
	   				},error:function(){
	   					alert("error");
	   				}
	   			});
   			}
   		}

 

대댓글
//대댓글창 띄우기
   		function re_reply(reply_Idx,bidx){
   			if(login == ""){
   				alert("로그인 후 이용해주세요.");
   			}else{
   				var reply = "";
   					reply += "<div class='re_reply_box'>";
   					reply += 	"<span class='reply_ico'>└</span>";
   					reply += 	"<div class='reply_info_wrapper' >";
   					reply += 		"<ul class='reply_info'>";
   					reply += 			"<li class='id'>"+id+"</li>";
   					reply += 			"<li class='re_reply_btn' onclick='re_reply_btn("+reply_Idx+","+bidx+");'>댓글등록</li>";
   					reply += 			"<li class='cancel' onclick='getCommentList();'>취소</li>";//취소버튼 클릭시 댓글 목록리스트 함수 실행
   					reply +=		"</ul>";
   					reply += 	"</div>"; 
   					reply += 	"<div class='reply_view_wrapper'>";
   					reply += 		"<textarea id='reply_Edit_Content' name='reply_Content' style='width:100%;'></textarea>";
   					reply += 		"<input type='hidden' name='rparent' value="+reply_Idx+">";
   					reply += 	"</div>";
   					reply += "</div>";
	   				$(".re_reply_area"+reply_Idx).html(reply);
   			}
   			
   			//display 여부에 따라 show,hide
    			if($(".re_reply_area"+reply_Idx).css("display") == "none"){
    				$(".re_reply_area"+reply_Idx).show();
    			}else{
    				$(".re_reply_area"+reply_Idx).hide();
   			}
   		}

 

대댓글 등록
//대댓글 등록
   		function re_reply_btn(reply_Idx,bidx){
   			var reply_Content = $("textarea[name='reply_Content']").val();
   			var rparent = $("input[name=rparent]").val();
   			
   			if(reply_Content == ""){
   				alert("내용을 입력해주세요.");
   			}else{
	   			$.ajax({
	   				url:"community_re_reply.do",
	   				type:"post",
	   				data:JSON.stringify({"reply_Content":reply_Content, "bidx":bidx,"rparent":rparent}), //rparent:대댓글 다는 댓글의 idx
	   				dataType:"json",
	   				contentType:"application/json; charset=UTF-8",
	   				success:function(result){
	   					getCommentList(); //대댓글 입력시 댓글목록함수 호출
	   					
	   				},error:function(){
	   					alert("error");
	   				}
	   			});
   			}
   		}

 

 


로그인을 하지 않고 답글쓰기 클릭시 로그인 후 이용하라는 경고창이 뜬다.

 

답글쓰기 클릭시 답글 밑에 답글 입력창이 나타남

 

답글등록 완료 후 답글을 등록한 댓글 밑에 작성한 순서대로 답글이 출력된다.

 

 

드디어 완성 해서 넘뿌듯뿌듯~~!

이번에 댓글 기능을 만들면서 느낀것은

ajax로 html을 뿌려줄때 태그의 열림닫힘 표시를 잘 해두자...............헷갈려죽는 줄 

 

https://gimmesome.tistory.com/176

 

Spring MVC 로 댓글(답글) 구현하기

사진자랑 게시판(게시판명: picture)의 '댓글' 기능을 예로 들었다. picture 게시판에선 카드리스트에서 카드를 클릭하면 나오는 모달창에서 댓글 아이콘을 클릭해야 댓글들을 볼 수 있고, 댓글과 대

gimmesome.tistory.com

댓글 기능 구현시 참고했던 포스팅!!

게시판 리스트에 검색기능을 만든다.

 

SearchType과 Keyword값을 넘김

submit버튼 클릭시 boardList로 제목과 작성자가 넘어감

 

 

Criteria를 상속받는 SearchCriteria 클래스를 만들어 검색기능을 추가한다.

 

BoardController에서 searchType과 keyword의 값을 넘겨받고 기본값을 설정해준다.

기존의 범위만 가져오는 Criteria객체를 SearchCriteria객체로 새로 생성하여 값을 담는다.

PageMaker에서도  기존의 Criteria와 getter,setter를 지우고

SearchCriteria의 getter, setter를 생성해준다.

계산식 메소드인 calcData에서 Criteria에 담았던 부분을 scri(SearchCriteria)로 변경해준다.

BoardDao의 boardSelectAll에서 검색어를 검색하는 부분을 쿼리문으로 만들어 str이라는 변수에 담아주고

쿼리문이 담긴 변수를 기존의 쿼리문 사이에 추가해준다.

그리고 새로만든 쿼리문의 물음표에 해당하는 값을 넣어준다.

 

검색어에 해당하는 게시글들이 리스트에 출력되어지는 것을 확인할 수 있다.

이제 전체갯수를 뽑아내는 카운트 메소드를 수정해 페이지번호를 매기는 부분을 수정해보자. 

 

 

 

BoardDao의 TotalCount에서 SearchCriteria를 매개변수로 받게하고

boardSelectAll과 마찬가지로 검색기능이 추가된 쿼리문으로 수정하고 물음표에 해당하는 값을 넣어준다.

 

boardTotalCount의 인자값으로 scri를 넘겨준다.

검색어를 입력했을때 검색된 키워드에 해당하는 게시물의 갯수를 추출해 페이지번호를 나타내주는 걸 확인할 수 있다.

 

 

페이징 부분에 searchType과 keyword를 파라미터로 넘겨준다.

 

 

파라미터로 넘기는 부분이 한글이 넘어가면 깨지기 때문에 인코딩처리를 해야한다.

PageMaker에서 인코딩 메소드 만든 후 

keyword의 인코딩정보를 UTF-8로 입력해주고 try.catch문을 입혀준다.

변수 str에 인코딩 정보를 넘겨 반환한다.

boardList의 페이징 처리부분을 돌아와서 

keyword부분을 encoding메소드로 감싼다.

 

띄어쓰기는 +로 변경되었다.

'Board > 게시판 만들기(jsp)' 카테고리의 다른 글

[JSP] JSTL에서 삼항연산자 사용하기  (0) 2024.01.29
파일 업로드  (0) 2022.12.07
아이디 중복체크(Ajax)  (2) 2022.12.06
로그인/로그아웃 기능 구현하기(세션)  (0) 2022.12.05
게시판 페이징  (0) 2022.12.02

 

 

cos.jar
0.05MB
imgscalr-lib-4.2.jar
0.03MB

 

 

 

member0919의 midx를 board0919에 외래키로 컬럼을 추가한다.  

 

파일업로드 기능구현을 위해 lib폴더에 드라이버를 복붙해준다.

 

baordWrite에서 파일타입은 String이 아니기 때문에

String과 파일타입이 동시에 넘어갈수 있도록 인코딩타입을 지정해준다.

 


boardController

게시글을 작성하고 데이터를 넘기는(boardWriteAction)부분에

파일이름 중복정책 기능을 import하여 객체생성한다.

DefaultFileRenamePolicy는 동일한 파일명이 존재한다면 

숫자를 붙여서 새로운 파일처럼 업로드될 디렉토리에 파일을 저장하는 것을 의미한다.

 

 

파일업로드 기능을(MultipartRequest ) import하여 객체생성 

생성 후 값을 넣어줘야함

 

생성한 매개변수 값을 상단에 초기화를 해준다.

 

데이터를 넘겨받는 부분을 Request → multiRequest로 변경

 

 

 

세션사용을 위해 import해주고 

세션값 꺼냄

 

 

 

Enumertion을 import해준다.

 

 

파일이름 추출

 

 

 

BoardVo에 midx 변수  추가

 

BoardController에서 midx,pwd,filename추가

 

파일업로드 시 파일을 저장해줄 파일생성

파일이 저장이 될 경로를 파일경로에  지정해준다.

 


BoardDao

 insert메소드에서 쿼리를 변경해준다.

파일업로드 기능을 추가했으므로 filename을 물음표로 변경한다.

쿼리에 pwd, midx추가하고 ?에 값을 지정해준다.

 


MemberVo

로그인한 회원번호로 게시글 등록을 할 수 있게 MemberVo에서 midx추가해준다.

 

 


MemberDao

memberLogin에서 midx를 꺼내는 쿼리로 수정하고 midx를 추가로 담는다.

 

 

 

로그인 후 게시물 작성하여 파일업로드 후 db확인시 로그인한 midx로 게시글이 작성되었고

지정한 경로에 파일이 정상적으로 업로드되었음을 확인할 수 있다.

 

 

 


화면에 이미지 나타내어주기

 

BoardDao의 boardSelectOne 메소드에서 filename 추가

이미지 영역 생성 후 경로지정

 게시글 작성시 업로드한 이미지가 게시글에 나타내어지게된다.

 


파일다운로드.txt
0.00MB

 

파일명 클릭시 이미지 다운로드 받기

BoardController에서 파일다운로드 경로를 지정해주고 

파일의 전체경로를 작성해준다.

빨간줄부분은 import해준다.

 

이미지를 다운받을 수 있게된다.

 

https://makecodework.tistory.com/entry/JSP-cosjar-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-eclipse-%EC%97%90%EC%84%9C-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

 

[JSP] cos.jar 를 이용하여 eclipse 에서 파일 업로드 기능 구현하기

웹페이지에서 파일 업로드 기능을 구현하는 방법은 여러가지가 있는데, 그중에서 cos.jar를 이용하는 방법이 꽤 간편한 방법인 듯 하다. cos.jar 파일 다운로드 www.servlets.com 접속하기(☜ 새창에서

makecodework.tistory.com

 

 

javastudy0919.zip
3.37MB

 

 

https://doolyit.tistory.com/20

 

jQuery ajax 기본 사용법 ... 비동기적 서버통신 done,fail, always

ajax 는 Asynchronous Javascript and Xml 의 약자인데, 비동기식 자바스크립트와 XML 이라고 보면된다 javascript 의 XMLHttpRequest 를 이용하여 직접 구현하여도 되지만, jQuery 를 이용하는 것이 훨씬 더 간단하게

doolyit.tistory.com

 memberJoin에서 상단에 jquery cdn주소를 추가로 작성해준다.

 

회원가입 페이지에서 중복체크 버튼 만들고 아이디값을 부여한다.

 

 

 

제이쿼리 작성 후 중복체크버튼에 클릭이벤트 부여 시 동작이 잘되는지 alert메시지로 확인

 

input의 name이 memberId인 값을 변수 memberId에 담고

아이디체크 가상경로를 변수 url에 담는다.

 

 Ajax작성하여 회원가입시 아이디값을 입력했을때 성공여부를 확인해본다.

 

 

MemberDao에서 회원가입되어있는 아이디의 갯수를 추출하는 메소드 만든다.

 

 

 

 

 

MemberConrtoller에서 입력한 아이디값이 정상적으로 넘어왔는지 체크를 해본 후

입력한 아이디의 갯수를 value에 담는다.

idYn에 아이디의 갯수를 담은 value를 담아준다.

 

 

 

memberJoin페이지로 돌아와

form태그 안에 아이디값을 확인하는  input type="hidden" 을 작성하여 value를 지정해준다.

 

 

 

첫번째 if문

data의 길이가 0이 아니면 두번째 if문 실행 후 #Idchk값은 3이 된다.

 

두번째 if문

idYn의 값이 0이면(입력한 아이디가 회원가입이 되어있지 않으면)

'사용가능한 아이디입니다.'라는 경고창이 출력되고 #idchk2의 값이 0이 된다.  

 

0이 아닐경우엔(입력한 아이디가 이미 회원가입이 되어있음)

'사용불가능한 아이디입니다.'라는 경고창이 출력되고 #idchk2의 값이 1이 된다.

 

 

 

 

아이디 입력 후 중복체크 버튼을 누르지 않았을 때

중복체크를 하라는 경고창을 뜨게하는 구문을 유효성검사 부분에 작성한다.

아이디 중복체크를 하지않고 확인버튼을 눌렀을시

value가 3이 아닌 경우 '아이디 중복체크 해주세요' 경고창이 뜨게되고

중복된 아이디를 입력한 뒤  확인버튼을 눌렀을 시  #idchk2의 값은 1이 되므로

#idchk2가 0이 아니기때문에 '사용할 수 없는 아이디입니다.' 경고창이 뜨게된다.

 

 

 

아이디 입력하는 input의 onblur 이벤트를 걸어 포커스 영역을 벗어날때 함수를 실행한다.

 

함수가 실행되면 idchk 값이 1이 된다.

'Board > 게시판 만들기(jsp)' 카테고리의 다른 글

게시판 검색 기능  (0) 2022.12.14
파일 업로드  (0) 2022.12.07
로그인/로그아웃 기능 구현하기(세션)  (0) 2022.12.05
게시판 페이징  (0) 2022.12.02
★★★트랜잭션 ★★★  (1) 2022.11.30

 

javastudy0919.zip
3.37MB

 로그인화면 페이지 만들기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
<script>
function check(){
	
	var fm = document.frm;
	
	if(fm.memberId.value == ""){
		alert("아이디를 입력해주세요.");
		fm.memberId.focus();
		return;
	}else if(fm.memberPwd.value == ""){
		alert("비밀번호를 입력해주세요.");
		fm.memberPwd.focus();
		return;
	}
	
	//가상경로 지정
	fm.action = "<%=request.getContextPath() %>/member/memberLoginAction.do"; 
	fm.method = "post"; //감춰져서 넘기는 방식 Post
	fm.submit();
	return;
}
</script>
</head>
<body>
로그인 화면
<form name="frm">
<table border=1 style="width:270px; margin-top:10px;">
<tr>
<td style="text-align:right;">아이디 : </td>
<td style="text-align:center;"><input type="text" name = "memberId"></td>
</tr>

<tr>
<td style="text-align:right;">비밀번호 : </td>
<td style="text-align:center;"><input type="password" name = "memberPwd"></td>
</tr>

<tr>
<td colspan=2 style="text-align:center;">
<input type="button" value="로그인" onclick="check()">
<input type="button" value="취소">
</td>
</tr>

</table>
</form>
</body>
</html>

 

 

1. MemberController에서 파라미터로 넘어온 값을 받음

input에 입력된 값을 변수에 담는다.

 

2. MemberDao에서  아이디와 비밀번호를 매개변수로 받는 memberLogin 메소드 만든다.

member0919에서 delyn이 N이고 memberid와 memberpwd가 ?인 컬럼값을 조회하는 쿼리를 작성하여

연결객체에 sql문장을 담아 실행하고 결과를 가져온다.

 

 

 

3. MemberController에서 memberLogin메소드를 호출함.

로그인정보를 value값에 담아 회원정보가 있으면 1, 없으면 0값을 반환한다.

회원정보가 없으면 로그인 화면으로 이동하고

회원정보가 있으면 메인페이지로 이동한다.

로그인 성공시 메인페이지로 이동 

콘솔창에 찍어본 값도 정상적으로 출력된다.

 


세션을 사용하여 로그인 기능 구현

1. MemberDao로 돌아와

member0919에서 delyn이 N이고 아이디와 패스워드가 ? 사람의 이름과 아이디를  추출하는 쿼리로 수정한다.

그리고 if문에서 mv에 있는 아이디와 이름값을 꺼내온다.

 

 

2. MemberController에서 아이디와 비민번호를 mv에 담는다.

정상적으로 담겨졌는지 확인을 위해 콘솔창에 출력해서 확인해본다.

 

3. mv가 null이면 로그인화면으로 이동하고

null이 아닐경우 세션에 mv를 담고 메인페이지로 이동을한다.

 

HttpSession은 사용을 위해 import해준다.

 

 

 

 

 

4. index 페이지에서  MemberVo사용을 위해 import해주고 

session.setAttribute로 저장된 값은 object타입이기 때문에 값을 꺼내기위해선 형변환이 필요하다.

MemberVo로 형변환을하고 세션에 담겨있는 mv를 꺼내 변수 mv에 담는다.

그리고

mv가 null이 아닐경우 mv에 담긴 이름과 아이디를 각각의 변수에 담는다.

담긴 변수에 값으로 로그인정보를 화면에 나타나게한다.

로그인이 정상적으로 되면 index페이지에 회원이름과 아이디가 나타난다.


로그아웃 기능구현

 

index 페이지에서 로그아웃 변수를 만들어 초기화해주고

조건문안에서 변수에 로그아웃 버튼을 만들어 준 뒤 클릭이벤트를 걸어

로그아웃페이지로 이동하는 경로를 작성한다.

 

로그인을 하게되면 로그아웃 버튼이 생성된다.

 

MemberController에서 로그아웃버튼 클릭시 memberLogOut페이지로 이동하게 되면

세션을 초기화시키고 로그아웃이 되었으면 메인페이지로 이동을 한다.

 

로그아웃 버튼 클릭시 로그아웃이 된 화면을 확인할 수 있다.

 

https://enai.tistory.com/29

 

세션(Session) 이용하는 방법

세션은 클라이언트 별로 서버에 저장되는 정보이다. 사용자 컴퓨터에 저장되던 쿠키와 다르게 서버에 저장되므로, 비교적 보안이 필요한 데이터는 쿠키보다 세션에 저장한다. 서버가 종료되거

enai.tistory.com

https://muengx2.tistory.com/55

 

[HttpSession] 기초 개념

[Session] - 방문자가 웹 서버에 접속해 있는 상태 - WAS의 메모리에 Object의 형태로 저장 - 메모리가 허용하는 용량까지 제한없이 저장가능 [동작순서] - 클라이언트가 페이지 요청 - 접근한 클라이언

muengx2.tistory.com

 

'Board > 게시판 만들기(jsp)' 카테고리의 다른 글

파일 업로드  (0) 2022.12.07
아이디 중복체크(Ajax)  (2) 2022.12.06
게시판 페이징  (0) 2022.12.02
★★★트랜잭션 ★★★  (1) 2022.11.30
게시글 답변하기  (2) 2022.11.30

+ Recent posts