본문 바로가기

JSP

JSP_6강(MVC 예제)

  Model - DataDto

Lombok 어노테이션 선언 후 DB table 안에 저장한 컬럼명과 똑같이 변수를 작성해준다.

@Data // Lombok 어노테이션(Getter/Setter)
public class DataDto {
    private int m_code;
    private String m_str;
    private int m_int;
    private String m_date;
}

  View - jsp

- home.xml

각 페이지로 이동할 수 있는 메인페이지

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"
            integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 관리자</h1>
<p>
    <a href="inputFrm">[데이터 입력]</a>
    <a href="dataList">[데이터 목록]</a>
</p>
<hr>
<p>${nowtime}</p>
</body>
<script>
    let m = "${msg}";
    if (m != "") {
        alert(m);
    }
</script>
</html>

 

- inputFrm.jsp

정보를 입력하는 페이지

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>입력 양식</title>
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"
            integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 입력</h1>
<fieldset>
  <legend>다음 데이터를 입력하세요.</legend>
      <form action="inputProc">
            <p>문자열 : <input type="text" name="m_str"></p>
            <p>정수 : <input type="text" name="m_int"></p>
            <p>날짜 : <input type="date" name="m_date"></p>
            <input type="submit" value="전송">
      </form>
</fieldset>
</body>
</html>

 

- dataList.jsp

입력한 정보 리스트를 한번에 볼 수 있는 페이지

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>데이터 목록</title>
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"
            integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 목록</h1>
<table border="1">
    <tr>
        <th width="50">코드</th>
        <th width="100">문자열</th>
        <th width="80">정수</th>
        <th width="100">날짜</th>
    </tr>
    <c:forEach var="d" items="${dList}">
        <tr>
            <!-- 링크와 전달할 파라미터를 구분하기 위해 ?를 사용 -->
            <td><a href="detail?code=${d.m_code}">${d.m_code}</a></td>
            <td>${d.m_str}</td>
            <td>${d.m_int}</td>
            <td>${d.m_date}</td>
        </tr>
    </c:forEach>
</table>
</body>
<script>
    let m = "${msg}";
    if (m != "") {
        alert(m);
    }
</script>
</html>

 

- detail.jsp

dataList 페이지에서 각 code를 눌렀을 때 해당 정보만 나타나는 페이지

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>상세보기</title>
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"
            integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 상세보기</h1>
<table border="1">
    <tr>
        <th width="50">CODE</th>
        <td width="150">${data.m_code}</td>
    </tr>
    <tr>
        <th width="50">STR</th>
        <td width="150">${data.m_str}</td>
    </tr>
    <tr>
        <th width="50">INT</th>
        <td width="150">${data.m_int}</td>
    </tr>
    <tr>
        <th width="50">DATE</th>
        <td width="150">${data.m_date}</td>
    </tr>
    <tr>
        <td colspan="2">
            <button id="ubtn">수정</button>
            <button id="dbtn">삭제</button>
        </td>
    </tr>
</table>
</body>
<script>
    const ub = document.getElementsByTagName("button");

    ub[0].addEventListener("click", function () {
        location.href = "updateFrm?code=${data.m_code}";
    });

    ub[1].addEventListener("click", function () {
        let q = confirm("삭제합니까?");

        if (q == true) {
            location.href = "deleteProc?code=${data.m_code}";
        }
    });

    let m = "${msg}";
    if (m != "") {
        alert(m);
    }
</script>
</html>

 

- updateFrm.jsp

코드를 제외한 모든 정보를 수정할 수 있는 페이지

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>수정 양식</title>
    <script src="https://code.jquery.com/jquery-3.6.1.min.js"
            integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
