* 여러개의 게시판들중 게시판의 아이디를 기준으로 관련 글 목록을 불러오는 작업

이미 main 메서드에서 게시판 별 board_info_idx 값을 파라미터로 주입 받아 놓고 있다.

@Controller
@RequestMapping("/board")
public class BoardController {
	
	...
	
	@GetMapping("/main")
	public String main(@RequestParam("board_info_idx") int board_info_idx, Model model) {
		
		model.addAttribute("board_info_idx", board_info_idx);
		
		return "board/main";
	}

 

- JAVA 프로젝트

1. 게시판 제목 불러오기

1.1 Mapper 설정

public interface BoardMapper {
	...
	
	@Select("select board_info_name " +
			"from board_info_table " +
			"where board_info_idx = #{board_info_idx}")
	String getBoardInfoName(int board_info_idx);
}

 

1.2 DAO 설정

@Repository
public class BoardDao {
	
    @Autowired
    private BoardMapper boardMapper;

    ...
	
    public String getBoardInfoName(int board_info_idx) {
        return boardMapper.getBoardInfoName(board_info_idx);
    }
	
}

 

1.3 Service 설정

@Service
@PropertySource("/WEB-INF/properties/option.properties")
public class BoardService {
	
    ...
    
    public String getBoardInfoName(int board_info_idx) {
    	return boardDao.getBoardInfoName(board_info_idx);
    }
	
}

 

1.4 Controller 설정

@Controller
@RequestMapping("/board")
public class BoardController {
	
    @Autowired
    private BoardService boardService;

    @GetMapping("/main")
    public String main(@RequestParam("board_info_idx") int board_info_idx, Model model) {

        model.addAttribute("board_info_idx", board_info_idx);

        String boardInfoName = boardService.getBoardInfoName(board_info_idx);
        model.addAttribute("boardInfoName", boardInfoName);

        return "board/main";
    }

 

1.5 views/board/main.jsp 설정

<h4 class="card-title">${boardInfoName }</h4>

 

여기까지가 게시판 별 제목을 불러오는 설정이다.

 


 

2. 글 목록 불러오기

2.1 쿼리문 작성

게시판 테이블에 작성자 명이 없기 때문에 user 테이블과 JOIN을 해서 작성자명 까지 가져와야 한다.

2.2 ContentBean에 작성자명을 받을 필드 추가

public class ContentBean {
	
    ...
    private String content_writer_name; // DB에서 불러올 작성자명

 

2.3 Mapper 설정

public interface BoardMapper {
	...
    
    @Select("select a1.content_idx, a1.content_subject, a2.user_name as content_writer_name, to_char(a1.content_date, 'YYYY-MM-DD') as content_date " +
			"from content_table a1, user_table a2 " +
			"where a1.content_writer_idx = a2.user_idx " +
			    "and a1.content_board_idx = #{board_info_idx} " +
			"order by a1.content_idx desc")
	List<ContentBean> getContList(int board_info_idx);

 

2.4 DAO 설정

@Repository
public class BoardDao {
	...
	public List<ContentBean> getContList(int board_info_idx) {
		return boardMapper.getContList(board_info_idx);
	}
}

 

2.5 Service 설정

@Service
@PropertySource("/WEB-INF/properties/option.properties")
public class BoardService {
    ...
    public List<ContentBean> getContList(int board_info_idx) {
        return boardDao.getContList(board_info_idx);
    }
}

 

2.6 Controller 설정

@Controller
@RequestMapping("/board")
public class BoardController {
	
    @Autowired
    private BoardService boardService;

    @GetMapping("/main")
    public String main(@RequestParam("board_info_idx") int board_info_idx
                        , Model model) {

        model.addAttribute("board_info_idx", board_info_idx);

        String boardInfoName = boardService.getBoardInfoName(board_info_idx);
        model.addAttribute("boardInfoName", boardInfoName);

        List<ContentBean> contentList = boardService.getContList(board_info_idx);
        model.addAttribute("contentList", contentList);

        return "board/main";
    }
    
