728x90

top.jsp

사진경로 추가

<c:if test="${!empty memberVo }">
    <ul class="nav navbar-nav">
        <ul class="dropdown-menu dropdown-menu-dark">
            <li><a class="dropdown-item" href="${root}/memberUpdateForm">회원수정</a></li>
            <li><a class="dropdown-item" href="${root}/memberImageForm">사진</a></li>
            <li><a class="dropdown-item" href="${root }/memberLogout">로그아웃</a></li>
        </ul>
        </li>
    </ul>
</c:if>

 

memberImageForm

<%--
  Created by IntelliJ IDEA.
  User: thddm
  Date: 2024-05-22
  Time: 오후 12:16
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath }"/>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- jQuery 라이브러리 -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <!-- Bootstrap 라이브러리 -->
    <script type="text/javascript">
        $(document).ready(function () {
            if(${!empty msg1}){
                $("#msgType").attr("class","modal-content panel-warning");
                $("#failModal").modal("show");

            }
        });
    </script>

    <title>Title</title>
</head>
<style>
    body {
        background-color: #f8f9fa; /* 배경색 변경 */
    }

    .panel-heading {
        background-color: #007bff; /* 헤더 색 변경 */
        color: white;
    }

    .form-control {
        border-radius: 25px; /* 입력 필드 둥글게 */
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 입력 필드 그림자 */
    }

    .btn-primary {
        background-color: #ff4081; /* 버튼 색 변경 */
        border-color: #ff4081;
        border-radius: 25px;
        display : flex;
        position: relative;
        left: 50%;
        padding: 10px 20px ;
    }

    .btn-primary:hover {
        background-color: mediumpurple; /* 버튼 호버 효과 */
        border-color: #f06292;
        color: #f8f9fa;
    }
</style>
<body>
<div class="container">
    <jsp:include page="../include/top.jsp"/>
    <div class="panel panel-default">
        <div class="panel-heading">
            <h3 class="panel-title">사진 등록</h3>
        </div>
        <div class="panel-body">
            <form action="${root }/memberImageUpdate" method="post" class="form-horizontal" enctype="multipart/form-data">
                <input type="hidden" name="memberID" value="${memberVo.memberID }">
                <div class="form-group">
                    <label class="control-label col-sm-2" >아이디:</label>
                    <div class="col-sm-8">
                        <label class="form-control" >${memberVo.memberID } </label>
                    </div>

                </div>

                <div class="form-group">
                    <label class="control-label col-sm-2" for="memberProfile">사진 업로드:</label>
                    <div class="col-sm-10">
                        <input type="file" class="form-control" id="memberProfile" name="memberProfile"
                               placeholder="사진을 등록 해 주세요">
                    </div>
                </div>
                <div class="form-group">
                    <button class="btn-primary">사진 업로드</button>
                </div>
            </form>
        </div>
    </div>
    <!-- 실패 -->
    <div class="modal fade" id="failModal" role="dialog">
        <div class="modal-dialog">
            <div class="modal-content" id="msgType">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                    <h3>${msg1 }</h3>
                </div>
                <div class="modal-body">
                    <p>${msg2 }</p>
                </div>
                <div class="modal-footer">
                    <button type="button"  class="btn btn-secondary"
                            data-dismiss="modal">Close
                    </button>

                </div>
            </div>
        </div>
    </div>
</body>
</html>

 

 

home.jsp

~~님 옆에 사진 띄우기

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- jQuery 라이브러리 -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <!-- Bootstrap 라이브러리 -->
    <script type="text/javascript">
        $(document).ready(function () {
            if (${!empty msg1}) {
                $("#msgType").attr("class", "modal-content panel-warning");
                $("#failModal").modal("show");

            }
        });
    </script>
</head>
<body>
<div class="container">
    <jsp:include page="include/top.jsp"/>
    <c:if test="${empty memberVo }">
        <h3>Spring Legacy</h3>
    </c:if>

    <!-- 디비를 확인해보면 공백 -->
    <c:if test="${!empty memberVo}">
        <c:if test="${memberVo.memberProfile eq ''}">
            <img src="${root }resources/image/naver.png" style="width: 50px; height: 50px;">
        </c:if>

        <!-- 로그인한 후 사진등록하면 사진을 upload에 저장하도록 -->
        <c:if test="${memberVo.memberProfile ne ''}">
            <img src="${root }/resources/upload/${memberVo.memberProfile}" style="width: 40px; height: 40px;">
        </c:if>
        <h3>${memberVo.memberName}님 환영합니다!</h3>
    </c:if>


    <div class="panel panel-default">
        <div>
            <img src="${root }/resources/image/naver.png" style="width:50px; height:50px">
        </div>
        <div class="panel-body">
            <ul class="nav nav-tabs">
                <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
                <li><a href="MainBoard">게시판</a></li>
                <li><a href="#" data-toggle="tab">공지</a></li>
            </ul>

            <div class="tab-content">
                <div class="tab-pane fade show active" id="home">
                    <h4>Home</h4>
                    <p>content</p>
                </div>

                <div class="tab-pane fade show " id="home1">
                    <h4>게시판</h4>
                    <p>content</p>
                </div>

                <div class="tab-pane fade show " id="home2">
                    <h4>공지</h4>
                    <p>content</p>
                </div>
            </div>
        </div>
    </div>
</div>

<div class="modal fade" id="failModal" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content" id="msgType">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h3>${msg1 }</h3>
            </div>
            <div class="modal-body">
                <p>${msg2 }</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary"
                        data-dismiss="modal">Close
                </button>

            </div>
        </div>
    </div>
</div>
</body>
</html>

 

MemberController

    @RequestMapping("/memberImageForm")
    public String memberImageForm() {
        return "member/memberImageForm";
    }

    @RequestMapping("/memberImageUpdate")
    public String memberImageUpdate(HttpServletRequest request, HttpSession session,
                                    RedirectAttributes rttr) throws IOException {

        MultipartRequest multi=null;
        int maxSize=40*1024*1024;
        String savePath=request.getRealPath("/resources/upload");
        System.out.println(savePath);

        multi=new MultipartRequest(request, savePath, maxSize, "UTF-8",
                new DefaultFileRenamePolicy());

        String memberID=multi.getParameter("memberID"); //클라이언트에서 넘김 memberID값 받음

        String newProfile="";

        File file=multi.getFile("memberProfile");  //input type file의 name값으로 파일가져옴

        if(file!=null) {
            String str=file.getName().substring(file.getName().lastIndexOf(".")+1); //확장자
            str=str.toUpperCase();

            if(str.equals("PNG") || str.equals("GIF") || str.equals("JPG")) {
                String origin=memberMapper.getMember(memberID).getMemberProfile();
                //resources/upload/.../...
                File file1=new File(savePath+"/"+origin);

                if(file1.exists()) {
                    file1.delete();
                }
                newProfile=file.getName();

            }
            else {
                if(file.exists()) {
                    file.delete();
                }
                rttr.addFlashAttribute("msg1", "실패");
                rttr.addFlashAttribute("msg2", "이미지 파일만 업로드할 수 있습니다");

                return "redirect:/memberImageForm";
            }
        }
        Member member=new Member();
        member. setMemberID(memberID);
        member. setMemberProfile(newProfile);
        memberMapper.memberProfileUpdate(member); //id기준으로 사진업데이트 됨

        Member m=memberMapper.getMember(memberID);

        session.setAttribute("memberVo", m);
        rttr.addFlashAttribute("msg1", "성공");
        rttr.addFlashAttribute("msg2", "업로드 되었습니다");

        return "redirect:/";
    }

}

 

MemberMapper

package kr.bit.mapper;

import kr.bit.entity.Member;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface MemberMapper {
    public Member registerCheck(String memberID);

    public int memberRegister(Member member);

    public  Member memberLogin(Member memberVo);

    public int memberUpdate(Member memberVo);

    public Member getMember(String memberID);

    public void memberProfileUpdate(Member memberVo);
}

 

MemberMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="kr.bit.mapper.MemberMapper">
    <select id="registerCheck" resultType="kr.bit.entity.Member">
        select *
        from member_table
        where memberID = #{memberID}
    </select>

    <insert id="memberRegister" parameterType="kr.bit.entity.Member">
        insert into member_table(memberID, memberPw, memberName, memberAge,
                                 memberGender, memberEmail, memberProfile)
        values (#{memberID}, #{memberPw}, #{memberName},
                #{memberAge}, #{memberGender}, #{memberEmail}, #{memberProfile})
    </insert>

    <select id="memberLogin" parameterType="kr.bit.entity.Member" resultType="kr.bit.entity.Member">
        select *
        from member_table
        where memberID = #{memberID}
          and memberPw = #{memberPw}
    </select>

    <update id="memberUpdate" parameterType="kr.bit.entity.Member">
        update member_table
        set memberPw=#{memberPw},
            memberName=#{memberName},
            memberAge=#{memberAge},
            memberGender=#{memberGender},
            memberEmail=#{memberEmail}
        where memberID = #{memberID}
    </update>

    <select id="getMember" resultType="kr.bit.entity.Member">
        select *
        from member_table
        where memberID = #{memberID}
    </select>

    <update id="memberProfileUpdate" parameterType="kr.bit.entity.Member">
        update member_table
        set memberProfile=#{memberProfile}
        where memberID = #{memberID}
    </update>
</mapper>

 


맨 위 디자인 변경

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath }"/>
<nav class="navbar navbar-expand-Lg navbar-dark bg-dark">
    <div class="container-fluid">
        <div class="navbar-header">
            <button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#Navbar">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="${root }/">Spring Legacy</a>
        </div>

        <div class="collapse navbar-collapse" id="Navbar">
            <ul class="nav navbar-nav">

                <li><a href="MainBoard">게시판</a></li>
            </ul>
            <c:if test="${empty memberVo }">
                <!-- 회원정보 비어있을 경우 -->
                <ul class="nav navbar-nav navbar-right">
                    <li><a class="dropdown-item" href="${root }/memberLoginForm">로그인 </a></li>
                    <li><a class="dropdown-item" href="${root }/memberJoin">회원가입</a></li>
                </ul>
            </c:if>

            <c:if test="${!empty memberVo }">
                <ul class="nav navbar-nav navbar-right">
                            <li><a href="${root}/memberUpdateForm">회원수정</a></li>
                            <li><a href="${root}/memberImageForm">사진</a></li>
                            <li><a href="${root }/memberLogout">로그아웃</a></li>

                            <c:if test="${!empty memberVo}">
                                <c:if test="${memberVo.memberProfile eq ''}">
                                    <img src="${root }resources/image/예.png" style="width: 100px; height: 100px;">
                                    ${memberVo.memberName}님 안녕하세요!
                                </c:if>
                                <c:if test="${memberVo.memberProfile ne ''}">
                                    <img src="${root }/resources/upload/${memberVo.memberProfile}"
                                         style="width: 40px; height: 40px;">
                                    ${memberVo.memberName}님 안녕하세요!
                                </c:if>
                            </c:if>
                        </ul>
            </c:if>
        </div>
    </div>
