본문으로 바로가기

로그인

쿠키와 세션을 이용하여 로그인을 한다. 로그인의 상태에 따라 화면단에 보여지는 것도 달리 할 것이다.



1) index.jsp

1
2
3
<li>
    <a href="/login">로그인</a>
<li>
cs



2) LoginCommand.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
package tody.lovely.util;
 
import javax.persistence.Entity;
import javax.validation.constraints.NotEmpty;
 
@Entity
public class LoginCommand {
    
    @NotEmpty(message="아이디를 입력해주세요.")
    private String id;
 
    @NotEmpty(message="비밀번호를 입력해주세요.")
    private String pw;
    private boolean rememberId;
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getPw() {
        return pw;
    }
    public void setPw(String pw) {
        this.pw = pw;
    }
    public boolean isRememberId() {
        return rememberId;
    }
    public void setRememberId(boolean rememberId) {
        this.rememberId = rememberId;
    }
 
}
cs

Hiberante를 썼다. 여기는 null만 검증하면 되는 거라서 hibernate를 썼다.



3) LoginController.java

1
2
3
4
5
6
7
8
9
10
11
12
    @RequestMapping(value="/login", method=RequestMethod.GET)
    public ModelAndView loginForm(LoginCommand loginCommand,
                    @CookieValue(value="REMEMBER", required=false) Cookie rememberCookie) throws Exception {
        
        if(rememberCookie!=null) {
            loginCommand.setId(rememberCookie.getValue());
            loginCommand.setRememberId(true);
        }
        
        ModelAndView mv = new ModelAndView("user/login/loginForm");
        return mv;
    }
cs

- 3행 : 아이디 기억을 위한 Cookie 부분이다.

- 5~8행 : Cookie가 있으면(아이디 기억을 했으면) Cookie에 있는 id와 rememberId의 값을 보낸다.



4) loginForm.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="panel-body">
   <form:form role="form" commandName="loginCommand" action="/login" method="post">
        <fieldset>
            <div class="form-group">
                <form:input type="text" class="form-control" placeholder="ID" path="id"/>
            </div>
            <div class="form-group">
                 <form:password class="form-control" placeholder="Password" path="pw"/>
            </div>
            <div class="checkbox">
                <label>
                    <form:checkbox path="rememberId"/>아이디 기억
                </label>
            </div>
                <button type="submit" class="btn btn-lg btn-success btn-block">로그인</button>
        </fieldset>
    </form:form>
</div>
cs



5) 확인

짠!



6) AuthInfo.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
package tody.lovely.util;
 
//회원 정보 세션 유지
public class AuthInfo {
    
    private String id;
    private String name;
    private int grade;
    
    public AuthInfo(String id, String name, int grade) {
        this.id = id;
        this.name = name;
        this.grade = grade;
    }
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getGrade() {
        return grade;
    }
    public void setGrade(int grade) {
        this.grade = grade;
    }
 
}
cs

회원 정보 세션을 유지해주는 기능을 할 것이다. UserVO를 그대로 사용하게 되면 보안성에 취약할 뿐만 아니라, 불필요한 정보까지 유지가 된다. 그래서 따로 세션 정보 유지를 위해 만들었다.

- 10~14행 : 로그인이 성공하면서, 저장된다.



7) UserVO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package tody.lovely.vo;
 
import java.util.Date;
 
public class UserVO {
    
    private int IDX;
    private String ID;
    private String EMAIL;
    private String NAME;
    private String PASSWORD;
    private int GRADE;
    private Date REGDATE;
        
    //비밀번호 확인
    public boolean matchPassword(String pw) {
        return this.PASSWORD.equals(pw);
    }
 
    /* Getter, Setter 생략 */
}
cs

- 16~18행 : 비밀번호 확인을 위해서 추가했다.



