본문 바로가기
카테고리 없음

spring 26강-2 Spring Boot와 MongoDB 연동 실습- 회원관리 예제(회원가입, 로그인, 로그아웃)

by avvin 2019. 7. 11.

spring 26강-2 Spring Boot와 MongoDB 연동 실습- 회원관리 예제(회원가입, 로그인, 로그아웃)


실습예제(기본 설정)


Spring Starter Project





pom.xml dependencies 설정


1
2
3
4
5
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-devtools</artifactId>
     <optional>true</optional>
 </dependency>



devtools

클래스 소스코드가 바뀌면 서버를 재시작해야하는데

개발 단계에서는 이 라이브러리를 추가하여 코드가 바뀔 시 자동으로 재시작하게 해준다.


pom.xml [ <dependencies> ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<dependencies>
        <!-- spring boot auto restart
        (설정, 클래스가 바뀌면 auto restart) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- MYSQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- Mogno DB -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- JSP / JSTL -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
    </dependencies>



이번 실습에서는 Thymeleaf 말고 jsp사용




Spring04MongodbApplication.java : 시작 클래스

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.spring04;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class Spring04MongodbApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(Spring04MongodbApplication.class, args);
    }
}
 




application.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server.port = 80
 
## View Path Config ##
# jsp 쓰기위해 필요 (view resolver)
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
 
#jsp auto restart
server.servlet.jsp.init-parameters.development=true
spring.devtools.livereload.enabled=true
 