</nav>
<html>

로그인 안되어있으면 글쓰기 버튼 안보임
로그인 되어있으면 글쓰기 버튼이 보임

main.jsp

    //로그인이 안되어있으면 글작성 버튼이 안보임
    if(${!empty memberVo}) {

        li += "<tr>";
        li += "<td colspan='5'>";
        li += "<button class='btn btn-primary btn-sm' onclick='getForm()'>글작성</button>";
        li += "</td>";
        li += "</tr>";
    }
    li += "</table>";
    // 생성한 테이블을 화면에 적용
    $("#view").html(li);
    // 화면에 테이블을 표시
    $("#view").css("display", "block");
    // 글 작성 폼을 숨
    $("#wfrom").css("display", "none");
}

 

728x90
728x90

RedirectAttributes / addFlashAttribute

 

RedirectAttributes 

리다이렉트 시 데이터를 전달하는 방법 중 하나로, 스프링 프레임워크에서는 RedirectAttributes를 제공한다.

리다이렉트 동작 원리

  1. HTTP 요청 흐름:
    • 리다이렉트가 발생하면 기존 요청이 끊기고 새로운 HTTP GET 요청이 시작된다.
  2. 모델 데이터의 소멸:
    • 리다이렉트 이전에 수행된 모델 데이터는 새로운 요청이 시작되면서 사라지기 때문에, 리다이렉트를 통해 모델을 전달하는 것은 불가능하다.

쿼리스트링 사용의 문제점

  • 데이터를 전달하기 위해 쿼리스트링을 사용할 경우, URL에 데이터가 노출되는 단점이 있다.

RedirectAttributes 사용의 장점

  • 플래시 속성 사용:
    • RedirectAttributes는 리다이렉트 전 플래시 속성을 세션에 저장하고, 리다이렉트 후 해당 속성을 세션에서 모델로 이동시킨다.
    • 이 방식은 헤더에 파라미터를 붙이지 않기 때문에 URL에 노출되지 않는다.
  • 일회성 속성:
    • addFlashAttribute를 사용하여 일회성 성공 알림 등을 구현할 수 있다.
    • 플래시 속성은 일회성으로, 새로고침하면 사라진다.

cf)

@PostMapping("/submit")
public String handleFormSubmission(RedirectAttributes redirectAttributes) {
    // 비즈니스 로직 수행 후
    redirectAttributes.addFlashAttribute("message", "성공적으로 처리되었습니다.");
    return "redirect:/success";
}

@GetMapping("/success")
public String showSuccessPage(Model model) {
    // 플래시 속성으로부터 데이터 가져오기
    String message = (String) model.getAttribute("message");
    model.addAttribute("message", message);
    return "successPage";
}

 

실제 구현 코드

package kr.bit.controller;


import kr.bit.entity.Member;
import kr.bit.mapper.MemberMapper;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;

@Controller
public class MemberController {

    @Autowired
    MemberMapper memberMapper;

    @RequestMapping(value = "/memberJoin")
    public String memberJoin() {
        return "member/join";
    }

    @RequestMapping("/memberRegisterCheck") //ajax에서 넘긴 id값을 주입받음
    public @ResponseBody int memberRegisterCheck(@RequestParam("memberID") String memberID) {

        Member m = memberMapper.registerCheck(memberID);
        if (m != null || memberID.equals("")) {
            return 0; // 이미 존재하는 아이디
        }
        return 1; //새로 생성되는 아이디
    }

    @RequestMapping("/memberRegister")
    public String memberRegister(Member member, String memberPw1, String memberPw2, RedirectAttributes rttr, HttpSession session) {
        if (member.getMemberID().equals("") ||
                memberPw1.equals("") ||
                memberPw2.equals("") ||
                member.getMemberName().equals("") ||
                member.getMemberGender().equals("") ||
                member.getMemberEmail().equals("")) {
            rttr.addFlashAttribute("msg1", "실패!");
            rttr.addFlashAttribute("msg2", "필수 입력사항을 모두 입력해주세요!");
            return "redirect:/memberJoin";
        }
        if (!memberPw1.equals(memberPw2)) {
            rttr.addFlashAttribute("msg1", "실패!");
            rttr.addFlashAttribute("msg2", "비밀번호가 일치하지 않습니다!");
            return "redirect:/memberJoin";
        }
        int result = memberMapper.register(member); // db에 회원정보 저장
        member.setMemberProfile("");

        if (result == 1) { //1행 추가됨 -> insert 성공되면
            rttr.addFlashAttribute("msg1", "a");
            rttr.addFlashAttribute("msg2", "회원가입에 성공했습니다");

            session.setAttribute("memberVo",member);

            return "redirect:/";

        } else {
            rttr.addFlashAttribute("msg1", "실패");
            rttr.addFlashAttribute("msg2", "회원가입에 실패했습니다");

            return "redirect:memberJoin/";

        }

    }
}

 

join.jsp

추가 코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function () {

            if (${!empty msg1}) {
                $("#msgType").attr("class", "modal-content panel-warning");
                $("#failModal").modal("show");
            }
        });

        function doubleCheck() {
            let memberID = $("#memberID").val(); // 폼에서 적은 id값 가져오기

            $.ajax({
                url: "${root}/memberRegisterCheck",
                type: "get",
                data: {"memberID": memberID},
                success: function (result) {
                    if (result == 1) {
                        $("#checkMessage").html("사용할 수 있는 아이디입니다.");
                    } else {
                        $("#checkMessage").html("사용할 수 없는 아이디입니다.");
                    }
                    $("#exampleModal").modal("show");
                },
                error: function () {
                    alert("error");
                }
            });
        }

        function goInsert(){

            let memberAge=$("#memberAge").val();
            if(memberAge==0 || memberAge==""){ // 입력한 값과 비교하기 위해서 공백처리(입력한값)
                alert("나이를 입력하세요!");
                return false;
            }
            document.frm.submit(); //서버에 전송
        }

        function passwordCheck() {
            let memberPw1 = $("#memberPw1").val();
            let memberPw2 = $("#memberPw2").val();

            if (memberPw1 != memberPw2) {
                $("#passMessage").html("비밀번호가 일치하지 않습니다");
            } else {
                $("#passMessage").html("비밀번호가 일치합니다!").css("color", "green");
                $("#memberPw").val(memberPw1); // 서버에 히든값으로 전송
            }
        }

    </script>
    <style>
        body {
            background-color: #f8f9fa;
            font-family: 'Helvetica Neue', Arial, sans-serif;
            padding-top: 50px;
        }

        .form-container {
            background: white;
            padding: 40px;
            border-radius: 12px;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
        }

        .form-control {
            border-radius: 30px;
            padding: 15px;
        }

        .btn-custom {
            border-radius: 30px;
            background-color: #007bff;
            border: none;
            color: white;
            transition: background-color 0.3s ease;
        }

        .btn-custom:hover {
            background-color: #0056b3;
        }

        .modal-header {
            background-color: #343a40;
            color: white;
        }

        .modal-footer .btn-secondary {
            border-radius: 30px;
        }
    </style>
</head>
<body>
<div class="container d-flex justify-content-center">
    <div class="col-md-8 form-container">
        <h2 class="text-center mb-4">회원가입</h2>
        <!-- 회원가입 폼 시작 -->
        <form name="frm" action="${root}/memberRegister" method="post">
            <input type="hidden" id="memberPw" name="memberPw" value=""/>
            <div class="mb-3">
                <label for="memberID" class="form-label">아이디</label>
                <div class="input-group">
                    <input type="text" class="form-control" id="memberID" name="memberID" placeholder="아이디를 입력해">
                    <button type="button" class="btn btn-custom ms-2" onclick="doubleCheck()">중복확인</button>
                </div>
            </div>
            <div class="mb-3">
                <label for="memberPw1" class="form-label">비밀번호</label>
                <input type="password" class="form-control" id="memberPw1" name="memberPw1" onkeyup="passwordCheck()"
                       placeholder="비밀번호 입력">
            </div>
            <div class="mb-3">
                <label for="memberPw2" class="form-label">비밀번호 확인</label>
                <input type="password" class="form-control" id="memberPw2" name="memberPw2" onkeyup="passwordCheck()"
                       placeholder="비밀번호 확인">
            </div>
            <div class="mb-3">
                <label for="memberName" class="form-label">이름</label>
                <input type="text" class="form-control" id="memberName" name="memberName" placeholder="이름을 입력하세요">
            </div>
            <div class="mb-3">
                <label for="memberAge" class="form-label">나이</label>
                <input type="number" class="form-control" id="memberAge" name="memberAge" maxlength="10"
                       placeholder="나이를 입력하세요">
            </div>
            <div class="mb-3">
                <label for="memberGender" class="form-label">성별</label>
                <div class="d-flex">
                    <div class="form-check me-3">
                        <input class="form-check-input" type="radio" name="memberGender" id="male" value="남자" checked>
                        <label class="form-check-label" for="male">남자</label>
                    </div>
                    <div class="form-check">
                        <input class="form-check-input" type="radio" name="memberGender" id="female" value="여자">
                        <label class="form-check-label" for="female">여자</label>
                    </div>
                </div>
            </div>
            <div class="mb-3">
                <label for="memberEmail" class="form-label">이메일</label>
                <input type="email" class="form-control" id="memberEmail" name="memberEmail" maxlength="50"
                       placeholder="이메일을 입력하세요" onkeyup="emailCheck()">
            </div>
            <div class="d-flex justify-content-between align-items-center">
                <span id="passMessage" class="text-danger"></span>
                <button type="button" class="btn btn-custom" onclick="goInsert()">등록</button>
            </div>
        </form>
        <!-- 회원가입 폼 끝 -->
    </div>
</div>