8) LoginController.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
    @Resource(name="userService")
    private UserService userSer;
 
    @RequestMapping(value="/login", method=RequestMethod.POST)
    public ModelAndView loginSuccess(@Valid LoginCommand loginCommand, BindingResult bindingResult,
                                    HttpSession session, HttpServletResponse response) throws Exception {
 
        if(bindingResult.hasErrors()) {
            ModelAndView mv = new ModelAndView("user/login/loginForm");
            return mv;
        }
        
        try {
            
            AuthInfo authInfo = userSer.loginAuth(loginCommand);
            session.setAttribute("authInfo", authInfo);
            
            Cookie rememberCookie = new Cookie("REMEMBER", loginCommand.getId());
            rememberCookie.setPath("/");
            if(loginCommand.isRememberId()) {
                rememberCookie.setMaxAge(60*60*24*7);
            } else {
                rememberCookie.setMaxAge(0);
            }
            response.addCookie(rememberCookie);
            
        } catch (IdPasswordNotMatchingException e) {
            bindingResult.rejectValue("pw""notMatch""아이디와 비밀번호가 맞지않습니다.");
            ModelAndView mv = new ModelAndView("user/login/loginForm");
            return mv;
        }
        
        ModelAndView mv = new ModelAndView("login/loginSuccess");
        return mv;
    }
cs

- 5행, 8~11행 : @Valid 어노테이션을 이용해 유효성검사를 한다.

- 15~16행 : 로그인에 성공하면 authInfo를 반환한다.

- 18행 : 쿠키를 생성하여 로그인 될때 생성된 id를 쿠키에 저장한다.

- 19행 : 쿠키를 찾을 경로를 변경해준다.

- 20~21행 : 아이디 기억을 체크했다면, 7일 정도의 유효시간을 정해준다. ( 60*60*24*30 : 30일 )

- 23행 : 아이디 기억을 체크하지 않았다면, 설정하지 않는다.

- 25행 : 쿠키를 적용해준다.

- 27~31행 : Service에서 exception을 한 부분이다. 아이디가 없거나, 비밀번호가 맞지않으면 에러를 보낸다.

- 33행: 로그인에 성공하면 이동할 페이지를 정할 수 있다. 메인 페이지로 보내고 싶다면 redirect:/ 로 설정하면 된다.



9) UserService.java

1
2
    AuthInfo loginAuth(LoginCommand loginCommand) throws Exception;
 
cs

Controller의 15행에 의해 만들어졌다.



10) UserServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @Resource(name="userDAO")
    private UserDAO userDAO;
 
    @Override
    public AuthInfo loginAuth(LoginCommand loginCommand) throws Exception {
        UserVO user = userDAO.selectById(loginCommand.getId());
        if(user == null) {
            throw new IdPasswordNotMatchingException();
        }
        if(!user.matchPassword(loginCommand.getPw())) {
            throw new IdPasswordNotMatchingException();
        }
        return new AuthInfo(user.getID(), user.getNAME(), user.getGRADE());
    }
cs

- 8~9행 : 아이디가 있는 지 확인한다. 없으면 exception 처리한다.

- 10~12행 : 아이디와 비밀번호가 맞는 지 확인한다. UserVO에서 만들었다.

- 13행 : 아이디와 비밀번호가 확인되면, AuthInfo에 회원정보를 저장한다.



11) exception.java

1
2
3
4
5
package tody.lovely.exception;
 
public class IdPasswordNotMatchingException extends RuntimeException {
 
}
cs



12) UserDAO.java

1
2
3
4
5
6
7
8
@Repository("userDAO")
public class UserDAO extends AbstractDAO{
 
    public UserVO selectById(String id) {
        return (UserVO) selectOne("user.selectById", id);
    }
 
}
cs



13) user_sql.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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="user">
    
    <select id="selectById" resultType="tody.lovely.vo.UserVO">
        <![CDATA[
          SELECT
              *
          FROM
              USER
          WHERE
              ID = #{id}       
      ]]>
    </select>
 
</mapper>
cs