# static resource
spring.mvc.static-path-pattern=/resources/** // "res/**"로 써있던데 뭘까
 
## MongoDB Config ##
spring.data.mongodb.uri=mongodb://localhost:27017
#일반 사용자 계정
spring.data.mongodb.database=web 
spring.data.mongodb.username=web
spring.data.mongodb.password=1234
 
#Mysql 사용 안하지만 mysql 설정을 빠뜨리면 에러가 남 //왜인진 모름 ㅠ
## Mysql Config ##
spring.datasource.username=root
spring.datasource.password=1234
spring.datasource.url=jdbc:mysql://localhost:3306/web?useSSL=false





타임리프 사용에 체크하고 프로젝트를 생성하면 
resources 폴더 하위에 static 폴더와 template 폴더가 자동생성되지만 
이번 실습 프로젝트에서는 체크하지 않았으므로 src/main/resources에 static 폴더를 직접 만들어준다.


src/main.java - com.example.spring04.config / MongoConfig.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.example.spring04.config;
 
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
 
//root-context에 들어가던 태그의 코드화
@Configuration
public class MongoConfig extends AbstractMongoConfiguration {
    //@Value : application.properties에 정의된 변수의 값을 읽어와서
    //아래 변수의 값으로 주는 어노테이션
    @Value("${spring.data.mongodb.username}")
    private String userName;
    @Value("${spring.data.mongodb.password}")
    private String password;
    @Value("${spring.data.mongodb.database}")
    private String database;
 
    @Override //extends AbstractMongoConfiguration
    protected String getDatabaseName() {
        return database;
    }
 
    //Legacy 프로젝트 설정파일의 <bean> 태그와 같은 역할을 하는 어노테이션
    public @Bean MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate((MongoClient) mongoClient(), 
                database);
    }
 
    @Override //extends AbstractMongoConfiguration
    public MongoClient mongoClient() {
        MongoCredential credential = //인증정보, 비밀번호는 문자배열로
                MongoCredential.createCredential(
                        userName, database, password.toCharArray());
        return new MongoClient(new ServerAddress( //실행에 지장없음
                //서버주소에 호스트, port num, credential
                "localhost"27017), Arrays.asList(credential));
    }
}
 





controller.HomeController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.spring04.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
@Controller //컨트롤러 빈으로 등록
public class HomeController {
    // http://localhost
    @RequestMapping("/")
    public String home() {
        // /WEB-INF/view/home.jsp
        return "home";  // home.jsp로 포워딩
    }
}



> JSP사용을 위한 세팅 필요

jsp를 view로 사용하는 방법


1. src/main 하위에 디렉토리 추가

  : src/main/webapp/WEB-INF/view 로 Spring Legacy 프로젝트처럼 view 디렉토리 생성


2. application.propertoes 설정


3. pom.xml에서 thymeleaf 라이브러리 주석처리 //두가지를 같이 쓸 순 없음



src/main/webapp/WEB-INF/views 디렉토리 추가 - home.jsp

home.jsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file="include/header.jsp" %>//같은 단위에 위치하므로 '../'는 빼야한다
</head>
<body>
<%@ include file="include/menu.jsp" %>
<h1>Welcome!</h1>
<c:if test="${sessionScope.userid != null}">
    <h2>${sessionScope.name}(${sessionScope.userid})님의
        방문을 환영합니다.
    </h2>
</c:if>
</body>
</html>



application.properties 설정
1
2
3
4
## View Path Config ##
# jsp 쓰기위해 필요 (view resolver)
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp



pom.xml에서 thymeleaf 라이브러리 주석처리// 이번 프로젝트에서는 추가 안함


view/include/header.jsp

1
2
3
4
5
6
7
8
9
10
<%@ 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="fmt"
uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn"
uri="http://java.sun.com/jsp/jstl/functions" %>
<script src="http://code.jquery.com/jquery-3.2.1.js"></script>
<link rel="stylesheet" href="/res/css/style.css">



스프링에서 jsp를 제외한 나머지 동적인 리소스는 서블릿으로 인식함


appliacation.properties

1
2
# static resource
spring.mvc.static-path-pattern=/resources/**



style.css

1
2
3
4
5
6
7
@CHARSET "UTF-8";
a:link { text-decoration: none; color: blue; }
a:hover { text-decoration: underline; 
color: red; }
a:visited { text-decoration: none; }
a:active { text-decoration: none; 
color: yellow; }
cs


하이퍼링크에 대한 style.css


include/menu.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" 
uri="http://java.sun.com/jsp/jstl/core" %>
 
<a href="${path}/">Home</a> | 
<a href="${path}/memo.do">메모장</a> | 
<a href="${path}/guestbook.do">방명록</a> | 
<div style="text-align:right;">
<c:choose>
    <c:when test="${sessionScope.userid == null }">
        <a href="${path}/member/login.do">로그인</a>
    </c:when>
    <c:otherwise>
        ${sessionScope.name}님이 로그인중입니다.
        <a href="${path}/member/logout.do">로그아웃</a>
    </c:otherwise>
</c:choose>    
</div>  
<hr>




model.member.dto.MemberDTO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.spring04.model.member.dto;
 
public class MemberDTO {
    private String _id;//mongodb의 Document(레코드에 해당)식별자
    private String passwd;
    private String name;
    private String email;
    private String hp;
    private String zipcode;
    private String address1;
    private String address2;
 
    public MemberDTO() {
    }
 
    ...getter,setter,toString() 생략...
    
}
 



MemberDAO.java ( Interface )

1
2
3
4
5
6
7
8
9
package com.example.spring04.model.member.dao;
 
import com.example.spring04.model.member.dto.MemberDTO;
 
public interface MemberDAO {
    MemberDTO loginCheck(String userid, String passwd);
    void join(MemberDTO dto);
}
 




MemberDAOImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.example.spring04.model.member.dao;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
 
import com.example.spring04.model.member.dto.MemberDTO;
 
@Repository
public class MemberDAOImpl implements MemberDAO {
 
    //mongodb에 접속하여 명령어를 실행하는 객체
    @Autowired
    private MongoTemplate mongoTemplate;
    //mongodb의 컬렉션(테이블에 해당)
    String COLLECTION_NAME="member"; //테이블 이름
    
//로그인 체크    
    @Override
    public MemberDTO loginCheck(String userid, String passwd) {
     
   // _id : Document(레코드에 해당)의 식별자
        Query query=new Query(new Criteria("_id").is(userid).and("passwd").is(passwd));
//mongoTemplate.find(쿼리, 리턴자료형, 컬렉션이름)
//리스트가 리턴되므로 get(0) 첫번째 Document만 리턴        
        List<MemberDTO> list=mongoTemplate.find(query, MemberDTO.class,COLLECTION_NAME);

        if(list.size() > 0) {
            return list.get(0);
        }else {
            return null;
        }
    }
//회원가입 처리
    @Override
    public void join(MemberDTO dto) {
        //Document가 생성됨(insert)
        mongoTemplate.insert(dto, COLLECTION_NAME);
    }
 
}
 

 


*어노테이션 정리


@RestController : json을 리턴할 경우 사용하는 컨트롤러 (@Controller + @ResponseBody)


@RequestBody : json형식의 입력변수. 메서드에 json 형식으로 데이터(변수)가 넘어올때


@ResponseBody : json형식의 출력값. 페이지로 포워드되는 것이 아닌 데이터만 넘기는 경우


@RequestParam : get/post 방식으로 전달되는 매개변수(개별변수)


@ModelAttribute : get/post 방식으로 전달되는 매개변수(클래스 타입)


@PathVariable : url에 포함된 변수




MemberService.java

1
2
3
4
5
6
7
8
9
package com.example.spring04.service.member;
 
import com.example.spring04.model.member.dto.MemberDTO;
 
public interface MemberService {
    MemberDTO loginCheck(String userid, String passwd);
    void join(MemberDTO dto);
}    
 




MemberServiceImp.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.spring04.service.member;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import com.example.spring04.model.member.dao.MemberDAO;
import com.example.spring04.model.member.dto.MemberDTO;
 
@Component
public class MemberServiceImpl implements MemberService {
 
    @Autowired
    private MemberDAO memberDao;
    
    @Override
    public MemberDTO loginCheck(String userid, String passwd) {
        return memberDao.loginCheck(userid, passwd);
    }
    @Override
    public void join(MemberDTO dto) {
        memberDao.join(dto);
    }
 
}
 



MemberCotroller.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.example.spring04.controller;
 
import java.util.HashMap;
import java.util.Map;
 
import javax.servlet.http.HttpSession;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
 
import com.example.spring04.model.member.dto.MemberDTO;
import com.example.spring04.service.member.MemberService;
 
@Controller
@RequestMapping("member/*")
public class MemberController {
    @Autowired
    private MemberService memberService;
    
    @RequestMapping("login.do")
    public String login() {
        return "member/login"//login.jsp로 이동
    }
    @RequestMapping("login_check.do")
    public ModelAndView login_check(
            String _id, String passwd
            ,HttpSession session) {
        MemberDTO dto=memberService.loginCheck(_id, passwd);
        String message="";
        String url="";
        if(dto==null) { //로그인 실패/DAOImpl에서 넘긴 null
            message="로그인 정보가 정확하지 않습니다.";
            url="member/login";
        }else { //로그인 성공
            message=dto.getName()+"님 환영합니다.";
            url="home";
            //세션에 등록
            session.setAttribute("userid", _id);
            session.setAttribute("name", dto.getName());
        }
        Map<String,Object> map=new HashMap<>();
        map.put("message", message);
        return new ModelAndView(url, "map", map);
    }
    
    @RequestMapping("join.do")
    public String join() {
        return "member/join"//join.jsp 회원가입페이지로 이동
    }
    @RequestMapping("member_join.do")
    public String member_join(String _id, String passwd
            , String name) {
        MemberDTO dto=new MemberDTO();
        dto.set_id(_id);
        dto.setPasswd(passwd);
        dto.setName(name);
        memberService.join(dto); //mongodb에 insert됨
        return "redirect:/member/login.do"//로그인 화면으로 이동
    }
    @RequestMapping("logout.do")
    public String logout(HttpSession session) {
        //세션 정보 초기화
        session.invalidate();
        //로그인 페이지로 이동
        return "redirect:/member/login.do";
    }
}




*[404 Error]가 뜨면 서버의 console을 봐야한다.



login.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<%@ include file="../include/header.jsp" %>
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>로그인하세요</h2>
<form method="post" name="form1"
    action="${path}/member/login_check.do">
<span style="color:red;">${map.message}</span>    
<table>
    <tr>
        <td>아이디</td>
        <td><input type="text" name="_id"></td>
    </tr>
    <tr>
        <td>비밀번호</td>
        <td><input type="password" name="passwd"></td>
    </tr>
    <tr>
        <td colspan="2" align="center">    
            <input type="submit" value="로그인">
            <input type="button" value="회원가입" 
                onclick="location.href='${path}/member/join.do';">
        </td>
    </tr>
</table>
</form>
</body>
</html>




document의 _class 는 저장된 자료형을 나타냄(  _class : "MemberDTO")