ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 44일차 - 관리자, 아이디 중복체크, 이미지 표시
    백엔드(웹 서버, WAS)/Spring 2024. 3. 26. 17:21

     

    <tr>
        <th>관리자 여부</th>
        <td><input type="checkbox" name="auth"/></td>
    </tr>

    회원가입을 저장하는 방식에 대해 고민해보자

    auth 라는 컬럼을 member 테이블에 정보를 저장한다

    - 장점 : 관리가 편리하다, - 단점 : 테이블을 수정해야한다

     

    관리자 테이블을 따로 만들어서 관리한다

    - 장점 : 기존 구조를 수정하지 않아도 된다 - 단점 : 테이블을 조인시켜서 가져와야함

    create table author (
    	id varchar(50)
    	,perm varchar(20)
    	,constraint foreign key(id) references member(id) on delete cascade
    );

    아이디와 비밀번호를 만족하고 퍼미션의 권한이 있는 유저인지 확인한다

    	@RequestMapping(value="/login.do", method=RequestMethod.POST)
    	public String login(String id, String pw
    			,HttpSession session) {
    		logger.info("/login.do, 로그인 처리 요청");
    		String page = "redirect:/";
    		MemberDTO info = service.login(id,pw);
    		if(info.getId() != null) {
    			session.setAttribute("loginInfo", info);
    			page = "redirect:/boardList.do";
    		}
    		return page;
    	}

     

    	<select id="login" resultType="kr.co.photo.member.dto.MemberDTO">
    		SELECT
    				m.id
    				,m.pw
    				,m.name
    				,a.perm
    				,m.age
    				,m.gender
    				,m.email 
    		FROM member m LEFT OUTER JOIN author a ON a.id = m.id
    			WHERE m.id=#{param1} AND pw=#{param2}
    	</select>

    흔히 실수하는 부분

    두개의 테이블에서 동일한 이름을 가진 컬럼이 있을 수 있어서 꼭 어떤 테이블의 컬럼인지 지정해줘야한다

    하지만 세개 이상의 테이블에서는 오류를 찾기 어렵다


    회원가입시 중복 체크 

    joinForm

    <style>
    	input[name="id"] {
    		width:70%;
    	}
    </style>
    <input type="button" value="중복체크"/>

     

    	function checkDuplicate() {
    		var id = $("input[name='id']").val();
    		window.location.href="checkDuplicateID.do?id=" + id;	
    	}

    form 으로 서버에 전송할 수 없으므로 반드시 아이디의 데이터를 가져오려면 JS 로 통해서 태그의 값을 가져오고 GET 방식으로 id 파라미터에 담아서 서버에 요청을 보낸다

    Controller

    	@RequestMapping(value="/checkDuplicateID.do")
    	public String checkDuplicateID(String id, HttpSession session, Model model) {
    		String page = "joinForm";
    		logger.info("{}", id);
    		if (id.equals("")) {
    			model.addAttribute("msg", "아이디를 입력해주세요");
    		} else if(service.checkDuplicateID(id)) {
    			model.addAttribute("msg", "사용 가능한 아이디입니다");
    		} else {
    			model.addAttribute("msg", "이미 사용중인 아이디가 있습니다");
    		}
    		return page;
    	}

    Service

    	public boolean checkDuplicateID(String id) {
    		return dao.checkDuplicateID(id) > 0;
    	}

    DAO

    Member_Mapper.xml

    	<select id="checkDuplicateID" resultType="int">
    		SELECT count(id) FROM member WHERE id=#{param1}
    	</select>

    사용자에게 전달받은 파라미터를 중복체크하고 중복이라면 Model 을 통해서 사용자에게 알려준다

     


    동기 vs 비동기 방식

    동기 방식

    회원가입 양식을 모두 작성한 후 서버에게 요청하게 되면, 서버에서는 요청을 받고! 회원가입 페이지를 사용자에게 보여주었다 

     

    서버가 요청을 처리한 후 결과 페이지를 사용자는 계~속 기다려야한다(동기 방식)

    비동기 방식 AJAX(Asynchronous JavaScript And Xml)

    기존 페이지는 그대로 두고 폼안에 무언가를 입력받고서 특정한 요소를 바꾸고 싶을때 사용한다

    Map 형태로 다시 돌려주고, 자바스크립트JSON 과 유사한 형태가 Map 이기 때문이다

    요청을 받아서 전달하고 다 되면  나에게 날려주는 누군가가 중간에 존재한다

    콜센터에 예약하면 전화해주는 서비스, (콜센터 상담자)

    게임 매칭 중 다른 일을 하고 있다가 잡힘, (매칭 시스템)

    비동기로 통신하는 JavaScriptObjectN ??? 와 xml 이라는 뜻이다

    요청해놓고 다른 일을 자유롭게 할 수 있다

    결과 페이지를 보여주는 것이 아니라 페이지의 일부분만 수정한다

     

    그래서 AJAX 에서는 그 역할을 XML OBJECT 머시기가 중재한다

     

    보석처럼 AJAX 를 써야한다

    1. 보안성이 굉장히 취약하다

     


    AJAX 를 이용한 아이디 중복체크 기능

    현재 jdk 버젼에 따라서 라이브러리 버젼을 지정해줘야한다

    json 과 비슷한 java 객체를 javascript 에서 인식할 수 있도록 도와줄 라이브러리

    <!-- jackson-databind : Map 등을 json 형태로, 문자열을 json 혀앹로 변경해주는 라이브러리 -->
    <!-- https://central.sonatype.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.14.2</version>
    </dependency>

     

    AJAX 로 서버에게 요청을 보낼때 

    ■ Response 객체를 활용한다(페이지 이동만 되거나 객체에 프린트만 하거나)
    ■ AJAX 는 요청 보내는 페이지와 받는 페이지가 동일해야 한다(페이지 이동 안됨)
    ■ 반환 할때 JSON 형태로 반환해야 한다({키:값}) 

    ■ 여기서 java 객체는 Map 형태에 키와 값을 클래스 형태로 키와 값을 저장한다

    function checkDuplicateID() {
        var id = $("input[name='id']").val();
        // AJAX 를 이용한 비동기 통신
        // JS 에서는 Object 는 문자열 key-value 사용할 수 있고
        // 배열은 인덱스로 접근할 수 있다
        // 순서는 상관없지만 어디로 보내 어떤 파라미터를 보내 성공시 어떻게? 실패시 어떻게?
        $.ajax({
            type:'post' // method 방식
            ,url:'checkDuplicateID.do' // 요청할 주소
            ,data:{'id':id} // 파라미터 
            ,success:function(data){ // 성공했을 경우
                // AJAX 에서 XmlHttpRequest 객체를 통해 대신 받아와서
                // 여기에 뿌려준다
                console.log(data);
                if (data.use > 0) {
                    alert("이미 사용중인 아이디입니다");
                    $("input[name='id']").val('');
                } else {
                    alert("사용 가능한 아이디입니다");
                }
    
            } 
            ,error:function(error){ // 통신 실패한 경우
                console.log(error);
            }
        });
    // ajax 통신 규칙
    	// 1. Response 객체를 활용한다(페이지 이동만 되거나 객체에 프린트만 하거나)
    	// 2. AJAX 는 요청 보내는 페이지와 받는 페이지가 동일해야 한다(페이지 이동 안됨)
    	// 3. 반환 할때 JSON 형태로 반환해야 한다({키:값}) 
    	// 4. json 과 비슷한 java 객체를 javascript 에서 인식할 수 있도록 도와줄 라이브러리
    	// 4-1. 여기서 java 객체는 Map 형태에 키와 값을 클래스 형태로 키와 값을 저장한다
    	@RequestMapping(value="/checkDuplicateID.do")
    	@ResponseBody // response 객체에 반환하는 값을 담는 역할
    	public Map<String, Object> checkDuplicateID(String id, HttpSession session, Model model) {
    		logger.info("회원의 아이디 : {}", id);
    		Map<String,Object> map = new HashMap<String,Object>();
    		map.put("use", service.checkDuplicateID(id));
    		// response 객체는 페이지 위에 그리는 역할이기 때문이다
    		// 반환되는 값 객체 기존 페이지 위에 덮어 씌워버린다
    		return map;
    	}

    중복인 아이디로 회원가입을 하려고 하면 '이미 사용중인 아이디입니다' 라고 문구창이 뜬다

    반대의 경우에는 사용 가능하다고 알려준다


    게시글에 파일 있으면 이미지 아이콘 표시하기

    list.jsp

    첨부된 파일의 갯수가 1개 이상이면 image.png 를 표시하고 반대인 경우 no_image.png 를 보여준다

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    <link rel="stylesheet" href="resources/css/common.css" type="text/css">
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <style>
    </style>
    </head>
    <body>
    	게시판 리스트
    	<hr/>
    	<button>선택 삭제</button>
    	<table>
    		<tr>
    			<th><input type="checkbox" id="all"/></th>
    			<th>글번호</th>
    			<th>이미지</th>
    			<th>제목</th>
    			<th>작성자</th>
    			<th>조회수</th>
    			<th>날짜</th>
    		</tr>
    		<c:forEach items="${list}" var="item">
    			<tr>
    				<td><input type="checkbox" name="del" value="${item.idx}"/></td>
    				<td>${item.idx}</td>
    				<td>
    					<c:if test="${item.img_cnt>0}"><img class="icon" src="resources/img/image.png"/></c:if>
    					<c:if test="${item.img_cnt==0}"><img class="icon" src="resources/img/no_image.png"/></c:if>
    				</td>
    				<td>${item.subject}</td>
    				<td>${item.user_name}</td>
    				<td>${item.bHit}</td>
    				<td>${item.reg_date}</td>
    			</tr>
    		</c:forEach>
    	</table>
    </body>
    <script>
    </script>
    </html>

    board_mapper.xml

    게시글에 첨부된 파일의 갯수를 photo 테이블에서 서브쿼리로 통해 가져오고 그 값을 BoardDTO 에 담는다

    	<select id="list" resultType="kr.ajax.board.dto.BoardDTO">
    	SELECT 
    		(select count(new_filename) from photo p where p.idx= b.idx) as img_cnt,
    		b.idx, 
    		b.subject, 
    		b.user_name, 
    		b.bHit, 
    		b.reg_date 
    	FROM bbs b ORDER BY idx DESC	
    	</select>

    아이콘으로 사용할 이미지 파일

     

     

Designed by Tistory.