14) loginForm.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div class="panel-body">
   <form:form role="form" commandName="loginCommand" action="/login" method="post">
        <fieldset>
            <div class="form-group">
                <form:input type="text" class="form-control" placeholder="ID" path="id"/>
                <form:errors path="id"/>
            </div>
            <div class="form-group">
                 <form:password class="form-control" placeholder="Password" path="pw"/>
                 <form:errors path="pw"/>
            </div>
            <div class="checkbox">
                <label>
                    <form:checkbox path="rememberId"/>아이디 기억
                </label>
            </div>
                <button type="submit" class="btn btn-lg btn-success btn-block">로그인</button>
        </fieldset>
    </form:form>
</div>
cs

- 06, 10행: 에러메세지를 보여주기 위해 추가한다.



15) loginSuccess.jsp

1
로그인 성공! ${authoInfo.name }님, 반갑습니다.
cs

controller에서 메인 페이지로 리다이렉트했다면 만들지 않아도 되는 페이지다. 각자 원하는 대로 꾸미면 된다.

${authInfo.name}은 세션에 넣어둔 정보를 가져와서 확인할 수 있다.



16) index.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
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 
<c:catch>
    <c:choose>
        <c:when test="${empty authInfo }">
            <li>
                 <a href="/login"><i class="fa fa-sign-in"></i> 로그인</a>
             </li>
             <li>
                 <a href="/register/step1"><i class="fa fa-user"></i> 회원가입</a>
             </li>
        </c:when>
        <c:otherwise>
            <c:choose>
                <c:when test="${authInfo.grade eq '1' }">
                    <li>
                       <p>관리자 ${authInfo.name }님, 환영합니다.</p>
                   </li>
                   <li>
                       <a href="/logout"><i class="fa fa-sign-out"></i> 로그아웃</a>
                   </li>
                </c:when>
                <c:otherwise>
                    <li>
                       <p>${authInfo.name }님, 반갑습니다!</p>
                   </li>
                   <li>
                       <a href="/logout"><i class="fa fa-sign-out"></i> 로그아웃</a>
                   </li>
                </c:otherwise>
            </c:choose>
        </c:otherwise>
    </c:choose>
</c:catch>
cs

- 5~12행 : 로그인을 하지 않아, 세션정보가 없다면 로그인/회원가입이 뜬다.

- 15~21행 : 로그인이 되어 세션정보가 있는데, grade가 1이면(관리자) 관리자 화면이 뜬다.

- 24~30행 : 로그인이 되어 세션정보가 있는데, grade가 1이 아니면 일반회원 화면이 뜬다.



17) 확인


17-1. 비밀번호나 아이디가 틀린 경우

에러 문구가 떴다.


17-2. 로그인 성공

authInfo 세션에 넣어둔 정보인 이름도 떴다.

그리고 메인 페이지의 수정으로 인해 로그인/회원가입도 로그아웃으로 바뀌었다.


로그인은 끝났다. 아이디 기억은 로그아웃을 완성하고 해보자.



로그아웃

로그아웃은 매우 쉽다. 그냥 세션만 끊어주면 되기 때문!


1) index.jsp

1
2
3
<li>
    <a href="/logout">로그아웃</a>
</li>
cs



2) LoginController.java

1
2
3
4
5
6
    @RequestMapping("/logout")
    public ModelAndView logout(HttpSession session) {
        session.invalidate();
        ModelAndView mv = new ModelAndView("redirect:/");
        return mv;
    }
cs

- 3행 : 세션 전체를 날려버린다.

- 4행 : 로그아웃 버튼을 누르면 바로 메인페이지로 리다이렉트한다.



3) 확인


3-1. 로그아웃을 누를 경우

세션이 모두 사라져서 다시 로그인/회원가입이 뜬다.



4) 아이디 기억 기능 확인

4-1. 아이디 기억을 하고 로그인 후 로그아웃하고 다시 로그인할 경우


아이디 기억을 누르고 로그인을 했다.

로그아웃 후 다시 로그인을 누르면, 아이디와 아이디기억부분의 체크가 자동으로 되어있다.