    ...
    
}

 

2.7 views/board/main.jsp 설정

<table class="table table-hover" id='board_list'>
    <thead>
        <tr>
            <th class="text-center d-none d-md-table-cell">글번호</th>
            <th class="w-50">제목</th>
            <th class="text-center d-none d-md-table-cell">작성자</th>
            <th class="text-center d-none d-md-table-cell">작성날짜</th>
        </tr>
    </thead>
    <tbody>
        <c:forEach var='obj' items="${contentList }">
            <tr>
                <td class="text-center d-none d-md-table-cell">${obj.content_idx }</td>
                <td><a href='${root }board/read'>${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>

 


- XML 프로젝트

JAVA 프로젝트와 다른 것만 표기

 

1. Mapper 설정

...
<mapper namespace="board">
    ...

    <select id="getBoardInfoName" parameterType="java.lang.Integer" resultType="java.lang.String">
        <![CDATA[
            select board_info_name
            from board_info_table
            where board_info_idx = #{board_info_idx}
        ]]>
    </select>

    <select id="getContList" parameterType="java.lang.Integer" resultType="com.example.beans.ContentBean">
        <![CDATA[
            select a1.content_idx, a1.content_subject, a2.user_name as content_writer_name, to_char(a1.content_date, 'YYYY-MM-DD') as content_date
            from content_table a1, user_table a2
            where a1.content_writer_idx = a2.user_idx
                and a1.content_board_idx = #{board_info_idx}
            order by a1.content_idx desc
        ]]>
    </select>
</mapper>

2. DAO 설정

@Repository
public class BoardDao {
	
	@Autowired
	private SqlSessionTemplate sqlSessionTemplate;
	
	...
	
    public String getBoardInfoName(int board_info_idx) {
        return sqlSessionTemplate.selectOne("board.getBoardInfoName", board_info_idx);
    }

    public List<ContentBean> getContList(int board_info_idx) {
        return sqlSessionTemplate.selectList("board.getContList", board_info_idx);
    }
}

- JAVA 프로젝트

1. /WEB-INF/views/user/modify.jsp 페이지 설정

1.1 modelAttribute는 modifyUserBean으로 설정

     컨트롤러에서 UserBean을 modifyUserBean에 주입해서 넘겨주기 때문에

     UserBean의 필드명과 form input 의 name 값이 같다면 form input에 value속성을 지정하지 않아도 된다.

<%@ 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>

...

<form:form action="${root }user/modify_pro" method="post" modelAttribute="modifyUserBean">
    <div class="form-group">
        <form:label path="user_name">이름</form:label>
        <form:input path="user_name" class="form-control" readonly="true" />
    </div>
    <div class="form-group">
        <form:label path="user_id">아이디</form:label>
        <form:input path="user_id" class="form-control" readonly="true" />
    </div>
    <div class="form-group">
        <form:label path="user_pw">비밀번호</form:label>
        <form:password path="user_pw" class="form-control" />
        <form:errors path="user_pw" style="color:red" />
    </div>
    <div class="form-group">
        <form:label path="user_pw2">비밀번호 확인</form:label>
        <form:password path="user_pw2" class="form-control" />
        <form:errors path="user_pw2" style="color:red" />
    </div>
    <div class="form-group">
        <div class="text-right">
            <form:button class="btn btn-primary">정보수정</form:button>
        </div>
    </div>
</form:form>

 

2. Controller에서의 view 페이지 설정

@Controller
@RequestMapping("/user")
public class UserController {

	...
	
    @GetMapping("/join")
    public String join(@ModelAttribute("joinUserBean") UserBean joinUserBean) {
        return "user/join";
    }

 

3. 정보수정 Mapper 설정

유저의 정보 조회와 수정 처리 쿼리문을 작성 해준다.

package com.example.mapper;

...

public interface UserMapper {
	
	...
	
	@Select("select user_id, user_name " + 
			"from user_table " + 
			"where user_idx = #{user_idx}")
	UserBean getModifyUserInfo(int user_idx);
	
	@Update("update user_table " + 
			"set user_pw = #{user_pw} " +
			"where user_idx = #{user_idx}")
	void modifyUserInfo(UserBean modifyUserBean);
	
}

 

4. DAO 설정

@Repository
public class UserDao {
	
    @Autowired
    private UserMapper userMapper;

    ...

    public UserBean getModifyUserInfo(int user_idx) {
        return userMapper.getModifyUserInfo(user_idx);
    }

    public void modifyUserInfo(UserBean modifyUserBean) {
        userMapper.modifyUserInfo(modifyUserBean);
    }

 

 

5. 서비스에서 다오 주입 후 컨트롤러 셋팅

컨트롤러에서 modifyUserBean이라는 이름으로 Bean을 주입 받았기 때문에 modifyUserBean에 데이터를 담아야지만

form에서 보여줄 수 있다.

그렇기 때문에 서비스로 modifyUserBean객체를 그대로 넘겨 준다.

public class UserController {

	...
	
	@GetMapping("/modify")
	public String modify(@ModelAttribute("modifyUserBean") UserBean modifyUserBean) {
		userService.getModifyUserInfo(modifyUserBean);
		
		return "/user/modify";
	}

서비스에서는 getModifyUserInfo에서 컨트롤러부터 전달받은 modifyUserBean에 값을 담아주기만 하면 된다.

package com.example.service;

...

@Service
public class UserService {
	
	@Autowired
	private UserDao userDao;
	
	@Resource(name = "loginUserBean")
	private UserBean loginUserBean;
	
	...
	
	public void getModifyUserInfo(UserBean modifyUserBean) {
		UserBean tempModifyUserBean = userDao.getModifyUserInfo(loginUserBean.getUser_idx());
		
		modifyUserBean.setUser_id(tempModifyUserBean.getUser_id());
		modifyUserBean.setUser_name(tempModifyUserBean.getUser_name());
		modifyUserBean.setUser_idx(loginUserBean.getUser_idx());
	}
	
	public void modifyUserInfo(UserBean modifyUserBean) {
		modifyUserBean.setUser_idx(loginUserBean.getUser_idx());
		
		userDao.modifyUserInfo(modifyUserBean);
	}
	
}

 

6. 컨트롤러에서 form 데이터 전달 받아 처리할 메서드 설정

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Resource(name = "loginUserBean")
    private UserBean loginUserBean;
    
    ...

    @PostMapping("/modify_pro")
    public String modify_pro(@Valid @ModelAttribute("modifyUserBean") UserBean modifyUserBean, BindingResult result) {
        if(result.hasErrors()) {
            return "user/modify";
        }

        userService.modifyUserInfo(modifyUserBean);

        return "user/modify_success";
    }

 

7. 오류메시지 설정

데이터를 주고 받는 ModelAttribute의 modifyUserBean에 대한 오류 메시지를 설정.

 

8. Validator에서 modifyUserBean에 대한 조건을 설정.

package com.example.validator;

...

public class UserValidator implements Validator{

	@Override
	public boolean supports(Class<?> clazz) {
		// TODO Auto-generated method stub
		return UserBean.class.isAssignableFrom(clazz);
	}

	@Override
	public void validate(Object target, Errors errors) {
		// TODO Auto-generated method stub
		UserBean userBean = (UserBean) target;
		
		String beanName = errors.getObjectName();
		
		if (beanName.equals("joinUserBean") || beanName.equals("modifyUserBean")) {
			if (userBean.getUser_pw().equals(userBean.getUser_pw2()) == false) {
				errors.rejectValue("user_pw", "NotEquals");
				errors.rejectValue("user_pw2", "NotEquals");
			}
		}
		
		if (beanName.equals("joinUserBean")) {
			if (userBean.isUserIdExist() == false) {
				errors.rejectValue("user_id", "DontCheckUserIdExist");
			}
		}
	}
	
}

 

9. 수정 성공 시 페이지 셋팅

<%@ 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("수정 되었습니다.");
	location.href="${root}user/modify";
</script>

 


-XML 프로젝트

자바 프로젝트 설정과 다른 것만 기록을 해본다.

 

1. 매퍼 설정

<?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="getModifyUserInfo" parameterType="java.lang.Integer" resultType="com.example.beans.UserBean">
		<![CDATA[
			select user_id, user_name 
			from user_table 
			where user_idx = #{user_idx}
		]]>
	</select>
	
	<update id="modifyUserInfo" parameterType="com.example.beans.UserBean">
		<![CDATA[
			update user_table 
			set user_pw = #{user_pw} 
			where user_idx = #{user_idx} 
		]]>
	</update>
	
</mapper>

 

2. DAO 설정

package com.exmaple.dao;

...

@Repository
public class UserDao {
	
	@Autowired
	private SqlSessionTemplate sqlSessionTemplate;
	
	...
	
	public UserBean getModifyUserInfo(int user_idx) {
		return sqlSessionTemplate.selectOne("user.getModifyUserInfo", user_idx);
	}
	
	public void modifyUserInfo(UserBean modifyUserBean) {
		sqlSessionTemplate.update("user.modifyUserInfo", modifyUserBean);
	}
}

 

반드시 로그인을 해야만 볼 수 있는 페이지를 사용자가 주소를 쳐서 직접 접속 하는 경우 접근 하지 못하도록 하는 처리

Interceptor에서 로그인 여부를 확인하고 로그인 하였을 경우에만 다음 단계로 진행 되도록 처리

 

- JAVA 프로젝트

1. HandlerInterceptor를 구현하는 CheckLoginInterceptor Interceptor를 만든다.

loginUserBean.isUserLogin() 값을 기준으로 처리를 해준다.

package com.example.interceptor;

...

public class CheckLoginInterceptor implements HandlerInterceptor {
	
    private UserBean loginUserBean;

    public CheckLoginInterceptor(UserBean loginUserBean) {
        this.loginUserBean = loginUserBean;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        // TODO Auto-generated method stub
        if(loginUserBean.isUserLogin() == false) {
            String contextPath = request.getContextPath();
            response.sendRedirect(contextPath + "/user/not_login");
            // Interceptor의 preHandle 메서드에서 return false;를 하게되면 다음 단계로 넘어가지 않는다.
            return false; 
        }
        return true;
    }
	
}

 

2. ServletAppContext에서 Interceptor를 등록

addPathPatterns메서드에 URL 접근시 Interceptor를 거치도록할 주소를 설정

excludePathPatterns메서드에 Interceptor 에서 검증 하지 않을 주소를 설정

package com.example.config;

...

public class ServletAppContext implements WebMvcConfigurer{
	
	...
    
    @Resource(name = "loginUserBean")
    private UserBean loginUserBean;
	
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        ...

        CheckLoginInterceptor checkLoginInterceptor = new CheckLoginInterceptor(loginUserBean);
        InterceptorRegistration reg2 = registry.addInterceptor(checkLoginInterceptor);
        reg2.addPathPatterns("/user/modify", "/user/logout", "/board/*");
        reg2.excludePathPatterns("/board/main");
    }

 

3. Controller에서 Interceptor에서 응답온 결과를 처리해줄 메서드 생성

@Controller
@RequestMapping("/user")
public class UserController {

    ...

    @GetMapping("/not_login")
    public String not_login() {
        return "/user/not_login";
    }

 

4. view 처리

<%@ 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("로그인 해주세요");
	location.href="${root}user/login";
</script>

 

 

 

 


- XML 프로젝트

1. HandlerInterceptor를 구현하는 CheckLoginInterceptor Interceptor를 만든다.

XML 프로젝트의 경우 Interceptor에서 Bean 주입을 받을 수 있다.

package com.example.interceptor;

..

public class CheckLoginInterceptor implements HandlerInterceptor {
	
	@Resource(name = "loginUserBean")
	@Lazy
	private UserBean loginUserBean;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		if(loginUserBean.isUserLogin() == false) {
			String contextPath = request.getContextPath();
			response.sendRedirect(contextPath + "/user/not_login");
			return false;
		}
		return true;
	}
	
}

 

2. WEB-INF/config/servlet-context.xml 에서 Interceptor 등록

<?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
			 					 http://www.springframework.org/schema/mvc/spring-mvc.xsd
			 					 http://www.springframework.org/schema/beans
			 					 http://www.springframework.org/schema/beans/spring-beans.xsd
			 					 http://www.springframework.org/schema/context
			 					 http://www.springframework.org/schema/context/spring-context.xsd">
			 					 
	...
	
	<interceptors>
		...
		<interceptor>
			<mapping path="/user/modify"/>
			<mapping path="/user/logout"/>
			<mapping path="/board/*"/>
			<exclude-mapping path="/board/main"/>
			<beans:bean class="com.example.interceptor.CheckLoginInterceptor" />
		</interceptor>
	</interceptors>

 

이하의 내용은 JAVA 프로젝트와 동일 하다.

- JAVA 프로젝트

메뉴 부분은 여러 화면에서 쓰이기 때문에 Interceptor로 처리 했었다.

(TopMenuInterceptor에서 topMenuService를 가져와 메서드 호출해서 구성했다.)

때문에 로그인 전 후 처리도 이곳에서 해주면 된다.

 

JAVA 프로젝트의 경우 Interceptor에서는 Bean을 주입 받을 수 없다.

그렇기 때문에 Interceptor를 정의한 ServletAppContext에서 Bean을 주입 받아서 Interceptor로 전달을 해주면 된다.

 

1. ServletAppContext에서 loginUserBean을 주입 받아 Interceptor에 전달

package com.example.config;

...

@Configuration
@EnableWebMvc
@ComponentScan("com.example.controller")
@ComponentScan("com.exmaple.dao")
@ComponentScan("com.example.service")

@PropertySource("/WEB-INF/properties/db.properties")
public class ServletAppContext implements WebMvcConfigurer{
	
    ...

    @Autowired
    private TopMenuService topMenuService;

    // Session영역에 저장해 놓은 loginUserBean을 주입 받는다.
    @Resource(name = "loginUserBean")
    private UserBean loginUserBean;
    
    ...
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // TODO Auto-generated method stub
        WebMvcConfigurer.super.addInterceptors(registry);
        
	// TopmenuInterceptor에 위에서 주입 받은 loginUserBean을 넘겨준다.
        TopMenuInterceptor topMenuInterceptor = new TopMenuInterceptor(topMenuService, loginUserBean);

        InterceptorRegistration reg1 = registry.addInterceptor(topMenuInterceptor);
        reg1.addPathPatterns("/**");
    }

 

2. TopmenuInterceptor에서 위에서 지정한 loginUserBean을 전달 받는다.

package com.example.interceptor;

...

public class TopMenuInterceptor implements HandlerInterceptor{

	private TopMenuService topMenuService;
	private UserBean loginUserBean;
	
	public TopMenuInterceptor(TopMenuService topMenuService, UserBean loginUserBean) {
		this.topMenuService = topMenuService;
		this.loginUserBean = loginUserBean;
	}
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		List<BoardInfoBean> topMenuList = topMenuService.getTopMenuList();
		request.setAttribute("topMenuList", topMenuList);
		request.setAttribute("loginUserBean", loginUserBean);
		
		return true;
	}
}

 

3. WEB-INF/views/include/top_menu.jsp로 이동해서 메뉴 로그인 전 후 처리

<ul class="navbar-nav ml-auto">
    <c:choose>
        <c:when test="${loginUserBean.userLogin == true }">
            <li class="nav-item">
                <a href="${root }user/modify" class="nav-link">정보수정</a>
            </li>
            <li class="nav-item">
                <a href="${root }user/logout" class="nav-link">로그아웃</a>
            </li>
        </c:when>
        <c:otherwise>
            <li class="nav-item">
                <a href="${root }user/login" class="nav-link">로그인</a>
            </li>
            <li class="nav-item">
                <a href="${root }user/join" class="nav-link">회원가입</a>
            </li>
        </c:otherwise>
    </c:choose>
</ul>

 

 

4. 로그아웃 처리하기

UserController로 이동해서 loginUserBean 값에 false 처리

(UserBean.java에서 생성자를 통해 기본 값도 false로 줬다.)

public class UserBean {
	
    ...

    private boolean userIdExist;

    private boolean userLogin;

    public UserBean() {
        this.userIdExist = false;
        this.userLogin = false;
    }
@Controller
@RequestMapping("/user")
public class UserController {

    @GetMapping("/logout")
    public String logout() {
        loginUserBean.setUserLogin(false);

        return "/user/logout";
    }

 

 


- XML 프로젝트

XML 프로젝트의 경우 JAVA 프로젝트와 다르게 Interceptor에서 Bean을 주입 받을 수 있다.

 

1. Interceptor에서 loginUserBean을 전달 받는다.

package com.example.interceptor;

...

public class TopMenuInterceptor implements HandlerInterceptor{

	@Autowired
	private TopMenuService topMenuService;
	
	@Resource(name = "loginUserBean")
	@Lazy
	private UserBean loginUserBean;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		List<BoardInfoBean> topMenuList = topMenuService.getTopMenuList();
		request.setAttribute("topMenuList", topMenuList);
		request.setAttribute("loginUserBean", loginUserBean);
		
		return true;
	}
}

 

나머지 설정은 JAVA프로젝트로 할 때와 동일하다.

- 사용자 로그인 기능 구현

- 아이디 비밀번호 입력에 대한 유효성 검사

- 로그인 성공 시 사용자 정보를 세션에 저장

 

- JAVA 프로젝트

1. 로그인 여부를 담을 변수 생성

기본 값은 false로 주고 하고 성공시 true 대입

package com.example.beans;

...

public class UserBean {

	...
    
	private boolean userLogin;
	
	public UserBean() {
		...
		this.userLogin = false;
	}
    
    getter, setter 설정..

 

2. 해당 Bean을 Session Scope로 등록

Bean의 이름을 한곳에서만 사용 한다면 UserBean Class에서 이름을 정하면 되지만 이 클래스는 다양한 목적으로

쓰기 때문에 RootContext 에서 지정해준다.

package com.example.config;

...

// 프로젝트 작업시 사용할 bean을 정의하는 클래스
@Configuration
public class RootAppContext {
	
	@Bean("loginUserBean")
	@SessionScope
	public UserBean loginUserBean() {
		return new UserBean();
	}
	
}

 

3. WEB-INF/views/user/login.jsp 설정

modelAttribute 속성의 값으로 tempLoginUserBean 값을 줬다. (자유롭게 지정이 가능 함)

이곳에서 사용하는 Bean은 로그인 시 잠시만 사용 할 것이기 때문에 이름을 temp로 붙여줬다.

(loginUserBean이란 이름을 세션에 Bean을 등록할때 이미 사용 함.)

* bean의 변수값과 input field의 name 값을 맞춰주도록 하자.

<%@ 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 }/" />

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

<form:form action="${root }user/login_pro" method="post" modelAttribute="tempLoginUserBean">
    <div class="form-group">
        <form:label path="user_id">아이디</form:label>
        <form:input path="user_id" class="form-control" />
        <form:errors path="user_id" style="color:red" />
    </div>
    <div class="form-group">
        <form:label path="user_pw">비밀번호</form:label>
        <form:password path="user_pw" class="form-control" />
        <form:errors path="user_pw" style="color:red" />
    </div>
    <div class="form-group text-right">
        <form:button class="btn btn-primary">로그인</form:button>
        <a href="${root }user/join" class="btn btn-danger">회원가입</a>
    </div>
</form:form>

 

4. 컨트롤러에서 form의 modelAttribute 속성의 값으로 tempLoginUserBean 넘겨주기

package com.example.controller;

...

@Controller
@RequestMapping("/user")
public class UserController {
	
	...
	
	@Resource(name = "loginUserBean")
	private UserBean loginUserBean;

	@GetMapping("/login")
	public String login(@ModelAttribute("tempLoginUserBean") UserBean tempLoginBean) {
		
		return "user/login";
	}

 

5. 유효성 검사 하기

  5.1 컨트롤러 설정

package com.example.controller;

...

@Controller
@RequestMapping("/user")
public class UserController {
	
	...
	
	@Resource(name = "loginUserBean")
	private UserBean loginUserBean;

	...
	
	@PostMapping("/login_pro")
	public String login_pro(@Valid @ModelAttribute("tempLoginUserBean") UserBean tempLoginUserBean, BindingResult result) {
		
		if (result.hasErrors()) {
			return "user/login";
		}
		
		 return "user/login_success";
	}

 

  5.2 properties 설정

@ModelAttribute의 값인 tempLoginUserBean에 대한 error message 설정

 

  5.3 Validator 설정

       다른 설정 값들이 있을 수 있기 때문에 Bean의 이름으로 조건을 걸어 해당 Bean에서만 유효성 검사를 설정 한다.

       @ModelAttribute의 값을 String beanName = errors.getObjectName();으로 받아올 수 있다.

       아래에선 로그인 시에는 조건에 걸리지 않고 회원 가입시와 추후 만들 정보 수정 시 작동 되도록 조건을 추가 했다.

package com.example.validator;

...

public class UserValidator implements Validator{

	...

	@Override
	public void validate(Object target, Errors errors) {
		// TODO Auto-generated method stub
		UserBean userBean = (UserBean) target;
		
		String beanName = errors.getObjectName();
		
		if (beanName.equals("joinUserBean") || beanName.equals("modifyUserBean")) {
			if (userBean.getUser_pw().equals(userBean.getUser_pw2()) == false) {
				errors.rejectValue("user_pw", "NotEquals");
				errors.rejectValue("user_pw2", "NotEquals");
			}
		}
		
		if (beanName.equals("joinUserBean")) {
			if (userBean.isUserIdExist() == false) {
				errors.rejectValue("user_id", "DontCheckUserIdExist");
			}
		}
	}
	
}

 

6. 매퍼 설정

로그인 시도한 값이 DB에 등록 되어 있는지 확인

package com.example.mapper;

...

public interface UserMapper {
	
	...
	
	@Select("select user_idx, user_name " + 
			"from user_table " +
			"where user_id = #{user_id} and user_pw = #{user_pw}")
	UserBean getLoginUserInfo(UserBean tempLoginUserBean);

 

7. DAO에서 Mapper에 정의한 쿼리문 실행

package com.exmaple.dao;

...

@Repository
public class UserDao {
	
	@Autowired
	private UserMapper userMapper;
	
	...
	
	public UserBean getLoginUserInfo(UserBean tempLoginUserBean) {
		return userMapper.getLoginUserInfo(tempLoginUserBean);
	}

 

8. Service에서 처리

위 2번 설정 에서 RootContext에서 loginUserBean 이라는 이름으로 SessionScope에 loginUserBean을 담아 줬다.

로그인 성공 시 loginUserBean에 로그인한 사용자의 정보를 담아 줘야 하기 때문에 loginUserBean를 주입 받는다.

package com.example.service;

...

@Service
public class UserService {
	
	@Autowired
	private UserDao userDao;
	
	@Resource(name = "loginUserBean")
	private UserBean loginUserBean;
	
	...
	
	public void getLoginUserInfo(UserBean tempLoginUserBean) {
		UserBean tempLoginUserBean2 = userDao.getLoginUserInfo(tempLoginUserBean);
		
        // tempLoginUserBean2에 가져온 값이 있으면 객체의 주소 값이 넘어 온다.
		if(tempLoginUserBean2 != null) {
			loginUserBean.setUser_idx(tempLoginUserBean2.getUser_idx());
			loginUserBean.setUser_name(tempLoginUserBean2.getUser_name());
			loginUserBean.setUserLogin(true);
		}
	}

 

9. Controller에서 처리

이 곳 에서도 Session 영역에 저장 되어 있는 UserBean을 loginUserBean으로 주입 받는다.

package com.example.controller;

...

@Controller
@RequestMapping("/user")
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@Resource(name = "loginUserBean")
	private UserBean loginUserBean;

	...
	
	@PostMapping("/login_pro")
	public String login_pro(@Valid @ModelAttribute("tempLoginUserBean") UserBean tempLoginUserBean, BindingResult result) {
		
		if (result.hasErrors()) {
			return "user/login";
		}
		
		userService.getLoginUserInfo(tempLoginUserBean);
		
		// service 단계에서 저장된 값으로 검증
		if(loginUserBean.isUserLogin() == true) {
			return "user/login_success";
		} else {
			return "user/login_fail";
		}
	}

 

10. WEB-INF/views/user/login_success.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("로그인 되었습니다");
	location.href="${root}main";
</script>

 

11. 로그인 실패 여부 처리

  11.1 컨트롤러 설정 login메서드 수정

   fail이란 이름의 파라미터에 false 값을 받아 model에 담는다.

   이후 fail에 true 값이 설정 될 경우 로그인 실패로 보면 된다.

package com.example.controller;

...

@Controller
@RequestMapping("/user")
public class UserController {
	
	...

	@GetMapping("/login")
	public String login(@ModelAttribute("tempLoginUserBean") UserBean tempLoginBean,
				@RequestParam(value = "fail", defaultValue = "false") boolean fail,
				Model model) {
		
		model.addAttribute("fail", fail);
		
		return "user/login";
	}

 

  11.2 WEB-INF/views/user/login.jsp 수정

<c:if test="${fail == true }" >
<div class="alert alert-danger">
    <h3>로그인 실패</h3>
    <p>아이디 비밀번호를 확인해주세요</p>
</div>
</c:if>
<form:form action="${root }user/login_pro" method="post" modelAttribute="tempLoginUserBean">

 


- XML 프로젝트

1. JAVA 프로젝트와 같음

 

2. Bean을 Session Scope로 등록

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean class="com.example.beans.UserBean" id="loginUserBean" scope="session" />	
</beans>

 

** 자동 주입 오류 발생 시 **

loginUserBean은 Session Scope로 등록한 Bean이다.

Session Scope는 브라우저가 최초에 요청을 발생 시키는 시점이다.

@Autowired나 @Resource 어노테이션이 붙어있기 때문에 JAVA 프로젝트의 경우 최초 요청이 발생 될때 주입이 되는데, XML 프로젝트의 경우 서버 가동시 자동으로 주입하려고 시도하게 된다.

자동 주입 하려고 하는데 Bean이 Session Scope로 되어 있어서 오류가 발생 할 수 있다.

빈을 사용 해야 하는데 오류가 발생 할 경우 @Lazy 어노테이션으로 해결 할 수 있다.

@Lazy를 붙여줄 경우 서버 가동시 주입 하지 않고 브라우저가 최초 요청시 주입 해준다.

package com.example.controller;

...

@Controller
public class HomeController {
	
	@Resource(name = "loginUserBean")
	@Lazy
	private UserBean loginUserBean;

 

 

6. Mapper 설정

<?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="getLoginUserInfo" parameterType="com.example.beans.UserBean" resultType="com.example.beans.UserBean">
		<![CDATA[
			select user_idx, user_name 
			from user_table 
			where user_id = #{user_id} and user_pw = #{user_pw}
		]]>
	</select>

 

7. DAO 설정

package com.exmaple.dao;

...

@Repository
public class UserDao {
	
	@Autowired
	private SqlSessionTemplate sqlSessionTemplate;
	
	...
	
	public UserBean getLoginUserInfo(UserBean tempLoginUserBean) {
		return sqlSessionTemplate.selectOne("user.getLoginUserInfo", tempLoginUserBean);
	}

 

이하 내용은 JAVA 프로젝트와 동일 하다.

- JAVA 프로젝트

1. Mapper 생성

package com.example.mapper;

...

public interface UserMapper {
	
	...
    
	@Insert("INSERT INTO user_table(user_idx, user_name, user_id, user_pw) " +
			"VALUES (user_seq.nextval, #{user_name}, #{user_id}, #{user_pw})")
	void addUserInfo(UserBean joinUserBean);

 

2. DAO에서 매퍼 사용하기

package com.exmaple.dao;

...

@Repository
public class UserDao {
	
	@Autowired
	private UserMapper userMapper;
	
	...
	
	public void addUserInfo(UserBean joinUserBean) {
		userMapper.addUserInfo(joinUserBean);
	}

 

3. Service에서 dao 호출

package com.example.service;

...

@Service
public class UserService {
	
	@Autowired
	private UserDao userDao;
	
	...
	
	public void addUserInfo(UserBean joinUserBean) {
		userDao.addUserInfo(joinUserBean);
	}

 

4. 컨트롤러에서 Service 호출

Service를 주입 받고 서비스 메서드 호출

package com.example.controller;

...

@Controller
@RequestMapping("/user")
public class UserController {
	
	@Autowired
	private UserService userService;
	
	...
	
	@PostMapping("/join_pro")
	public String join(@Valid @ModelAttribute("joinUserBean") UserBean joinUserBean, BindingResult result) {
		if (result.hasErrors()) {
			return "user/join";
		}
		
		userService.addUserInfo(joinUserBean);
		
		return "user/join_success";
	}

 

5. views 에서 로그인 처리

<%@ 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("가입이 완료되었습니다");
	location.href="${root}user/login";
</script>

 

 

- XML 프로젝트

1. 매퍼 생성

<?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">

	...
	
	<insert id="addUserInfo" parameterType="com.example.beans.UserBean">
		<![CDATA[
			INSERT INTO user_table(user_idx, user_name, user_id, user_pw)
			VALUES (user_seq.nextval, #{user_name}, #{user_id}, #{user_pw})
		]]>	
	</insert>

 

2. DAO 에서 매퍼 사용

package com.exmaple.dao;

...

@Repository
public class UserDao {
	
	@Autowired
	private SqlSessionTemplate sqlSessionTemplate;
	
	...
	
	public void addUserInfo(UserBean joinUserBean) {
		sqlSessionTemplate.insert("user.addUserInfo", joinUserBean);
	}

 

3. Service, Controller, View 처리는 자바 프로젝트와 동일 하다.

 

 

 

 

+ Recent posts