<!-- 모달 -->
<div class="modal fade" id="exampleModal" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h3>메시지 확인</h3>
            </div>
            <div class="modal-body">
                <p id="checkMessage"></p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary"
                        data-dismiss="modal">Close
                </button>
            </div>
        </div>
    </div>
</div>

<!-- 실패 -->
<div class="modal fade" id="failModal" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content" id="msgType">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h3>${msg1 }</h3>
            </div>
            <div class="modal-body">
                <p>${msg2 }</p>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary"
                        data-dismiss="modal">Close
                </button>
            </div>
        </div>
    </div>
</div>

</body>
</html>

로그인기능

모달 추가!

home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- jQuery 라이브러리 -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <!-- Bootstrap 라이브러리 -->
    <script type="text/javascript">
        $(document).ready(function () {
            if(${!empty msg1}){
                $("#msgType").attr("class","modal-content panel-warning");
                $("#failModal").modal("show");

            }
        });
    </script>
</head>
<body>
<div class="container">
    <jsp:include page="include/top.jsp"/>
        <div class="panel panel-default">
            <div class="panel-body">
                <ul class="nav nav-tabs">
                    <li class="active"><a data-toggle="tab" href="#home">Home</a></li>
                    <li><a href="MainBoard">게시판</a></li>
                    <li><a href="#" data-toggle="tab" >공지</a></li>
                </ul>

                <div class="tab-content">
                    <div class="tab-pane fade show active" id="home">
                        <h4>Home</h4>
                        <p>content</p>
                    </div>

                    <div class="tab-pane fade show " id="home1">
                        <h4>게시판</h4>
                        <p>content</p>
                    </div>

                    <div class="tab-pane fade show " id="home2">
                        <h4>공지</h4>
                        <p>content</p>
                    </div>
                </div>
            </div>
    </div>
</div>

<div class="modal fade" id="failModal" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content" id="msgType">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h3>${msg1 }</h3>
            </div>
            <div class="modal-body">
                <p>${msg2 }</p>
            </div>
            <div class="modal-footer">
                <button type="button"  class="btn btn-secondary"
                        data-dismiss="modal">Close
                </button>

            </div>
        </div>
    </div>
</div>
</body>
</html>

top.jsp

<%--
  Created by IntelliJ IDEA.
  User: thddm
  Date: 2024-05-21
  Time: 오후 12:52
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath }"/>
<nav class="navbar navbar-expand-Lg navbar-dark bg-dark">
    <div class="container-fluid">
        <div class="navbar-header">
            <button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#Navbar">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="${root }/">Spring Legacy</a>
        </div>

        <div class="collapse navbar-collapse" id="Navbar">
            <ul class="nav navbar-nav">

                <li><a href="MainBoard">게시판</a></li>
            </ul>
            <c:if test="${empty memberVo }">
                <!-- 회원정보 비어있을 경우 -->
                <ul class="nav navbar-nav">
                    <li class="dropdown"><a class="dropdown-toggle" href="#"
                                            data-toggle="dropdown"> 클릭! </a>
                        <ul class="dropdown-menu dropdown-menu-dark">
                            <li><a class="dropdown-item" href="${root }/memberLoginForm">로그인 </a></li>
                            <li><a class="dropdown-item" href="${root }/memberJoin">회원가입</a></li>
                        </ul></li>
                </ul>
            </c:if>

            <c:if test="${!empty memberVo }">
                <ul class="nav navbar-nav">
                    <li class="dropdown"><a class="dropdown-toggle" href="#"
                                            data-toggle="dropdown"> 클릭! </a>
                        <ul class="dropdown-menu dropdown-menu-dark">
                            <li><a class="dropdown-item" href="#">회원수정</a></li>
                            <li><a class="dropdown-item" href="#">사진</a></li>
                            <li><a class="dropdown-item" href="${root }/memberLogout">로그아웃</a></li>
                        </ul></li>
                </ul>
            </c:if>
        </div>
    </div>
</nav>
<html>
<head>
    <title>Title</title>
</head>
<body>

</body>
</html>
<li class="nav-item dropdown">
    <a href="${root }/">
        Home
    </a>
</li>

 

memberController

package kr.bit.controller;

import kr.bit.entity.Member;
import kr.bit.mapper.MemberMapper;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;

@Controller
public class MemberController {
    @Autowired
    MemberMapper memberMapper;

    @RequestMapping("/memberJoin")
    public String join() {
        return "member/join";
    }

    @RequestMapping("/member/checkDuplicate")
    public @ResponseBody int checkDuplicate(@RequestParam("memberID") String memberID) {

        Member m = memberMapper.registerCheck(memberID);

        if (m == null || memberID.isEmpty()) {
            return 0;
        }
        return 1;
    }

    @RequestMapping("/memberRegister")
    public String memberRegister(Member member, String memberPw1, String memberPwCheck,
                                 RedirectAttributes rttr, HttpSession session) { //@ModelAttribute 생략  Model model 앞
        if (member.getMemberID().equals("") ||
                memberPw1.equals("") ||
                memberPwCheck.equals("") || member.getMemberName().equals("") ||
                member.getMemberGender().equals("") ||
                member.getMemberEmail().equals("")) {
            rttr.addFlashAttribute("msg1", "실패");
            rttr.addFlashAttribute("msg2", "입력해주세요");

            return "redirect:/memberJoin";
        }

        if (!memberPw1.equals(memberPwCheck)) {
            rttr.addFlashAttribute("msg1", "실패");
            rttr.addFlashAttribute("msg2", "비밀번호가 다릅니다");

            return "redirect:/memberJoin";
        }

        int result = memberMapper.memberRegister(member); // db에 회원정보 삽입
        member.setMemberProfile("");
        if (result == 1) { //1행 추가됨 <- insert 가 성공했다는 전제하
            rttr.addFlashAttribute("msg1", "성공 메세지");
            rttr.addFlashAttribute("msg2", "회원가입에 성공했습니다.");

            session.setAttribute("memberVo", member);

            return "redirect:/";
        } else {
            rttr.addFlashAttribute("msg1", "실패");
            rttr.addFlashAttribute("msg2", "회원가입에 실패했습니다");
            return "redirect:memberJoin/";
        }
    }

    @RequestMapping("/memberLoginForm")
    public String memberLoginForm() {
        return "member/memberLoginForm";
    }

    @RequestMapping("/memberLogout")
    public String memberLogout(HttpSession session) {
        session.invalidate();
        return "redirect:/";
    }

    @RequestMapping("/memberLogin")
    public String memberLogin(Member member, RedirectAttributes rttr,
                              HttpSession session) {

        if(member.getMemberID().equals("") ||
                member.getMemberPw().equals("")) {

            rttr.addFlashAttribute("msg1","실패");
            rttr.addFlashAttribute("msg2","아이디나 비밀번호를 입력하세요");

            return "redirect:memberLoginForm/";
        }

        Member memberVo=memberMapper.memberLogin(member);
        //id와 pw가 일치할경우 회원정보들을 memberVo에 저장

        if(memberVo!=null) {
            rttr.addFlashAttribute("msg1","성공");
            rttr.addFlashAttribute("msg2","로그인 되었습니다");

            session.setAttribute("memberVo", memberVo);

            return "redirect:/";
        }
        else {

            rttr.addFlashAttribute("msg1","실패");
            rttr.addFlashAttribute("msg2","로그인 다시 하세요");
            return "redirect:memberLoginForm/";
        }
    }
}


로그인 사용자 출력

바디 부분에 추가

<body>
<div class="container">
    <jsp:include page="include/top.jsp"/>
    <c:if test="${empty memberVo }">
        <h3>Spring Legacy</h3>
    </c:if>

    <c:if test="${!empty memberVo}">
        <h3>${memberVo.memberName}님 환영합니다!</h3>
    </c:if>


회원정보수정

memberUpdateForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath }"/>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function(){

            if(${!empty msg1}){
                $("#msgType").attr("class","modal-content panel-warning");
                $("#failModal").modal("show");
            }
        });

        function passwordCheck(){

            let memberPw1=$("#memberPw1").val();
            let memberPw2=$("#memberPw2").val();

            if(memberPw1 != memberPw2){
                $("#passMessage").html("비밀번호가 일치하지 않습니다");
            }
            else{   //(비번, 비번확인이 일치한다면)
                $("#passMessage").html("비밀번호가 일치합니다").css("color", "yellowgreen");
                $("#memberPw").val(memberPw1); //히든 value값에 비번 넣음

            }
        }

        function goUpdate(){

            let memberAge=$("#memberAge").val();
            if(memberAge==0 || memberAge==""){
                alert("나이를 입력하세요!");
                return false;
            }
            document.frm.submit();  //서버에 전송

        }
    </script>
</head>
<style>
    body {
        background-color: #f8f9fa; /* 배경색 변경 */
    }

    .panel-heading {
        background-color: #007bff; /* 헤더 색 변경 */
        color: white;
    }

    .form-control {
        border-radius: 25px; /* 입력 필드 둥글게 */
        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); /* 입력 필드 그림자 */
    }

    .btn-primary {
        background-color: #ff4081; /* 버튼 색 변경 */
        border-color: #ff4081;
        border-radius: 25px;
    }

    .btn-primary:hover {
        background-color: #f06292; /* 버튼 호버 효과 */
        border-color: #f06292;
    }