4-2. 아이디 기억을 하지않고 로그인 후 로그아웃하고 다시 로그인할 경우

아이디 기억을 하지 않고 로그인을 한다.

로그아웃 후 다시 로그인을 누르면 아이디 기억을 하지 않는 상태가 뜬다.


로그인, 로그아웃 끝!


2019.01.11

의외로 많은 분들이 이 글을 보시길래 깜짝 놀랐다. 통계보다가 놀랬다ㅎ 좀 빠진 부분이 있는 글이라서ㅠㅠ 그래서 나도 새로운 프로젝트에 그대로 복붙하면서 빠진 부분은 추가하고, 이상한 부분은 수정했다. 그대로 따라한다면 문제가 없을 것 같지만 그래도 생긴다면 ㅠㅠ.. 그리고 덧붙이자면 나는 이런 로그인, 로그아웃 보다는 Spring Security를 이용한 로그인, 로그아웃이 더 좋다고 생각한다. 보안적으로나.. 좀 더 있어 보이기도 하고.. 근데 스프링을 이제 배우는 단계라면 책에서도 이런 방법을 쓸 것이고, 굳이 보안까지 생각할 필욘 없다. 나중에 좀 더 스프링에 익숙해졌을 때 시큐리티를 이용해서 로그인, 로그아웃을 해보시길.. 그리고 제 블로그에 스프링 시큐리티를 이용한 로그인 로그아웃 글이 있으니 많이 놀러 와주세.. 읍읍