</head>
<body>
<h1>데이터 수정</h1>
<fieldset>
    <legend>다음 데이터를 입력하세요.</legend>
    <form action="updateProc">
        <p>코드 : <input type="text" name="m_code"
                       value="${data.m_code}" readonly></p>
        <p>문자열 : <input type="text" name="m_str"
                        value="${data.m_str}"></p>
        <p>정수 : <input type="text" name="m_int"
                       value="${data.m_int}"></p>
        <p>날짜 : <input type="date" name="m_date"
                       value="${data.m_date}"></p>
        <input type="submit" value="전송">
    </form>
</fieldset>
</body>
</html>

  Controller - DataDao

- DataDto.java

Dao 파일은 클래스가 아닌 인터페이스로 만들어준다.

@Mapper
public interface DataDao {
    void insertData(DataDto data);
    List<DataDto> selectList();

    // 하나의 정보를 가져오는 메소드
    DataDto selectData(int code);

    // 데이터 수정용 메소드
    void updateData(DataDto data);

    // 데이터 삭제용 메소드
    void deleteData(int code);
}

 

- resources/mappers/DataDao.xml

인터페이스로 만들어진 Dao의 DB 연결 내용은 Mybatis를 이용하여 이런 식으로 따로 코드를 짜게 된다.

<?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="com.jsframe.spr_jdbc02.dao.DataDao">
    <insert id="insertData" parameterType="DataDto">
        INSERT INTO datatbl
        VALUES (null, #{m_str}, #{m_int}, #{m_date})
    </insert>
    <update id="updateData" parameterType="DataDto">
        UPDATE datatbl
        SET m_str=#{m_str}, m_int=#{m_int}, m_date=#{m_date}
        WHERE m_code=#{m_code}
    </update>
    <delete id="deleteData" parameterType="Integer">
        DELETE FROM datatbl WHERE m_code=#{code}
    </delete>
    <select id="selectList" resultType="DataDto">
        SELECT * FROM  datatbl
    </select>
    <select id="selectData" resultType="DataDto" parameterType="Integer">
        SELECT * FROM datatbl WHERE m_code = #{code}
    </select>
</mapper>

  Controller - DataService

메소드별로 msg와 view 변수에 대해 값을 할당해주고, session과 rttr에 대한 매개변수도 처리해준다.

@Service
@Log
public class MemberService {
    @Autowired
    private MemberDao mDao;

    // 비밀번호 암호화 및 확인 객체
    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    // 회원가입 처리 메소드
    public String regMember(MemberDto member, RedirectAttributes rttr) {
        log.info("regMember()");
        String msg = null;
        String view = null;

        // 비밀번호 암호화 처리
        String cPwd = encoder.encode(member.getM_pwd());
        log.info("암호화된 비밀번호 : " + cPwd);
        log.info("비밀번호 길이 : " + cPwd.length());
        member.setM_pwd(cPwd); // 암호화된 비밀번호로 변경

        try {
            mDao.insertMember(member);
            msg = "가입 성공";
            view = "redirect:/";
        } catch (Exception e) {
            // e.printStackTrace();
            msg = "가입 실패";
            view = "redirect:register";
        }
        rttr.addFlashAttribute("msg", msg);
        return view;
    }

    // 로그인 처리 메소드
    public String loginProc(MemberDto member, HttpSession session,
                            RedirectAttributes rttr) {
        log.info("loginProc()");
        String msg = null;
        String view = null;

        String cPwd = mDao.selectPwd(member.getM_id());

        if(cPwd != null) { // 입력한 회원의 아이디가 있음
            if(encoder.matches(member.getM_pwd(), cPwd)) {
                member = mDao.selectMember(member.getM_id());
                // 세션에 로그인 성공 정보 저장
                session.setAttribute("mem", member);

                msg = "로그인 성공";
                view = "redirect:main";
            } else { // 비밀번호가 맞지 않는 경우
                msg = "비밀번호가 맞지 않습니다.";
                view = "redirect:/";
            }
        } else { // 잘못된 아이디 입력
            msg = "해당 아이디가 없습니다.";
            view = "redirect:/";
        }
        rttr.addFlashAttribute("msg", msg);
        return view;
    }

    public String updateMember(MemberDto member, HttpSession session,
                               RedirectAttributes rttr) {
        // 회원 정보를 수정하고, 세션에 로그인 정보 변경
        log.info("updateMember()");
        String msg = null;
        String view = null;

        try {
            mDao.updateMember(member);
            // session.setAttribute를 해줄 때
            // 기존 저장된 정보가 있다면 덮어쓰고, 없으면 새로 넣어줌
            session.setAttribute("mem",
                    mDao.selectMember(member.getM_id()));
            msg = "수정 성공";
            view = "redirect:main";
        } catch (Exception e) {
            // e.printStackTrace();
            msg = "수정 실패";
            view = "redirect:main";
        }
        rttr.addFlashAttribute("msg", msg);
        return view;
    }

    // 회원 삭제용 메소드 => 회원탈퇴와 로그아웃이 동시에 이뤄져야 함
    public String resignMember(HttpSession session, RedirectAttributes rttr) {
        log.info("resignMember()");
        String msg = null;
        String view = null;

        // 세션에 저장된 로그인 정보로부터 사용자의 id를 가져옴
        // 세션은 어느 것이든 다 받아내기 때문에 정확한 지정이 필요 => 앞에 명시해줌
        MemberDto member = (MemberDto) session.getAttribute("mem");
        String mid = member.getM_id();

        try {
            mDao.deleteMember(mid);
            // 삭제 성공 후 로그아웃 처리
            session.invalidate();

            msg = "탈퇴 성공";
            view = "redirect:/";
        } catch (Exception e) {
            // e.printStackTrace();
            msg = "탈퇴 실패";
            view = "redirect:main";
        }
        rttr.addFlashAttribute("msg", msg);
        return view;
    }
}

  Controller - DataController

각 화면에 대해 MemberService 클래스의 메소드를 지정함으로써 동작을 할 수 있게 해준다.

@Controller
@Log
public class MemberController {
    // Service 자동 처리
    @Autowired
    private MemberService mServ;

    // url 매핑된 메소드
    @GetMapping("/")
    public String home() {
        log.info("home()");
        return "home";
    }

    @GetMapping("register")
    public String register() {
        log.info("register");
        return "register";
    }

    @PostMapping("regProc")
    public String regProc(MemberDto member, RedirectAttributes rttr) {
        log.info("regProc()");
        String view = mServ.regMember(member, rttr);
        return view;
    }

    @PostMapping("loginProc")
    public String loginProc(MemberDto member, HttpSession session,
                            RedirectAttributes rttr) {
        log.info("loginProc()");
        String view = mServ.loginProc(member, session, rttr);
        return view;
    }

    @GetMapping("main")
    public ModelAndView main() {
        log.info("main()");
        ModelAndView mv = new ModelAndView();
        // 여기에 데이터를 담아줌
        mv.setViewName("main");
        return mv;
    }

    @GetMapping("logoutProc")
    public String logoutProc(HttpSession session) {
        log.info("logoutProc");
        // session.removeAttribute("mem");
        session.invalidate();
        // 세션 제거 후 첫 페이지로
        return "redirect:/";
    }

    @PostMapping("updateProc")
    public String updateProc(MemberDto member, HttpSession session,
                             RedirectAttributes rttr) {
        log.info("updateProc()");
        String view = mServ.updateMember(member, session, rttr);
        return view;
    }

    @GetMapping("resignProc")
    public String resignProc(HttpSession session, RedirectAttributes rttr) {
        log.info("resignProc()");
        String view = mServ.resignMember(session, rttr);
        return view;
    }
}

 

 

'JSP' 카테고리의 다른 글

JSP_5강(MVC)  (0) 2022.11.01
JSP_4강  (0) 2022.10.23
JSP_3강  (0) 2022.10.22
JSP_2강  (0) 2022.10.19
JSP_1강  (0) 2022.10.18