</style>
<body>
<div class="container">
    <jsp:include page="../include/top.jsp"/>
    <div class="panel panel-default">
        <div class="panel-heading">회원 정보 수정
        </div>
        <div class="panel-body">
            <form name="frm" action="${root }/memberUpdate" method="post">
                <input type="hidden" id="memberID" name="memberID" value="${memberVo.memberID }" />
                <input type="hidden" id="memberPw" name="memberPw" value="" />
                <table class='table table-bordered' style="text-align: center;">
                    <tr>
                        <td style="width: 100px; vertical-align: middle;">아이디</td>
                        <td>${memberVo.memberID }</td>
                    </tr>

                    <tr>
                        <td style="width: 100px; vertical-align: middle;" />비밀번호
                        </td>
                        <td colspan="2"><input class="form-control" type="password"
                                               id="memberPw1" name="memberPw1" onkeyup="passwordCheck()"
                                               placeholder="비밀번호를 입력" /></td>
                    </tr>

                    <tr>
                        <td style="width: 100px; vertical-align: middle;" />비밀번호확인
                        </td>
                        <td colspan="2"><input class="form-control" type="password"
                                               id="memberPw2" name="memberPw2" onkeyup="passwordCheck()"
                                               placeholder="비밀번호 확인" /></td>
                    </tr>

                    <tr>
                        <td style="width: 100px; vertical-align: middle;" />이름
                        </td>
                        <td colspan="2"><input class="form-control" type="text"
                                               id="memberName" name="memberName" placeholder="이름을 확인"
                                               value=${memberVo.memberName } /></td>
                    </tr>

                    <tr>
                        <td style="width: 100px; vertical-align: middle;">나이</td>
                        <td colspan="2"><input id="memberAge" name="memberAge"
                                               class="form-control" type="number" maxlength="10"
                                               placeholder="나이를 입력하세요."
                                               value=${memberVo.memberAge } /></td>
                    </tr>

                    <tr>
                        <td style="width: 100px; vertical-align: middle;">성별</td>
                        <td colspan="2">
                            <div class="form-group"
                                 style="text-align: center; margin: 0 auto;">

                                <input type="radio" name="memberGender" autocomplete="off"
                                       value="남자"
                                       <c:if test="${memberVo.memberGender eq '남자'}">checked</c:if> />남자


                                <input type="radio"
                                       name="memberGender" autocomplete="off" value="여자"
                                       <c:if test="${memberVo.memberGender eq '여자'}">checked</c:if> />여자
                            </div>
        </div>
        </td>
        </tr>

        <tr>
            <td style="width: 100px; vertical-align: middle;">이메일</td>
            <td colspan="2"><input id="memberEmail" name="memberEmail"
                                   class="form-control" type="text" maxlength="20"
                                   placeholder="이메일을 입력하세요." value="${memberVo.memberEmail }"/></td>
        </tr>

        <tr>
            <td colspan="3" style="text-align: left;"><span
                    id="passMessage" style="color: red"></span><input type="button"
                                                                      class="btn btn-primary btn-sm pull-right" value="수정"
                                                                      onclick="goUpdate()" /></td>

        </tr>

        </table>
        </form>
    </div>

    <!-- 모달 -->
    <div class="modal fade" id="exampleModal" role="dialog">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                    <h3>메시지 확인</h3>
                </div>
                <div class="modal-body">
                    <p id="checkMessage"></p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary"
                            data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 실패 -->
    <div class="modal fade" id="failModal" role="dialog">
        <div class="modal-dialog">
            <div class="modal-content" id="msgType">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">&times;</button>
                    <h3>${msg1 }</h3>
                </div>
                <div class="modal-body">
                    <p>${msg2 }</p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary"
                            data-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
</div>
</div>
</body>

 

memberController

@RequestMapping("/memberUpdateForm")
public String memberUpdateForm() {
    return "member/memberUpdateForm";
}

@RequestMapping("/memberUpdate")
public String memberUpdate(Member member, String memberPw1, String memberPw2,
                           RedirectAttributes rttr, HttpSession session) { //@ModelAttribute 생략  Model model 앞
    if (member.getMemberID().equals("") ||
            memberPw1.equals("") ||
            memberPw2.equals("") || member.getMemberName().equals("") ||
            member.getMemberGender().equals("") ||
            member.getMemberEmail().equals("")) {
        rttr.addFlashAttribute("msg1", "실패");
        rttr.addFlashAttribute("msg2", "입력해주세요");

    }
    if (!memberPw1.equals(memberPw2)) {
        rttr.addFlashAttribute("msg1", "실패");
        rttr.addFlashAttribute("msg2", "비밀번호가 다릅니다");

        return "redirect:/memberUpdateForm";
    }

    int result = memberMapper.memberUpdate(member);

    if (result == 1) {
        rttr.addFlashAttribute("msg1", "성공");
        rttr.addFlashAttribute("msg2", "회원정보 수정에 성공했습니다.");

        session.setAttribute("memberVo", member);
        //수정된 데이터들을 세션영역 memberVo에 담아서 redirect로 화면이동

        return "redirect:/";
    } else { // 수정 실패했을 때
        rttr.addFlashAttribute("msg1", "실패");
        rttr.addFlashAttribute("msg2", "회원정보 수정에 실패했습니다.");

        return "redirect:/memberUpdateForm";
    }
}

 

MemberMapper.xml

<update id="memberUpdate" parameterType="kr.bit.entity.Member">
    update member_table
    set memberPw=#{memberPw},
        memberName=#{memberName},
        memberAge=#{memberAge},
        memberGender=#{memberGender},
        memberEmail=#{memberEmail}
    where memberID = #{memberID}
    </update>

 

MemberMapper.interface

package kr.bit.mapper;

import kr.bit.entity.Member;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface MemberMapper {
    public Member registerCheck(String memberID);

    public int memberRegister(Member member);

    public  Member memberLogin(Member memberVo);

    public int memberUpdate(Member memberVo);
}

728x90
728x90

XML 설정

 