댓글을 달아 주세요

  1. 이전 댓글 더보기
  2. 스니 2018.10.08 18:09

    알려주신 걸 확인하려 하는데.. 음 코드를 그대로 사용해서 어떤 걸 고쳐야 할 지 잘 모르겠어요..콘솔에는018-10-08 18:09:41,190 INFO [ SQL ] : SELECT * FROM USER WHERE ID = 'kim'2018-10-08 18:09:41,198 INFO [jdbc.resultsettable] |----|---|------|-----|---------|------|--------|2018-10-08 18:09:41,198 INFO [jdbc.resultsettable] |IDX |ID |EMAIL |NAME |PASSWORD |GRADE |REGDATE |2018-10-08 18:09:41,198 INFO [jdbc.resultsettable] |----|---|------|-----|---------|------|--------|2018-10-08 18:09:41,198 INFO [jdbc.resultsettable] |----|---|------|-----|---------|------|--------|이렇게만 뜨곤 넘어가지 않아요..

    • BlogIcon #에게 2018.10.08 18:30 신고

      지금 쿼리문을 실행했는데 DB 테이블에 아무런 데이터가 오지 않고 있어요..! DB에 데이터를 추가해주셔야 될 거 같아요~!

    • 스니 2018.10.08 18:40

      db에 회원가입시 만들어놓은 아이디들이 다 들어간 상태입니다.. ㅠㅠ 이 때는 뭘 확인해야 할까요?

    • BlogIcon #에게 2018.10.08 18:52 신고

      잉??! 테이블명이 달라서 그런걸까요..? 회원가입때 똑같은 selectById를 썼었는데 여기서는 안된다는건 뭔가 이상한거 같아요ㅠㅠ!! 저렇게 쿼리문이 찍혔는데 데이터 테이블에 아무것도 없으면 데이터가 안온다는 게 분명한데..... mysql에서 쿼리를 찍어보시겠어요??

    • BlogIcon #에게 2018.10.08 18:54 신고

      아 아니면 UserVO 부분에서... 대문자 소문자 확인ㅇ해주시겠ㅇ요? mysql이랑 대문자 소문자 구분이 같아야 하거든요

  3. 가넷sw 2019.04.08 09:00

    적용중에 궁금한 사항이 있습니다.

    Neither BindingResult nor plain target object for bean name 'loginCommand' available as request attribute

    이 내용이 발생하는데 어느부분을 확인하여야 하는지 좀 확인해주실수 있을까요?

    • BlogIcon #에게 2019.04.09 11:19 신고

      로그인 컨트롤러에 선언을 안했거나, jsp에 commandName 을 셋팅 안하신 거 같아요. 답이 늦어서 죄송합니다 ㅠㅠ

  4. 오르막내리막 2019.04.13 04:40

    으흠...
    //로그인 비밀번호 확인
    public boolean matchPassword(String pw) {
    return this.PASSWORD.equals(pw);
    }

    ==============
    if(!user.matchPassword(loginCommand.getPw())) {
    throw new IdPwNoMatchingException();
    }



    여기에서 오류가 나네요;
    널포인트가 뜨면서 500이 뜨네요ㅠㅠ

    • BlogIcon #에게 2019.04.13 10:58 신고

      음.. 예외클래스가 rumtimeexception을 상속하는 지 봐야할 거 같고... userVo에 있는 비밀번호 확인 객체가 null로 와서 발생하는거 같아여..! logincommand에 비밀번호가 담겼는지도 확인해봐야할 거 같아용..

    • BlogIcon #에게 2019.04.13 11:00 신고

      혹시나 필요하실까봐 해당 프로젝트 깃 주소 남깁니당... https://github.com/todyDev/spring-sign-up-and-in

  5. 오르막내리막 2019.04.13 17:29

    확실히 Controller, Service, 쪽에서 문제 있는것 같은데 깃허브에서 찾아봐도 틀린게 전혀 없는데;
    이상하네요.........

  6. 오르막내리막 2019.04.13 17:31

    아 궁금한게 userVO에
    public boolean matchPassword(String pw) {
    return this.PASSWORD.equals(pw);
    }
    인자값인 pw가 userServiceImpl에


    public AuthInfo loginAuth(LoginCommand loginCommand) throws Exception {

    UserVO user = userDAO.selectById(loginCommand.getId());

    if(user == null) {
    throw new IdPwNoMatchingException();
    }
    else if(!user.matchPassword(loginCommand.getPw())) {
    throw new IdPwNoMatchingException();
    }
    return new AuthInfo(user.getID(), user.getNAME(), user.getGRADE());
    }

    여기서 비교하는게 맞는건가요???
    흑흑...어렵네여;

    • BlogIcon #에게 2019.04.13 17:38 신고

      pw가 사용자가 입력한 비밀번호인 logincommand.getPw() 에용! 거기서 비교하는 게 맞아요. 근데 비밀번호 비교하는 곳이 else if가 아니라 if 에요!!! 그래서 비밀번호가 맞지 않을때 널포인트가 발생한거 같아요!!!

  7. 오르막내리막 2019.04.13 17:41

    아 일부러 else if 로 바꿔봤습니다ㅠ
    if 로 해도 500 에러가 계속 뜨네욤 ㅠㅠ
    그리고 궁금한게 회원가입도 보면서 왔는데요 user_sql.xml 에서 쿼리문을 3개 다 썼으면 굳이 select * form user where id = #{id} 안써도 상관없죠?

    • BlogIcon #에게 2019.04.13 17:47 신고

      아악 그렇군용ㅎㅎ 회원가입때 사용했던 거를 그대로 사용한거에요 다만 이전에는 아이디와 이름만 가져왔다면 이번엔 모두 가져오는 걸로 살짝 바꿔준거죵!

      근데 왜 자꾸 널포인트가 발생할까요ㅠㅠ 데이터들이 제대로 안 담겨오는 거 같은데..

  8. 오르막내리막 2019.04.13 17:56

    아이고 ㅠㅠ 그러게요; 너무 답답합니다 ㅠㅠ 구글링하면서 이것저것 바꿔봐도 안되고...
    뭐가 문제인지 모르겠네여; 제가 살짝 변경해서 해보다가 너무 짜증나서 선생님껄로 싹 다 바꿔서 해봤는데도 안되더라구요...그래서 결국에는 userVO 부분 주석처리하니깐 JSP 성공페이지로 넘어가지는데 -_-;
    뭔지 모르겠습니당...

    • BlogIcon #에게 2019.04.13 18:24 신고

      음.. 제대로 된 로그인을 해도, 비밀번호나 아이디를 틀려도 널포인트가 발생하는 건가요..? 회원가입은 잘 되었다면.. sql문이 문제일 수도 있어용...

  9. 오르막내리막 2019.04.13 18:33

    넵 제대로된 로그인을 해도 500 널포인트가 뜨고 아니여도 널포인트가 뜹니다;
    음... 혹시 쿼리문에서 GRADE 이 부분은 따로 작성을 안해도 되나요???
    userVO 나 AuthInfo 같은데에는 grade가 있는데..
    쿼리문 상에서는 grade 에 대한 목록이 안보여서욤 하핳

    • BlogIcon #에게 2019.04.13 18:43 신고

      앗 selectById 쿼리문을 select * from .... 이렇게 해줫다면 grade도 넘어와용.. 혹시 회원가입때 꺼를 수정안하셨다면 grade 데이터가 안와서 마지막 리턴할때 user.getGRADE()에서 널포인트가 발생할 수도 있어요!!

  10. 오르막내리막 2019.04.13 18:48

    아 맞네요!


    <!-- SQL 특수문자 문자열로 인식. -->
    <select id="selectByEmail" resultType="com.popo.vo.UserVO">
    <![CDATA[
    SELECT EMAIL, NAME FROM USER WHERE EMAIL = #{email}
    ]]>
    </select>

    <!-- 아이디 조회 -->
    <!-- <select id="selectById" resultType="com.popo.vo.UserVO">
    <![CDATA[
    SELECT * FROM USER WHERE ID = #{id}
    ]]>
    </select> -->

    <!-- 회원가입 -->
    <select id="selectById" resultType="com.popo.vo.UserVO">
    <![CDATA[
    SELECT ID, NAME FROM USER WHERE ID = #{id}
    ]]>
    </select>

    <insert id="register">
    <![CDATA[
    INSERT INTO USER
    (
    EMAIL,
    ID,
    NAME,
    PASSWORD,
    GRADE,
    REGDATE
    )
    VALUES
    (
    #{email},
    #{id},
    #{name},
    #{password}
    GRADE()
    SYSDATE()
    )
    ]]>
    </insert>




    여기서 아이디 조회란에 SELECT * FROM USER WHERE ID = #{id} 이 부분때문에 에러가 계속 떠서 스프링에서는 같은 id가 중복되면 안되는건가 싶어서 주석처리하고
    회원가입에서 GRADE를 안했는데...

    이게 원인이였나보네요!!

  11. 오르막내리막 2019.04.13 18:49

    그러면 회원가입상태에서 grade 가 올라가게 하려면

    <![CDATA[
    INSERT INTO USER
    (
    EMAIL,
    ID,
    NAME,
    PASSWORD,
    GRADE,
    REGDATE
    )
    VALUES
    (
    #{email},
    #{id},
    #{name},
    #{password}
    GRADE()
    SYSDATE()
    )
    ]]>

    이렇게 하는게 맞는건가요????

    • BlogIcon #에게 2019.04.13 18:53 신고

      오! 찾아서 다행이네요! 저는 db생성할때 grade는 기본으로 0으로 설정했어요(회원은 0, 관리자는 1) 그래서 쿼리에 grade를 넣지 않아도 저절로 0이 들어가게 된거죠. 만약에 쿼리에 넣고싶으시면 GRADE()말고 0 을 넣어주면 될거에용!

  12. 스니님 2019.05.21 17:41

    안녕하세요 회원가입이 되다가 로그인에서 get 오류나서 post에 get도 @RequestMapping(value="/login", method= {RequestMethod.GET, RequestMethod.POST}) 이렇게 추가해줬더니 로그인이 됬는데 잘되던 회원가입이

    ### Error updating database. Cause: java.sql.SQLSyntaxErrorException: (conn=501) FUNCTION board.GRADE does not exist
    ### The error may involve com.zalesia.paxata.register.mapper.UserMapper.insertUser-Inline
    ### The error occurred while setting parameters
    ### SQL: INSERT INTO user ( ID, EMAIL, NAME, PASSWORD, GRADE, REGDATE ) VALUES ( ?, ?, ?, ?, GRADE(), SYSDATE() )
    ### Cause: java.sql.SQLSyntaxErrorException: (conn=501) FUNCTION board.GRADE does not exist
    ; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: (conn=501) FUNCTION board.GRADE does not exist] with root cause

    java.sql.SQLException: FUNCTION board.GRADE does not exist

    오류가나네요 문의좀 드리겠습니다!!

    • BlogIcon #에게 2019.05.21 17:46 신고

      sql문에서 GRADE() 에서 오류가 나는 거 같아요. mysql엔 GRADE() 함수가 없어요ㅠㅠ

    • 스니님 2019.05.21 17:48

      빠른답변 감사합니다 필자님꺼 보면서 꿈을키워가는 초보 개발자인데 혹시 마리아 db사용하는데 어떻게 해결하면 될까요??

    • BlogIcon #에게 2019.05.21 17:49 신고

      앗..ㅠㅠ 저도 초보개발자라 mysql 밖에 사용해보질 못했어요ㅠㅠ

    • 스니님 2019.05.21 17:49

      CREATE TABLE `user` (
      `IDX` INT(11) NOT NULL AUTO_INCREMENT,
      `ID` VARCHAR(45) NOT NULL,
      `EMAIL` VARCHAR(100) NOT NULL,
      `NAME` VARCHAR(45) NOT NULL,
      `PASSWORD` VARCHAR(45) NOT NULL,
      `GRADE` INT(11) NOT NULL DEFAULT '0',
      `REGDATE` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (`IDX`),
      UNIQUE INDEX `ID` (`ID`),
      UNIQUE INDEX `EMAIL` (`EMAIL`)
      )
      COLLATE='utf8_general_ci'
      ENGINE=InnoDB
      AUTO_INCREMENT=5
      ;
      마리아 디비 테이블 입니다


      <?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.zalesia.paxata.register.mapper.UserMapper">

      <select id="selectByEmail" parameterType="string" resultType="com.zalesia.paxata.register.model.UserVO">
      <![CDATA[
      SELECT
      EMAIL,
      NAME
      FROM
      user
      WHERE
      EMAIL = #{email}
      ]]>
      </select>

      <select id="selectById" parameterType="string" resultType="com.zalesia.paxata.register.model.UserVO">
      <![CDATA[
      SELECT
      *
      FROM
      user
      WHERE
      ID = #{id}
      ]]>
      </select>



      <insert id="insertUser" parameterType="com.zalesia.paxata.register.model.RegisterRequest">
      <![CDATA[
      INSERT INTO user
      (
      ID,
      EMAIL,
      NAME,
      PASSWORD,
      GRADE,
      REGDATE
      )
      VALUES
      (
      #{id},
      #{email},
      #{name},
      #{pw},
      GRADE(),
      SYSDATE()
      )
      ]]>
      </insert>





      </mapper>


      xml 입니다!!

    • 스니님 2019.05.21 17:53

      필자님께서 함수 없다고 하신거보고 똑같이 grade() default '0'해줬습니다!!
      mriadb 랑 mysql 이랑 문법이 같아요!!

    • 스니님 2019.05.21 18:04

      해결했습니다!!
      xml 이랑 db에

      grade를 만들어서 뻘짓했네요 ㅠㅠ
      감사합니다!!

    • BlogIcon #에게 2019.05.21 19:05 신고

      앗 왜 또 알람이ㅠㅠ 해결됐다니 다행이네요!!

  13. 스니님 2019.05.22 16:56

    안녕하세요 오늘도 질문이 있습니다! 17-2 상단에 로그인에서 dao님 반갑습니다! 로 바뀌게 어떻게 하는거에요 위에서 상단 bootstrap써서 tag로 잡혀있는데..

    • BlogIcon #에게 2019.05.22 17:33 신고

      16번을 보시면 방법이 나와있어요! authinfo에 담기는 세션을 이용해서 c태그로 로그인 했을때와 안했을 때를 다르게 보여줄 수 있어요

    • 스니님 2019.05.22 18:03

      따라했을때요 index.jsp body 부분에는 이름이 바뀌는데 tags에 tag 설정해준 header 부분에는 어떻게 줘야 될지를 모르겠네요 ㅠ

    • BlogIcon #에게 2019.05.22 18:15 신고

      음... header부분 코딩을 봐야할 거 같은데요??? 에러가 뜨는 게 아니라 이름이 뜨지 않는 거죠??

  14. 코머 2019.05.24 10:54

    항상 좋은 글 잘보고있습니다
    11) exception.java 요 클래스는 IdPasswordNotMatchingException 이걸로 만들면되겠죠?

  15. 익명 2019.07.04 10:26

    비밀댓글입니다

    • BlogIcon #에게 2019.07.04 10:32 신고

      회원가입에서 썼던걸 써도 되냐고 물어보신 거죠? 똑같은 걸 바라보게 하셨다면 가능합니다. 오류는 로그를 보여주셔야 제가 더 정확히 답변드릴 수 있어요ㅠㅠ

    • 익명 2019.07.04 17:24

      비밀댓글입니다

    • BlogIcon #에게 2019.07.04 17:34 신고

      id 값이 넘어오지가 않네요! jsp 부분에서 설정한 id의 path명이랑 xml에서 적어준 ${id}이 부분이 같은지 부터 확인해야할 거 같아요! 대소문자도 구분이 된답니다

      기존에 만든 게 있다면 그걸 써도 되죠! 저는 같은 거라도 각자의 용도? 목적?에 따라서 분리를 하는 경우도 있어요.. 그냥 제 귀찮음에 따라서..ㅎㅎ

    • 익명 2019.07.04 17:45

      비밀댓글입니다

    • BlogIcon #에게 2019.07.04 17:51 신고

      spring 카테고리 프로젝트는 하나의 프로젝트안에 만들었어요! 연결되어 있죠.
      회원가입과 로그인에 둘 다 아이디로 정보를 가져오는 똑같은 로직이 있지만, xml을 회원가입, 로그인 이렇게 나눴어요. 만들면서 블로그에도 올려야하기 때문에, 제가 헷갈릴까봐 나눈거에요~! 동일한 기능이면 판단하셔서 굳이 2번 만들 필요 없어욤!

  16. 익명 2019.07.17 17:03

    비밀댓글입니다

  17. BlogIcon 하얀날개 2020.02.14 18:00

    깔끔하게 정리해 주셨네요! 잘 배워갑니다!!

  18. 개발자를꿈꾸는퍼블리셔 2020.07.23 00:30

    안녕하세요! 오늘도 열심히 공부하고 갑니다 ㅜㅜ 도장 쾅![2020.07.23]

  19. cm 2020.10.10 22:22

    form:input이 placeholder도 안나오고 클릭이 안됩니다.
    checkbox도 안나오고요

    • BlogIcon #에게 2021.10.29 15:08 신고

      jsp 상단에 아래 태그가 선언되어 있을까요?

      <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

  20. bhs5121 2020.12.22 09:36

    혹시 해당 프로젝트 깃 주소 알려주실수 있으시나요??
    자바 스프링 독학중인데 참고하면서 공부하고 싶습니다.

    • BlogIcon #에게 2021.10.29 15:23 신고

      많이 늦었지만 다른 분들을 위해 남겨두겠습니다 ㅠㅠ 죄송합니다 ㅠㅠ

      https://github.com/todyDev/spring-sign-up-and-in

  21. 게스트1 2021.05.13 13:24

    very good 좋은 참고가 되었습니다. :)