기본구조

 

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

      <filter>
	    <filter-name>encodingFilter</filter-name>
	    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	    <init-param>
	       <param-name>encoding</param-name>
	       <param-value>UTF-8</param-value>
	    </init-param>
	    <init-param>
	       <param-name>forceEncoding</param-name>
	       <param-value>true</param-value>
	    </init-param>
	 </filter>
	 <filter-mapping>
	    <filter-name>encodingFilter</filter-name>
	    <url-pattern>/*</url-pattern>
	 </filter-mapping>

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>

	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

 

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/main/webapp/**" location="/main/webapp/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

	<context:component-scan base-package="kr.bit.controller" />



</beans:beans>

 

root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           https://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           https://www.springframework.org/schema/context/spring-context.xsd http://mybatis.org/schema/mybatis-spring https://mybatis.org/schema/mybatis-spring.xsd">

    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/springlegacy?serverTimezone=UTC"/>
        <property name="username" value="root"/>
        <property name="password" value="0000"/>
    </bean>

    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <constructor-arg ref="hikariConfig"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath:kr/bit/mapper/*.xml"/>
    </bean>

    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactory"/>
    </bean>

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="kr.bit.mapper"/>
    </bean>

</beans>

BoardController

package kr.bit.controller;

import kr.bit.entity.Board;
import kr.bit.mapper.BoardMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class BoardController {

    private final BoardMapper boardMapper;

    @RequestMapping("/")
    public String home() {
        return "home";
    }

    @RequestMapping("/boardList")
    public @ResponseBody List<Board> boardList() {
        return boardMapper.getList();    // json 데이터 형식으로 변환해서 리턴
    }
}

 

Controller 리턴 타입

  • String :  jsp파일의 경로와 파일이름을 나타내기 위해서 사용 
  • void : 호출하는 URL과 동일한 이름의 jsp를 의미 
  • 객체 타입 : 주로 JSON타입의 데이터를 만들어서 반환하는 용도 
    (이 경우는 주로 JSON데이터를 만들어 내는 용도로 사용)
  • ResponseEntity 타입 : response할 때 Http헤더정보와 내용을 가공하는 용도

 

@RequestBody, @ResponseBody

스프링 프레임워크에서 비동기 통신, API 통신을 구현하기 위해 @RequestBody, @ResponseBody를 사용할 수 있다.

  • @RequestBody : 클라이언트 -> 서버 요청 (json기반의 HTTP Body를 자바 객체로 변환)
  • @ResponseBody : 서버 -> 클라이언트 응답 (자바 객체를 json기반의 HTTP Body로 변환)

 

BoardMapper

package kr.bit.mapper;

import kr.bit.entity.Board;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Update;

import java.util.List;

@Mapper
public interface BoardMapper {
    public List<Board> getList();

    public void insertBoard(Board board);

    public Board getBoard(int idx);

    public void deleteBoard(int idx);

    public void updateBoard(Board board);

    @Update("update bitboard set count = count + 1 where board_idx = #{board_idx}")
    public void plusCount(int board_idx);
}

BoardMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="kr.bit.mapper.BoardMapper">

    <select id="getList" resultType="kr.bit.entity.Board">
        select * from bitboard order by board_idx desc
    </select>

    <insert id="insertBoard" parameterType="kr.bit.entity.Board">
        insert into bitboard(board_title, board_content, board_writer)
        values (#{board_title}, #{board_content}, #{board_writer})
    </insert>

    <select id="getBoard" resultType="kr.bit.entity.Board">
        select * from bitboard where board_idx = #{board_idx}
    </select>

    <delete id="deleteBoard" parameterType="int">
        delete from bitboard where board_idx = #{board_idx}
    </delete>

    <update id="updateBoard" parameterType="kr.bit.entity.Board">
        update bitboard
        set board_title = #{board_title}, board_content = #{board_content}, board_writer = #{board_writer}
    </update>
</mapper>

 

Board

package kr.bit.entity;

import lombok.Data;


@Data
public class Board {
    private int board_idx;
    private String board_title;
    private String board_content;
    private String board_writer;
    private String board_datetime;
    private int board_count;
}

Rest방식 / Ajax

브라우저에서 순수 데이터만을 전달할 수 있음

  •  서버는 클라이언트의 요청 결과를 xml, json형태로 전달하고, 브라우저에서 이를 가공하여 사용자에게 보여주는 방식

cf) 만약 하나의 페이지(jsp)에서 두가지 일을 처리해야 할 경우

     게시판 리스트와 로그인을 출력하는 일

  • 동기식 처리방식 : 1번일이 끝날때까지 기다린 후 2번일을 처리하는 방식(응답시간이 길어지며 화면이 바뀐다)
  • 비동기식 처리방식 : 1번 일과는 상관없이 2번일을 처리하는 방식(응답시간이 빠르고, 화면전환이 없다) 
    -> 콜백함수를 만들어 처리하게 해야한다

 

콜백함수

  • 서버로 요청 후 서버에서 응답하는 데이터를 클라이클라이언트가언트에서 받아서 처리하는 함수

 

 

Ajax 동작 방식

 

 

REST(Representational State Transfer)

 

home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            loadBoard();
        });

        function loadBoard() {
            $.ajax({
                url: "boardList",
                type: "GET",
                dataType: "json",
                success: make,
                error: function () {
                    alert("error");
                }
            });
        }

        function make(data) {
            var li = "<table class='table table-bordered'>";
            li += "<tr>";
            li += "<td>글번호</td>";
            li += "<td>제목</td>";
            li += "<td>글쓴이</td>";
            li += "<td>작성일</td>";
            li += "<td>조회수</td>";
            li += "</tr>"

            $.each(data, function (index, board) { // obj={"idx":1, "title":"제목1"..
                li += "<tr>";
                li += "<td>" + board.board_idx + "</td>";
                // 글번호(idx값) 가지고 goContent함수 <td id = "tit1">goContent(1)
                li += "<td id='tit" + board.board_idx + "'><a href='javascript:goContent(" + board.board_idx + ")'>" + board.board_title + "</a></td>";
                li += "<td>" + board.board_writer + "</td>";
                li += "<td>" + board.board_datetime.split(' ')[0] + "</td>";
                li += "<td id='cnt" + board.board_idx + "'>" + board.board_count + "</td>";
                li += "</tr>";

                li += "<tr id='con" + board.board_idx + "' style='display:none'>";
                li += "<td>내용</td>";
                li += "<td colspan='4'>";
                li += "<textarea id='ta" + board.board_idx + "' readonly rows='7' class='form-control'>"+board.board_content+"</textarea>";
                li += "<br/>";
                li += "<span id='up" + board.board_idx + "'><button class='btn btn-success btn-sm' onclick='goUpdateForm(" + board.board_idx + ")'>수정화면</button></span>&nbsp;";
                li += "<button class='btn btn-danger btn-sm' onclick='goDelete(" + board.board_idx + ")'>삭제</button>";
                li += "</td>";
                li += "</tr>";
            });

            li += "<tr>";
            li += "<td colspan='5'>";
            li += "<button class='btn btn-primary btn-sm' onclick='getForm()'>글작성</button>";
            li += "</td>";
            li += "</tr>";
            li += "</table>";

            $("#view").html(li);
            $("#view").css("display", "block");
            $("#wfrom").css("display", "none");
        }

        function goDelete(idx){
            $.ajax({
                url : "deleteBoard",
                type : "get",
                data : {"idx":idx}, // 삭제할 글 번호를 서버에 전달
                success : loadBoard,
                //서버와의 통신이 성공되면 loadBoard메소드를 호출 -> 삭제한 후의 결과를 테이블 형식으로 출력
                error : function(){
                    alert("error");
                }
            });
        }

        function goInsert() {

            let formData = $("#frm").serialize();

            $.ajax({
                url: "insertBoard",
                type: "POST", // post 방식으로 /boardInsert로 매핑
                data: formData, // 내가 폼에 입력한 데이터를 서버로 전달
                success: loadBoard,
                //서버와의 통신이 성공되면 loadBoard 메소드 호출 -> 내가 쓴거 테이블 형식으로 출력
                error: function () {
                    alert("Error");
                }
            });
        }
        // 제목을 클릭하면 내용을 보이게 함
        function goContent(board_idx) {
            if($("#con"+board_idx).css("display")=="none"){ // 내용폼이 안보이는 상황이면
                $("#con"+board_idx).css("display","table-row"); // 제목을 눌렀을 때 폼이 보임
            }
            else{
                $("#con"+board_idx).css("display","none"); // 제목 누르면 안보이게
            }
        }


        function getForm() {
            $("#wfrom").css("display", "block");
            $("#view").css("display", "none");
        }

        function goList() {
            $("#view").css("display", "block");
            $("#wfrom").css("display", "block");
        }


    </script>
</head>
<body>
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">게시판</div>
        <div class="panel-body" id="view">본문</div>
        <div class="panel-body" id="wfrom" style="display: none">
            <form id="frm">
                <table class="table">
                    <tr>
                        <td>제목</td>
                        <td><input type="text" id="title" name="board_title" class="form-control"/></td>
                    </tr>
                    <tr>
                        <td>내용</td>
                        <td><textarea rows="7" class="form-control" id="content" name="board_content"></textarea></td>
                    </tr>
                    <tr>
                        <td>글쓴이</td>
                        <td><input type="text" id="writer" name="board_writer" class="form-control"/></td>
                    </tr>
                    <tr>
                        <td colspan="2" align="center">
                            <button type="button" class="btn btn-success btn-sm" onclick="goInsert()">등록</button>
                            <button type="reset" class="btn btn-warning btn-sm" id="formclear">취소</button>
                            <button type="button" class="btn btn-info btn-sm" onclick="goList()">리스트</button>
                        </td>
                    </tr>
                </table>
            </form>
        </div>
        <div class="panel-footer">비트캠프</div>
    </div>
</div>
</body>
</html>

 

BoardController

@RequestMapping("/insertBoard")
public @ResponseBody void boardInsert(Board board) {
   boardMapper.insertBoard(board);
}

 


제목을 클릭했을 때 내용을 보이게 함 / 숨김

    // 제목을 클릭하면 내용을 보이게 함
        function goContent(board_idx) {
            if($("#con"+board_idx).css("display")=="none"){ // 내용폼이 안보이는 상황이면
                $("#con"+board_idx).css("display","table-row"); // 제목을 눌렀을 때 폼이 보임
            }
            else{
                $("#con"+board_idx).css("display","none"); // 제목 누르면 안보이게
            }
        }

 

 

삭제

home.jsp

        function goDelete(idx) {
            $.ajax({
                url: "deleteBoard",
                type: "get",
                data: {"idx": idx}, // 삭제할 글 번호를 서버에 전달
                success: loadBoard,
                //서버와의 통신이 성공되면 loadBoard메소드를 호출 -> 삭제한 후의 결과를 테이블 형식으로 출력
                error: function () {
                    alert("error");
                }
            });
        }

BoardController

    @RequestMapping("/deleteBoard")
    public @ResponseBody void boardDelete(@RequestParam("idx") int idx) {
        boardMapper.deleteBoard(idx);
    }

Update

 

home.jsp

  function goUpdate(idx) {

            let title = $("#nt" + idx).val();
            let content = $("#ta" + idx).val();

            $.ajax({
                url: "updateBoard",
                type: "POST",
                data: {"board_idx": idx, "board_title": title, "board_content": content}, //수정해서 가지고 갈 값
                success: loadBoard,
                error: function () {
                    alert("error");
                }
            })
        }

 

controller

   @RequestMapping("/updateBoard")
    public @ResponseBody void boardUpdate(Board board) {
        boardMapper.updateBoard(board);
    }

BoardMapper

  @Update("update bitboard set count = count + 1 where board_idx = #{board_idx}")
    public void plusCount(int board_idx);
    }

BoardMapper.xml

    <update id="updateBoard" parameterType="kr.bit.entity.Board">
        update bitboard
        set board_title = #{board_title},
        board_content = #{board_content}
        where board_idx = #{board_idx} <!-- 보통 PK 또는 조건을 사용합니다. -->
    </update>

제목을 클릭하면 내용이 보이는 goContent

 

home.jsp

// 제목을 클릭하면 내용을 보이게 함
function goContent(idx) {
    if ($("#con" + idx).css("display") == "none") { // 내용폼이 안보이는 상황이면

        $.ajax({
            url: "contentBoard",
                type:"get",
            data:{"idx":idx},
            dataType: "json",
            success: function (data) {
                $("#ta"+idx).val(data.board_content);
            },
            error : function () {
                alert("Error");
            }
        });

        $("#con" + idx).css("display", "table-row"); // 제목을 눌렀을 때 폼이 보임
    } else {
        $("#con" + idx).css("display", "none"); // 제목 누르면 안보이게
    }
}

 

controller

  @RequestMapping("/contentBoard")
    public @ResponseBody Board contentBoard(int idx) {
        Board board = boardMapper.getBoard(idx);
        return board;
    }
}

 

조회수(count)

 

home.jsp

      function goContent(board_idx) {
            if ($("#con" + board_idx).css("display") == "none") { // 내용폼이 안보이는 상황이면

                $.ajax({
                    url: "board/"+board_idx,
                    type: "get",
                    data: {"board_idx":board_idx},
                    dataType: "json",
                    success: function(data){
                        $("#ta"+ board_idx).val(data.board_content);
                    },
                    error: function(){
                        alert("에러")
                    }


                })


                $("#con" + board_idx).css("display", "table-row"); // 제목을 눌렀을 때 폼이 보임
            } else { //내용 폼이 보이면 제목 클릭함 -> 조회수 증가
                $("#con" + board_idx).css("display", "none"); // 제목 누르면 안보이게

                $.ajax({
                    url: "board/count/"+board_idx,
                    type: "put",
                    data: {"board_idx" : board_idx},
                    dataType: "json",
                    success: function(data){
                        console.log(data.board_count);
                        $("#cnt"+board_idx).val(data.board_count);//조회수 폼에 Board객체에 있는(data) 조회수 출력
                    },
                    error : function() {
                        alert("error");
                    }
                });
            }
        }

 

Controller

    @RequestMapping("/boardCount")
    public @ResponseBody Board boardCount(int board_idx){
        boardMapper.plusCount(board_idx);
        Board vo= boardMapper.getBoard(board_idx);
        return vo;
    }
}

본문 내용 Ajax 형식으로 호출하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <!-- jQuery 라이브러리 -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> <!-- Bootstrap 라이브러리 -->
    <script type="text/javascript">
        $(document).ready(function () { // 웹 페이지 로드 완료 후 실행할 함수를 등록합니다.
            loadBoard(); // 게시판을 로드하는 함수를 호출합니다.
        });

        function loadBoard() { // 게시판을 로드하는 함수입니다.
            $.ajax({ // Ajax를 사용하여 서버와 비동기 통신을 합니다.
                url: "board/List", // 데이터를 요청할 서버의 URL입니다.
                type: "GET", // HTTP 요청 방식입니다. 여기서는 GET을 사용합니다.
                dataType: "json", // 서버가 응답할 데이터의 타입입니다. 여기서는 json을 사용합니다.
                success: make, // 요청이 성공했을 때 호출될 함수입니다.
                error: function () { // 요청이 실패했을 때 호출될 함수입니다.
                    alert("error"); // 에러 메시지를 출력합니다.
                }
            });
        }

        function make(data) { // 게시판을 생성하는 함수입니다.
            var li = "<table class='table table-bordered'>"; // 테이블을 생성합니다.
            // 테이블의 헤더를 생성합니다.
            li += "<tr>";
            li += "<td>글번호</td>";
            li += "<td>제목</td>";
            li += "<td>글쓴이</td>";
            li += "<td>작성일</td>";
            li += "<td>조회수</td>";
            li += "</tr>"

            $.each(data, function (index, board) { // 게시글의 각 항목을 순회합니다.
                li += "<tr>";
                li += "<td>" + board.board_idx + "</td>"; // 게시글 번호
                li += "<td id='tit" + board.board_idx + "'><a href='javascript:goContent(" + board.board_idx + ")'>" + board.board_title + "</a></td>"; // 게시글 제목
                li += "<td>" + board.board_writer + "</td>"; // 게시글 작성자
                li += "<td>" + board.board_datetime.split(' ')[0] + "</td>"; // 게시글 작성일
                li += "<td id='cnt" + board.board_idx + "'>" + board.board_count + "</td>"; // 게시글 조회수
                li += "</tr>";
                // 게시글의 내용을 표시하는 부분을 생성합니다.
                li += "<tr id='con" + board.board_idx + "' style='display:none'>";
                li += "<td>내용</td>";
                li += "<td colspan='4'>";
                li += "<textarea id='ta" + board.board_idx + "' readonly rows='7' class='form-control'>" + board.board_content + "</textarea>";
                li += "<br/>";
                li += "<span id='up" + board.board_idx + "'><button class='btn btn-success btn-sm' onclick='goUpdateForm(" + board.board_idx + ")'>수정화면</button></span>&nbsp;";
                li += "<button class='btn btn-danger btn-sm' onclick='goDelete(" + board.board_idx + ")'>삭제</button>";
                li += "</td>";
                li += "</tr>";
            });

            li += "<tr>";
            li += "<td colspan='5'>";
            li += "<button class='btn btn-primary btn-sm' onclick='getForm()'>글작성</button>";
            li += "</td>";
            li += "</tr>";
            li += "</table>";

            $("#view").html(li); // 생성한 테이블을 화면에 적용합니다.
            $("#view").css("display", "block"); // 화면에 테이블을 표시합니다.
            $("#wfrom").css("display", "none"); // 글 작성 폼을 숨깁니다.
        }

        function goUpdateForm(idx) { // 글 수정 폼을 로드하는 함수입니다.
            $("#ta" + idx).attr("readonly", false); // 내용을 수정할 수 있도록 설정합니다.

            let title = $("#tit" + idx + " a").text(); // 제목을 가져옵니다.
            let newInput = "<input type='text' id='nt" + idx + "' class='form-control' value='" + title + "'/>"; // 새로운 입력 필드를 생성합니다.
            $("#tit" + idx).html(newInput); // 생성한 입력 필드를 적용합니다.

            let newButton = "<button class='btn btn-primary btn-sm' onclick='goUpdate(" + idx + ")'>수정</button>"; // 새로운 버튼을 생성합니다.
            $("#up" + idx).html(newButton); // 생성한 버튼을 적용합니다.
        }

        function goUpdate(idx){ // 글을 수정하는 함수입니다.

            let board_title = $("#nt"+idx).val(); // 수정된 제목을 가져옵니다.
            let board_content = $("#ta"+idx).val(); // 수정된 내용을 가져옵니다.
            $.ajax({ // Ajax를 사용하여 서버와 비동기 통신을 합니다.
                url: "board/update", // 데이터를 요청할 서버의 URL입니다.
                //여러개의 값을 json형식으로 컨트롤러에 보냘때 json.stringfy로 변환해서 전달해야함
                //그걸 컨트롤러에서 받을때 @RequestBody를 통해 받음
                type: "Put",
                contentType: 'application/json; charset=utf-8',
                data: JSON.stringify ( { "board_idx": idx, "board_title":board_title, "board_content": board_content }), //수정해서 가지고 갈 값
                success: loadBoard, // 요청이 성공했을 때 호출될 함수입니다.
                error: function(){ // 요청이 실패했을 때 호출될 함수입니다.
                    alert("Error"); // 에러 메시지를 출력합니다.
                }
            })
        }

        function goDelete(idx) { // 글을 삭제하는 함수입니다.
            $.ajax({ // Ajax를 사용하여 서버와 비동기 통신을 합니다.
                url: "board/"+idx, // 데이터를 요청할 서버의 URL입니다.
                type: "get", // HTTP 요청 방식입니다. 여기서는 GET을 사용합니다.
                data: {"board_idx": idx}, // 서버로 전송할 데이터입니다.
                success: loadBoard, // 요청이 성공했을 때 호출될 함수입니다.
                error: function () { // 요청이 실패했을 때 호출될 함수입니다.
                    alert("error"); // 에러 메시지를 출력합니다.
                }
            });
        }

        function goInsert() { // 글을 삽입하는 함수입니다.

            let formData = $("#frm").serialize(); // 폼에 입력한 데이터를 직렬화합니다.

            $.ajax({ // Ajax를 사용하여 서버와 비동기 통신을 합니다.
                url: "board/create", // 데이터를 요청할 서버의 URL입니다.
                type: "POST", // HTTP 요청 방식입니다. 여기서는 POST를 사용합니다.
                data: formData, // 서버로 전송할 데이터입니다.
                success: loadBoard, // 요청이 성공했을 때 호출될 함수입니다.
                error: function () { // 요청이 실패했을 때 호출될 함수입니다.
                    alert("Error"); // 에러 메시지를 출력합니다.
                }
            });
        }

        // 제목을 클릭하면 내용을 보이게 함
        function goContent(board_idx) {
            if ($("#con" + board_idx).css("display") == "none") { // 내용폼이 안보이는 상황이면

                $.ajax({
                    url: "board/"+board_idx,
                    type: "get",
                    data: {"board_idx":board_idx},
                    dataType: "json",
                    success: function(data){
                        $("#ta"+ board_idx).val(data.board_content);
                    },
                    error: function(){
                        alert("에러")
                    }


                })


                $("#con" + board_idx).css("display", "table-row"); // 제목을 눌렀을 때 폼이 보임
            } else { //내용 폼이 보이면 제목 클릭함 -> 조회수 증가
                $("#con" + board_idx).css("display", "none"); // 제목 누르면 안보이게

                $.ajax({
                    url: "board/count/"+board_idx,
                    type: "put",
                    data: {"board_idx" : board_idx},
                    dataType: "json",
                    success: function(data){
                        console.log(data.board_count);
                        $("#cnt"+board_idx).val(data.board_count);//조회수 폼에 Board객체에 있는(data) 조회수 출력
                    },
                    error : function() {
                        alert("error");
                    }
                });
            }
        }

        function getForm() { // 글 작성 폼을 로드하는 함수입니다.
            $("#wfrom").css("display", "block"); // 글 작성 폼을 표시합니다.
            $("#view").css("display", "none"); // 게시판을 숨깁니다.
        }

        function goList() { // 목록을 로드하는 함수입니다.
            $("#view").css("display", "block"); // 게시판을 표시합니다.
            $("#wfrom").css("display", "block"); // 글 작성 폼을 표시합니다.
        }

    </script>
</head>
<body>
<div class="container">
    <div class="panel panel-default">
        <div class="panel-heading">게시판</div>
        <div class="panel-body" id="view">본문</div>
        <div class="panel-body" id="wfrom" style="display: none">
            <form id="frm">
                <table class="table">
                    <tr>
                        <td>제목</td>
                        <td><input type="text" id="title" name="board_title" class="form-control"/></td>
                    </tr>
                    <tr>
                        <td>내용</td>
                        <td><textarea rows="7" class="form-control" id="content" name="board_content"></textarea></td>
                    </tr>
                    <tr>
                        <td>글쓴이</td>
                        <td><input type="text" id="writer" name="board_writer" class="form-control"/></td>
                    </tr>
                    <tr>
                        <td colspan="2" align="center">
                            <button type="button" class="btn btn-success btn-sm" onclick="goInsert()">등록</button>
                            <button type="reset" class="btn btn-warning btn-sm" id="formclear">취소</button>
                            <button type="button" class="btn btn-info btn-sm" onclick="goList()">리스트</button>
                        </td>
                    </tr>
                </table>
            </form>
        </div>
        <div class="panel-footer">비트캠프</div>
    </div>
</div>
</body>
</html>

 

BoardRestTestController

package kr.bit.controller;

import kr.bit.entity.Board;
import kr.bit.mapper.BoardMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RequestMapping("/board")
@RestController
public class BoardRestTestController {
 @Autowired
 private BoardMapper boardMapper;

    @GetMapping("/List")
    public  List<Board> boardList() {
        List<Board>list = boardMapper.getList();    // json 데이터 형식으로 변환해서 리턴
        return list;
    }

    @PostMapping("/create")
    public  void boardInsert(Board vo){
        boardMapper.insertBoard(vo);
    }

    @DeleteMapping("/{board_idx}")
    public @ResponseBody void boardDelete(@PathVariable("board_idx") int board_idx){
        boardMapper.deleteBoard(board_idx);
    }
//post , get, delete(삭제), put(업데이트)
    @PutMapping("/update")
    public void boardUpdate(@RequestBody Board vo){
        boardMapper.updateBoard(vo);
    }

    @GetMapping("/{board_idx}")
    public  Board boardContent(@PathVariable("board_idx") int idx){
        System.out.println("idx:"+idx);
        Board vo= boardMapper.getBoard(idx);
        return vo; //{idx:2, title: w, content:33 ...}
    }

    @PutMapping("/count/{board_idx}")
    public  Board boardCount(@PathVariable("board_idx")int  board_idx){
        boardMapper.plusCount(board_idx);
        Board vo= boardMapper.getBoard(board_idx);
        return vo;
    }
}
728x90
728x90

728x90
728x90

 

게시글 삭제

BoardMapper

@Delete("DELETE FROM content_table WHERE content_board_idx = #{content_board_idx}")
int getCnt(int content_board_idx);
  •   게시글을 삭제하는 쿼리문을 실행하는 메소드로 매개변수로 가져오는 게시글 번호를 기준으로 하여 삭제한다.

BoardDao

public void deleteInfo(int content_idx) {
    boardMapper.deleteInfo(content_idx);
}

BoardService

public void deleteInfo(int content_idx) {
    boardDao.deleteInfo(content_idx);
}

BoardController

    @GetMapping("/delete")
    public String delete(@RequestParam("board_info_idx") int board_Info_Idx,
                        @RequestParam("content_idx") int content_idx,
                                Model model) {

        boardService.deleteInfo(content_idx);

        model.addAttribute("board_info_idx",board_Info_Idx); // n팀 게시글 삭제 후 n팀으로 돌아오기 위해

        return "board/delete";
    }

Board.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="root" value="${pageContext.request.contextPath }/" />
<script>
    alert("Deleted successfully.")
    location.href='${root}board/main?board_info_idx=${board_info_idx}'
</script>

 

 

 


페이지작업

 

Page

package kr.bit.beans;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Page {
    private int min;
    private int max;
    private int prePage;
    private int nextPage;
    private int pageCnt;
    private int currentPage;

    public Page(int contentCnt, int currentPage, int contentPageCnt, int pa) {

        this.currentPage = currentPage;
        pageCnt = contentCnt / contentPageCnt;
        //533/10=53 €
        if (contentCnt % contentPageCnt > 0) {
            pageCnt++;
        }
        min = ((currentPage - 1) / contentPageCnt) * contentPageCnt + 1;
        max = min + pa - 1;

        if (max > pageCnt) {
            max = pageCnt;
        }

        prePage = min - 1;
        nextPage = max + 1;

        if (nextPage > pageCnt) {
            nextPage = pageCnt;
        }
    }
}

 

 

코드 추가

BoardMapper

@Select("select count(*) from content_table where content_board_idx = #{content_board_idx}")
int getCnt(int content_board_idx);

 

BoardDao

public int getCnt(int content_board_idx) {
    return boardMapper.getCnt(content_board_idx);
}

 

BoardService

public Page getCnt(int content_board_idx, int currentPage) {
    
    int content_cnt = boardDao.getCnt(content_board_idx);
    //                전체글 갯수
    Page p = new Page(content_cnt, currentPage, page_listcount, page_pa);
    
    return p;
    
}

 

BoardController

주석 되어있던것 주석 해

@GetMapping("/main")
public String main(@RequestParam("board_info_idx") int board_info_idx,
                   @RequestParam(value = "page", defaultValue = "1") int page,
                   Model model) {
    model.addAttribute("board_info_idx", board_info_idx);

    String boardName = boardService.getBoardName(board_info_idx); // 팀명 추출 메소드
    model.addAttribute("boardName", boardName);

    List<Content> contentLi = boardService.getContent(board_info_idx, page);
    model.addAttribute("contentLi", contentLi); // 게시글 목록

    Page pbean=boardService.getCnt(board_info_idx, page);
    model.addAttribute("pbean", pbean); //
    model.addAttribute("page", page); //

    return "board/main";
}

 

Board/main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath }/"/>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fighting, Our Class</title>
    <!-- Bootstrap CDN -->
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>

<c:import url="/WEB-INF/views/include/top_menu.jsp"/>

<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <h3 class="card-title">${boardName }</h3>
            <table class="table table-hover" id="board_list">
                <thead>
                <tr>
                    <th class="text-center d-none d-md-table-cell">Post Number</th>
                    <th class="w-50">Title</th>
                    <th class="text-center d-none d-md-table-cell">Writer</th>
                    <th class="text-center d-none d-md-table-cell">Date</th>
                </tr>
                </thead>

                <tbody>
                <c:forEach var='obj' items="${contentLi }">
                    <tr>
                        <td class="text-center d-none d-md-table-cell">${obj.content_idx }</td>
                        <td><a href='${root }board/read?board_info_idx=${board_info_idx}&content_idx=${obj.content_idx}&page=${page}'>${obj.content_subject }</a></td>
                        <td class="text-center d-none d-md-table-cell">${obj.content_writer_name }</td>
                        <td class="text-center d-none d-md-table-cell">${obj.content_date }</td>

                    </tr>
                </c:forEach>
                </tbody>
            </table>

            <div class="d-none d-md-block">
                <ul class="pagination justify-content-center">
                    <c:choose>
                        <c:when test="${pBean.prePage <= 0 }">
                            <li class="page-item disabled">
                                <a href="#" class="page-link">Previous</a>
                            </li>
                        </c:when>
                        <c:otherwise>
                            <li class="page-item">
                                <a href="${root }board/main?board_info_idx=${board_info_idx}&page=${pBean.prePage}" class="page-link">Previous</a>
                            </li>
                        </c:otherwise>
                    </c:choose>


                    <c:forEach var='idx' begin="${pBean.min }" end='${pBean.max }'>
                        <c:choose>
                            <c:when test="${idx == pBean.currentPage }">
                                <li class="page-item active">
                                    <a href="${root }board/main?board_info_idx=${board_info_idx}&page=${idx}" class="page-link">${idx }</a>
                                </li>
                            </c:when>
                            <c:otherwise>
                                <li class="page-item">
                                    <a href="${root }board/main?board_info_idx=${board_info_idx}&page=${idx}" class="page-link">${idx }</a>
                                </li>
                            </c:otherwise>
                        </c:choose>
                        //첫번째 페이지에서 이전으로 못가게 막음

                    </c:forEach>

                    <c:choose>
                        <c:when test="${pBean.max >= pBean.pageCnt }">
                            <li class="page-item disabled">
                                <a href="#" class="page-link">Next</a>
                            </li>
                        </c:when>
                        <c:otherwise>
                            <li class="page-item">
                                <a href="${root }board/main?board_info_idx=${board_info_idx}&page=${pBean.nextPage}" class="page-link">Next</a>
                            </li>
                        </c:otherwise>
                    </c:choose>
                    // 마지막 페이지에 도달하면 멈춤

                </ul>
            </div>

            <div class="text-right">
                <a href="${root }board/write?board_info_idx=${board_info_idx}" class="btn btn-primary">Write</a>
            </div>

        </div>
    </div>
</div>

<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>

</body>
</html>

 

728x90
728x90

게시판 시스템에서 특정 콘텐츠의 정보를 조회하고 표시하는 기능

Main.jsp

   <tbody>
         <c:forEach var="obj" items="${contentLi}">
             <tr>
                 <td class="text-center d-none d-md-table-cell">${obj.content_idx}
                 </td>
                 <td><a href="${root }board/read?board_info_idx=${board_info_idx}
&content_idx=${obj.content_idx}&page=${page}">${obj.content_subject}</a>
                 </td>
                 <td class="text-center d-none d-md-table-cell">${obj.content_writer_name }
                 </td>
                 <td class="text-center d-none d-md-table-cell">${obj.content_date}
                 </td>
             </tr>

 

 

BoardController

  @GetMapping("/read")
    public String read(
        @RequestParam("board_info_idx") int board_info_idx,
        @RequestParam("content_idx") int content_idx,
        @RequestParam("page") int page,
        Model model)
        {
            model.addAttribute("board_info_idx", board_info_idx);
            model.addAttribute("content_idx", content_idx);

    return "board/read";
    }

 

BoardMapper

content_tableuser_table을 조인하여 콘텐츠와 작성자에 대한 세부 정보를 가져온다.

 

쿼리문 추가

@Select("SELECT a2.user_name AS content_writer_name, " +
        "DATE_FORMAT(a1.content_date, '%Y-%m-%d') AS content_date, " +
        "a1.content_subject, a1.content_text, a1.content_writer_idx " +
        "FROM content_table a1 JOIN user_table a2 " +
        "ON a1.content_writer_idx = a2.user_idx " +
        "WHERE content_idx = #{content_idx}")
Content getInfo(int content_idx);

 

BoardDao

BoardMappergetInfo 메서드를 호출하여 콘텐츠 세부 정보를 가져옴

public Content getInfo(int content_idx) {
    return boardMapper.getInfo(content_idx);
}

BoardService

BoardDaogetInfo 메서드를 호출하여 콘텐츠 세부 정보를 가져옴

public Content getInfo(int content_idx) {
    return boardDao.getInfo(content_idx);
}

 

BoardController(코드추가)

BoardController에서는 특정 콘텐츠의 상세 페이지 요청을 처리하는 메서드를 가지고 있다.

이 메서드는 content_idx를 기반으로 콘텐츠의 세부 정보를 가져와 모델에 추가한다.

  • 파라미터: 이 메서드는 요청 URL에서 board_info_idx, content_idx, page를 받아온다.
  • 모델 속성: 이 파라미터들과 조회된 콘텐츠(readContent)를 모델에 추가하여 뷰에서 사용할 수 있게 한다.
   @GetMapping("/read")
    public String read(
        @RequestParam("board_info_idx") int board_info_idx,
        @RequestParam("content_idx") int content_idx,
        @RequestParam("page") int page,
        Model model)
        {
            model.addAttribute("board_info_idx", board_info_idx);
            model.addAttribute("content_idx", content_idx);

            Content readContent = boardService.getInfo(content_idx);
            model.addAttribute("readContent",readContent);
            
            model.addAttribute("loginBean", loginBean);
            model.addAttribute("page", page);

        return "board/read";
        }

 

 

Controller에 loginBean 추가해서 주입받게함

 

Read.jsp

에서 표시되는것들을 다 자동으로 주입되게 바꿈

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath }/"/>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fighting, Our Class</title>
    <!-- Bootstrap CDN -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>

<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <div class="form-group">
                <label for="board_writer_name">Writer</label>
                <input type="text" value="${readContent.content_writer_name}" disabled="disabled" class="form-control"
                       id="board_writer_name" name="board_writer_name"/>
            </div>

            <div class="form-group">
                <label for="board_date">Date</label>
                <input type="text" value="${readContent.content_date}" disabled="disabled" class="form-control"
                       id="board_date" name="board_date"/>
            </div>

            <div class="form-group">
                <label for="board_subject">Subject</label>
                <input type="text" value="${readContent.content_subject}" disabled="disabled" class="form-control"
                       id="board_subject" name="board_subject"/>
            </div>

            <div class="form-group">
                <label for="board_content">Content</label>
                <textarea style="resize: none" rows="10" disabled="disabled"
                          class="form-control" id="board_content"
                          name="board_content">${readContent.content_text}</textarea>
            </div>

            <div class="form-group">
                <div class="text-right">
                    <a href="${root }board/main?board_info_idx=${board_info_idx}&{page}=${page}"
                       class="btn btn-primary">List</a>
                    <c:if test="${loginBean.user_idx == readContent.content_writer_idx}">
                        <a href="${root }board/modify?board_info_idx=${board_info_idx}&content_idx=${content_idx}&page=${page}"
                           class="btn btn-info">Modify</a>
                        <a href="${root }board/delete?board_info_idx=${board_info_idx}&content_idx=${content_idx}"
                           class="btn btn-danger">Delete</a>
                    </c:if>
                </div>
            </div>

        </div>
    </div>
</div>
<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

 

write_success

코드추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="root" value="${pageContext.request.contextPath }/"/>

<script>
    alert('Saved Successfully.')
    location.href = "${root}board/read?board_info_idx=${writeBean.content_board_idx}&content_idx=${writeBean.content_idx}&page=1"
</script>





 

WriterInterceptor

(작성자 외 다른이가 수정,삭제 하지 못하도록)

package kr.bit.interceptor;

import kr.bit.beans.Content;
import kr.bit.beans.User;
import kr.bit.service.BoardService;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class WriterInterceptor implements HandlerInterceptor {

    private User loginBean;
    private BoardService boardService;
    //인터셉터는 주입 불가

    //게시글 작성자가 아닌 다른 살마이 수정, 삭제를 하지 못하도록
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String str = request.getParameter("content_idx");
        int content_idx = Integer.parseInt(str);

        Content con = boardService.getInfo(content_idx);

        if (con.getContent_writer_idx() != loginBean.getUser_idx()) {
            String str2 = request.getContextPath();

            response.sendRedirect(str2 + "/board/not_writer");

            return false;
        }
        return true;
    }

}

 

BoardController

매핑작업 추가


    @GetMapping("/not_wirter")
    public String not_wirter() {
        return "not_writer";
    }
}

 

not_writer.jsp 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="root" value="${pageContext.request.contextPath }/" />
<script>
    alert('Invalid access.')
    location.href="${root}main"
</script>

 

ServletAppContext

코드 추가

boardService, loginBean 주입

WriterInterceptor 추가

package kr.bit.config;



import kr.bit.beans.User;
import kr.bit.interceptor.LoginInterceptor;
import kr.bit.interceptor.TopMenuInterceptor;
import kr.bit.interceptor.WriterInterceptor;
import kr.bit.mapper.BoardMapper;
import kr.bit.mapper.TopMenuMapper;
import kr.bit.mapper.UserMapper;
import kr.bit.service.BoardService;
import kr.bit.service.TopMenuService;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.*;

import javax.annotation.Resource;

@Configuration
@EnableWebMvc
@ComponentScan("kr.bit.controller")
@ComponentScan("kr.bit.dao")
@ComponentScan("kr.bit.service")
@PropertySource("/WEB-INF/properties/db.properties")
public class ServletAppContext implements WebMvcConfigurer {

    @Value("${db.classname}")
    private String db_classname;

    @Value("${db.url}")
    private String db_url;

    @Value("${db.username}")
    private String db_username;

    @Value("${db.password}")
    private String db_password;

    @Autowired
    private TopMenuService topMenuService; //@service

    @Resource(name = "loginBean")
    private User loginBean;  // 로그인 여부에 따라 상단메뉴바가 다르게 보이도록 하기위해 주입받음

    @Autowired
    private BoardService boardService;


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        WebMvcConfigurer.super.configureViewResolvers(registry);
        registry.jsp("/WEB-INF/views/", ".jsp");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        WebMvcConfigurer.super.addResourceHandlers(registry);
        registry.addResourceHandler("/**").addResourceLocations("/resources/");
    }

    @Bean
    public BasicDataSource dataSource() {
        BasicDataSource source = new BasicDataSource();
        source.setDriverClassName(db_classname);
        source.setUrl(db_url);
        source.setUsername(db_username);
        source.setPassword(db_password);

        return source;
    }

    @Bean
    public SqlSessionFactory factory(BasicDataSource source) throws Exception {

        SqlSessionFactoryBean fac = new SqlSessionFactoryBean();
        fac.setDataSource(source);
        SqlSessionFactory factory = fac.getObject();
        return factory;
    }

    @Bean
    public MapperFactoryBean<BoardMapper> board_mapper(SqlSessionFactory factory) throws Exception {

        MapperFactoryBean<BoardMapper> fac =
                new MapperFactoryBean<BoardMapper>(BoardMapper.class);

        fac.setSqlSessionFactory(factory);
        return fac;

    }

    @Bean
    public MapperFactoryBean<TopMenuMapper> top_mapper(SqlSessionFactory factory) throws Exception {

        MapperFactoryBean<TopMenuMapper> fac =
                new MapperFactoryBean<TopMenuMapper>(TopMenuMapper.class);

        fac.setSqlSessionFactory(factory);
        return fac;

    }

    @Bean
    public MapperFactoryBean<UserMapper> user_mapper(SqlSessionFactory factory) throws Exception {

        MapperFactoryBean<UserMapper> fac =
                new MapperFactoryBean<UserMapper>(UserMapper.class);

        fac.setSqlSessionFactory(factory);
        return fac;

    }

    //인터셉터 -> 등록
    public void addInterceptors(InterceptorRegistry re) {
        WebMvcConfigurer.super.addInterceptors(re);

        TopMenuInterceptor top = new TopMenuInterceptor(topMenuService, loginBean);

        InterceptorRegistration re1 = re.addInterceptor(top);//TopMenuInterceptor등록
        re1.addPathPatterns("/**"); //모든경로로 매핑해도 다 뜨도록..컨트롤러 전에 preHandle

        LoginInterceptor login = new LoginInterceptor(loginBean);
        InterceptorRegistration re2 = re.addInterceptor(login);  // LoginInterceptor등록

        re2.addPathPatterns("/user/modify", "/user/logout", "/board/*");
        // 이 주소로 들어가기 전에 로그인 여부를 알아내서 로그인이 안되어있다면 user/not_login 으로 강제이동
        re2.excludePathPatterns("/board/main");

        WriterInterceptor writer = new WriterInterceptor(loginBean, boardService);
        InterceptorRegistration re3 = re.addInterceptor(writer);
        re3.addPathPatterns("/board/modify", "/board/delete");
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public ReloadableResourceBundleMessageSource messageSource() {
        ReloadableResourceBundleMessageSource res =
                new ReloadableResourceBundleMessageSource();

        res.setBasename("/WEB-INF/properties/error");
        return res;
    }
}

 


게시글 수정

modify.jsp

form으로 변환

modifyBean 코드 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="root" value="${pageContext.request.contextPath }/"/>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fighting, Our Class</title>
    <!-- Bootstrap CDN -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>

<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <form:form action="${root }board/modify_pro" method="post" modelAttribute="modifyBean">
                <form:hidden path="content_idx"/>
                <form:hidden path="content_board_idx"/>
                <input type="hidden" name="page" value="${page}">
                <div class="form-group">
                    <form:label path="content_writer_name">Writer</form:label>
                    <form:input readonly="true" class="form-control" path="content_writer_name"/>
                </div>

                <div class="form-group">
                    <form:label path="board_date">Date</form:label>
                    <form:input class="form-control" path="content_date" readonly="true"/>
                </div>

                <div class="form-group">
                    <form:label path="content_subject">Subject</form:label>
                    <form:input class="form-control" path="content_subject"/>
                    <form:errors path="content_subject" style='color:red'/>
                </div>

                <div class="form-group">
                    <form:label path="content_text">Content</form:label>
                    <form:textarea class="form-control" path="content_text"
                                   rows="10" style="resize:none"></form:textarea>
                    <form:errors path="content_text" style='color:red'/>
                </div>

                <div class="form-group">
                    <div class="text-right">
                        <button type="submit" class="btn btn-primary">Complete Modification</button>
                        <a href="${root }board/read?board_info_idx=${board_info_idx}&content_idx=${content_idx}&page=${page}" class="btn btn-info">Cancel</a>
                    </div>
                </div>
            </form:form>
        </div>
    </div>
</div>
<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

 

BoardController

modify 매핑

@GetMapping("/modify")

//매핑 및 요청 파라미터:
public String modify(@RequestParam("board_info_idx") int board_info_idx,
                     @RequestParam("content_idx") int content_idx,
                     @RequestParam("page") int page,
                     @ModelAttribute("modifyBean") Content modifyBean,
                     Model model) {

    //모델에 데이터 추가:
    model.addAttribute("board_info_idx", board_info_idx);
    model.addAttribute("content_idx", content_idx);
    model.addAttribute("page", page);

    //수정할 글정보 ( 작성자, 제목 etc..) 를 가져와서 업데이트 시킨 후 출력함
    Content temp = boardService.getInfo(content_idx);

    //폼 데이터 설정:
    modifyBean.setContent_writer_name(temp.getContent_writer_name());
    modifyBean.setContent_date(temp.getContent_date());
    modifyBean.setContent_subject(temp.getContent_subject());
    modifyBean.setContent_text(temp.getContent_text());
    modifyBean.setContent_writer_idx(temp.getContent_writer_idx());
    modifyBean.setContent_board_idx(board_info_idx);
    modifyBean.setContent_idx(content_idx);

    //뷰 반환:
    return "board/modify";
}

매핑 및 요청 파라미터:

  • @GetMapping("/modify"): /modify URL로 GET 요청이 들어오면 이 메서드가 실행됨
  • @RequestParam: URL에서 board_info_idx, content_idx, page 파라미터를 받아옴
  • @ModelAttribute("modifyBean"): modifyBean이라는 이름으로 모델에 바인딩된 폼 데이터를 사용

 

modify_pro 추가

    @PostMapping("/modify_pro")
    public String modify_pro(@Valid @ModelAttribute("modifyBean") Content modifyBean,
                             BindingResult result,
                             @RequestParam("page") int page, Model model) {

        model.addAttribute("page", page);

        if(result.hasErrors()) {
            return "board/modify";
        }
//        boardService.modifyInfo(modifyBean);
        return "board/modify_success";
    }

BoardMapper

 

쿼리문 추가

-      게시물의 수정이 있을 때 게시물 테이블을 업데이트하는 쿼리문을 실행하는 메소드(제목, 내용, 게시물 번호)

-      ModifyContentBean을 매개변수로 한다.

    @Update("UPDATE content_table " + "SET content_subject = #{content_subject}, "
            + "content_text = #{content_text} " + "WHERE content_idx = #{content_idx}")
    void modifyInfo(Content modifyContentBean);

}

 

BoardDao

public void modifyInfo(Content modifyBean) {
    boardMapper.modifyInfo(modifyBean);
}

BoardService

   public void modifyInfo(Content modifyBean) {
        boardDao.modifyInfo(modifyBean);
    }

 

modify_success

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="root" value="${pageContext.request.contextPath }/"/>
<script>
    alert("Your Post has been updated")
    location.href = "${root}board/read?board_info_idx=${modifyBean.content_board_idx}&content_idx=${modifyBean.content_idx}&page=${page}"
</script>



728x90

+ Recent posts