[Spring 17-1] ๐ŸŒŸ์˜ˆ์™ธ ํด๋ž˜์Šค ๋ฐ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ• - ๋กœ๊ทธ์ธ ๋ฐ ํšŒ์›๊ฐ€์ž…

์ž„์Šนํ˜„ยท2023๋…„ 3์›” 2์ผ

Spring

๋ชฉ๋ก ๋ณด๊ธฐ
42/46

๐Ÿ’กKey Point๐Ÿ’ก

๐Ÿ“Œ@ExceptionHandler

๐Ÿ“ŒInterceptor ํด๋ž˜์Šค



๐ŸŒˆStep_1 ํ…Œ์ด๋ธ” ๋งŒ๋“ค๊ธฐ

๐Ÿ“ข๊ธฐ์กด์˜ USERINFO ํ…Œ์ด๋ธ” ์‚ฌ์šฉ
๐Ÿ“ข์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™” ์ž‘์—…

truncate table userinfo;

๐ŸŒˆStep_2 DTO ํด๋ž˜์Šค ์ƒ์„ฑ

๐Ÿ“ƒUserinfo.java

โ€ป xyz.itwill10.dto ํŒจํ‚ค์ง€์— Userinfo.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.dto;
//
import lombok.Data;
/*
์ด๋ฆ„       ๋„?       ์œ ํ˜•            
-------- -------- ------------- 
USERID   NOT NULL VARCHAR2(100) 
PASSWORD          VARCHAR2(100) 
NAME              VARCHAR2(200) 
EMAIL             VARCHAR2(300) 
STATUS            NUMBER(1) 
*/
@Data
public class Userinfo {
	private String userid;
	private String password;
	private String name;
	private String email;
	private int status;
}

๐ŸŒˆStep_3 ๋งคํผ ํŒŒ์ผ ์ƒ์„ฑ

๐Ÿ“ƒUserinfoMapper.xml

โ€ป xyz.itwill10.mapper ํŒจํ‚ค์ง€์— UserinfoMapper.xml ํŒŒ์ผ ์ƒ์„ฑ

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xyz.itwill10.mapper.UserinfoMapper">
	<!-- =============================================================================================== -->
	<insert id="insertUserinfo">
		insert into userinfo values(#{userid},#{password},#{name},#{email},#{status})
	</insert>
	<!-- =============================================================================================== -->
	<update id="updateUserinfo">
		update userinfo
		<set>
			<if test="password!=null and password!=''">
				password=#{password},
			</if>
			<if test="name!=null and name!=''">
				name=#{name},
			</if>
			<if test="email!=null and email!=''">
				email=#{email},
			</if>
			<if test="status==1 or status==9">
				status=#{status}
			</if>
		</set>
		where userid=#{userid}
	</update>
	<!-- =============================================================================================== -->
	<delete id="deleteUserinfo">
		delete from userinfo where userid=#{userid}
	</delete>
	<!-- =============================================================================================== -->
	<select id="selectUserinfo" resultType="Userinfo">
		select * from userinfo where userid=#{userid}
	</select>
	<!-- =============================================================================================== -->
	<select id="selectUserinfoList" resultType="Userinfo">
		select * from userinfo order by userid
	</select>
</mapper>

๐Ÿ“ƒUserinfoMapper.java(์ธํ„ฐํŽ˜์ด์Šค)

โ€ป xyz.itwill10.mapper ํŒจํ‚ค์ง€์— UserinfoMapper.java ์ธํ„ฐํŽ˜์ด์Šค ํŒŒ์ผ ์ƒ์„ฑ

package xyz.itwill10.mapper;
//
import java.util.List;
import xyz.itwill10.dto.Userinfo;
//
public interface UserinfoMapper {
	int insertUserinfo(Userinfo userinfo);
	int updateUserinfo(Userinfo userinfo);
	int deleteUserinfo(String userid);
	Userinfo selectUserinfo(String userid);
	List<Userinfo> selectUserinfoList();
}

๐ŸŒˆStep_4 DAO ํด๋ž˜์Šค ์ƒ์„ฑ

๐Ÿ“ƒUserinfoDAO.java(์ธํ„ฐํŽ˜์ด์Šค)

โ€ป xyz.itwill10.dao ํŒจํ‚ค์ง€์— UserinfoDAO.java ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ

package xyz.itwill10.dao;
//
import java.util.List;
import xyz.itwill10.dto.Userinfo;
//
public interface UserinfoDAO {
	int insertUserinfo(Userinfo userinfo);
	int updateUserinfo(Userinfo userinfo);
	int deleteUserinfo(String userid);
	Userinfo selectUserinfo(String userid);
	List<Userinfo> selectUserinfoList();
}

๐Ÿ“ƒUserinfoDAOImpl.java

โ€ป xyz.itwill10.dao ํŒจํ‚ค์ง€์— UserinfoDAOImpl.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.dao;
//
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dto.Userinfo;
import xyz.itwill10.mapper.UserinfoMapper;
//
@Repository
@RequiredArgsConstructor
public class UserinfoDAOImpl implements UserinfoDAO {
	private final SqlSession sqlSession;
	//
	@Override
	public int insertUserinfo(Userinfo userinfo) {
		return sqlSession.getMapper(UserinfoMapper.class).insertUserinfo(userinfo);
	}
	@Override
	public int updateUserinfo(Userinfo userinfo) {
		return sqlSession.getMapper(UserinfoMapper.class).updateUserinfo(userinfo);
	}
	@Override
	public int deleteUserinfo(String userid) {
		return sqlSession.getMapper(UserinfoMapper.class).deleteUserinfo(userid);
	}
	@Override
	public Userinfo selectUserinfo(String userid) {
		return sqlSession.getMapper(UserinfoMapper.class).selectUserinfo(userid);
	}
	@Override
	public List<Userinfo> selectUserinfoList() {
		return sqlSession.getMapper(UserinfoMapper.class).selectUserinfoList();
	}
}

๐ŸŒˆStep_5 ์˜ˆ์™ธ ํด๋ž˜์Šค ์ƒ์„ฑ

๐Ÿ“ƒExistsUserinfoException.java

โ€ป src/main/java ํด๋”์— xyz.itwill10.exception ํŒจํ‚ค์ง€ ์ƒ์„ฑ
โ€ป xyz.itwill10.exception ํŒจํ‚ค์ง€์— ExistsUserinfoException.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.exception;
//
import lombok.Getter;
import lombok.Setter;
import xyz.itwill10.dto.Userinfo;
//
//ํšŒ์›์ •๋ณด์— ๋Œ€ํ•œ ๋“ฑ๋ก ๋ช…๋ น์ด ์‹คํ–‰๋ ๋•Œ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๋ฐ›์•„ ์ „๋‹ฌ๋œ ํšŒ์›์ •๋ณด์˜ ์•„์ด๋””๊ฐ€ ์ด๋ฏธ ํšŒ์›์ •๋ณด์˜ ์•„์ด๋””๋กœ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ ๋ฐœ์ƒ๋˜์–ด ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์˜ˆ์™ธ ํด๋ž˜์Šค
@Getter
@Setter
public class ExistsUserinfoException extends Exception {
	private static final long serialVersionUID = 1L;
	//
	//์˜ˆ์™ธ ์ฒ˜๋ฆฌ์— ํ•„์š”ํ•œ ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ํ•„๋“œ
	//โ†’ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๋˜์–ด ์ „๋‹ฌ๋œ ํšŒ์›์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ํ•„๋“œ
	private Userinfo userinfo;
	//
	public ExistsUserinfoException() {//์ƒ์„ฑ์ž
		// TODO Auto-generated constructor stub
	}
	public ExistsUserinfoException(String message, Userinfo userinfo) {
		super(message);//๋ถ€๋ชจ?
		this.userinfo=userinfo;
	}
}

๐Ÿ“ƒUserinfoNotFoundException.java

โ€ป xyz.itwill10.exception ํŒจํ‚ค์ง€์— UserinfoNotFoundException.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.exception;
//
//ํšŒ์›์ •๋ณด์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ,์‚ญ์ œ,๊ฒ€์ƒ‰ ๋ช…๋ น์ด ์‹คํ–‰๋ ๋•Œ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์€ ์•„์ด๋””์˜ ํšŒ์›์ •๋ณด๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ๋ฐœ์ƒ๋˜์–ด ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์˜ˆ์™ธ ํด๋ž˜์Šค
public class UserinfoNotFoundException extends Exception {
	private static final long serialVersionUID = 1L;
	//
	public UserinfoNotFoundException() {//์ƒ์„ฑ์ž
		// TODO Auto-generated constructor stub
	}
	public UserinfoNotFoundException(String message) {
		super(message);
	}
}

๐Ÿ“ƒLoginAuthFailException.java

โ€ป xyz.itwill10.exception ํŒจํ‚ค์ง€์— LoginAuthFailException.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.exception;
//
import lombok.Getter;
import lombok.Setter;
//
//๋กœ๊ทธ์ธ์— ๋Œ€ํ•œ ์ธ์ฆ ๋ช…๋ น์ด ์‹คํ–‰๋ ๋•Œ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ „๋‹ฌ๋ฐ›์€ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ์— ๋Œ€ํ•œ ์ธ์ฆ ์‹คํŒจ๋œ ๊ฒฝ์šฐ ๋ฐœ์ƒ๋˜์–ด ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์˜ˆ์™ธ ํด๋ž˜์Šค
@Getter
@Setter
public class LoginAuthFailException extends Exception {
	private static final long serialVersionUID = 1L;
	//
	//์˜ˆ์™ธ์ฒ˜๋ฆฌ์— ํ•„์š”ํ•œ ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ํ•„๋“œ
	//โ†’ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ž…๋ ฅ๋˜์–ด ์ „๋‹ฌ๋œ ์•„์ด๋””๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ํ•„๋“œ
	private String userid;
	//
	public LoginAuthFailException() {//์ƒ์„ฑ์ž
		// TODO Auto-generated constructor stub
	}
	public LoginAuthFailException(String message, String userid) {
		super(message);
		this.userid=userid;
	}
}

๐ŸŒˆStep_6 Service ํด๋ž˜์Šค ์ƒ์„ฑ

๐Ÿ“ƒUserinfoService.java(์ธํ„ฐํŽ˜์ด์Šค)

โ€ป xyz.itwill10.service ํŒจํ‚ค์ง€์— UserinfoService.java ์ธํ„ฐํŽ˜์ด์Šค ํŒŒ์ผ ์ƒ์„ฑ

package xyz.itwill10.service;
//
import java.util.List;
import xyz.itwill10.dto.Userinfo;
import xyz.itwill10.exception.ExistsUserinfoException;
import xyz.itwill10.exception.LoginAuthFailException;
import xyz.itwill10.exception.UserinfoNotFoundException;
//
public interface UserinfoService {
	void addUserinfo(Userinfo userinfo) throws ExistsUserinfoException;
	void modifyUserinfo(Userinfo userinfo) throws UserinfoNotFoundException;//ํšŒ์›์ •๋ณด ๋ณ€๊ฒฝ
	void removeUserinfo(String userid) throws UserinfoNotFoundException;//ํšŒ์›์ •๋ณด ์‚ญ์ œ
	Userinfo getUserinfo(String userid) throws UserinfoNotFoundException;//ํšŒ์›์ •๋ณด ๊ฒ€์ƒ‰
	List<Userinfo> getUserinfoList();//ํšŒ์›๋ชฉ๋ก ๊ฒ€์ƒ‰
	Userinfo loginAuth(Userinfo userinfo) throws LoginAuthFailException;
}

๐Ÿ“ƒUserinfoServiceImpl.java

โ€ป xyz.itwill10.service ํŒจํ‚ค์ง€์— UserinfoServiceImpl.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.service;
//
import java.util.List;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dao.UserinfoDAO;
import xyz.itwill10.dto.Userinfo;
import xyz.itwill10.exception.ExistsUserinfoException;
import xyz.itwill10.exception.LoginAuthFailException;
import xyz.itwill10.exception.UserinfoNotFoundException;
//
//์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•
//1. jbcrypt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ”„๋กœ์ ํŠธ์— ๋นŒ๋“œ ์ฒ˜๋ฆฌ - ๋ฉ”์ด๋ธ : pom.xml
//2. BCrypt.hashpw(String password, String salt) ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„๋ฐ€๋ฒˆํ˜ธ์˜ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ
//โ†’ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฌธ์ž์—ด๊ณผ ์ฒจ๊ฐ€๋ฌผ์„ ์ „๋‹ฌ๋ฐ›์•„ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ - ์ฒจ๊ฐ€๋ฌผ์— ์˜ํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ๋ณ€ํ™˜
//โ†’ BCrypt ํด๋ž˜์Šค : BlowFish ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„๋œ ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค
//โ†’ BCrypt.gensalt(int log_bounds) : ์ฒจ๊ฐ€๋ฌผ(Salt - String)์˜ ๊ธธ์ด๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ์ฒจ๊ฐ€๋ฌผ์„ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ
//โ†’ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” ๋ฉ”์†Œ๋“œ๋กœ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ ์ฒจ๊ฐ€๋ฌผ์˜ ๊ธฐ๋ณธ ๊ธธ์ด๋Š” [10]์œผ๋กœ ์ž๋™ ์„ค์ •
//3. BCrypt.checkpw(String plaintext, String hashed)๋กœ ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•„ ์ฒ˜๋ฆฌ
//โ†’ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ๋น„๊ตํ•˜์—ฌ ๋‹ค๋ฅธ ๊ฒฝ์šฐ [false]๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฐ™์€ ๊ฒฝ์šฐ [true] ๋ฐ˜ํ™˜
//
//Service ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ๋Š” ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์‹œ ๋ฐœ์ƒ๋˜๋Š” ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ธ์œ„์  ์˜ˆ์™ธ ๋ฐœ์ƒ
//โ†’ ๋ฐœ์ƒ๋œ ์˜ˆ์™ธ๋Š” Controller ํด๋ž˜์Šค์—์„œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋˜๋„๋ก ์ „๋‹ฌ
@Service
@RequiredArgsConstructor
public class UserinfoServiceImpl implements UserinfoService {
	private final UserinfoDAO userinfoDAO;
	//
	@Transactional//์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ๋˜๋ฉด ์ž๋™์œผ๋กœ ๋กค๋ฐฑ์ฒ˜๋ฆฌ
	@Override
	public void addUserinfo(Userinfo userinfo) throws ExistsUserinfoException {
		//์ „๋‹ฌ๋ฐ›์€ ํšŒ์›์ •๋ณด์˜ ์•„์ด๋””๊ฐ€ ๊ธฐ์กด ํšŒ์›์ •๋ณด์˜ ์•„์ด๋””์™€ ์ค‘๋ณต๋œ ๊ฒฝ์šฐ
		if(userinfoDAO.selectUserinfo(userinfo.getUserid())!=null) {
			//์‚ฌ์šฉ์ž ์ •์˜ ์˜ˆ์™ธ ํด๋ž˜์Šค๋กœ ์ธ์œ„์  ์˜ˆ์™ธ ๋ฐœ์ƒ
			//โ†’ ์˜ˆ์™ธ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ณ  ์˜ˆ์™ธ์ฒ˜๋ฆฌ์‹œ ํ•„์š”๊ฐ’์„ ์ €์žฅํ•˜์—ฌ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ์˜ˆ์™ธ ํด๋ž˜์Šค ์ž‘์„ฑ
			throw new ExistsUserinfoException("์ด๋ฏธ ์‚ฌ์šฉ์ค‘์ธ ์•„์ด๋””๋ฅผ ์ž…๋ ฅ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.", userinfo);
		}
		//์ „๋‹ฌ๋ฐ›์€ ํšŒ์›์ •๋ณด์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌํ•˜์—ฌ ํ•„๋“œ๊ฐ’ ์ €์žฅ
		//โ†’ ์ „๋‹ฌ๋ฐ›์€ ํšŒ์›์ •๋ณด์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌํ•˜์—ฌ ํ•„๋“œ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋ช…๋ น์€ Controller ํด๋ž˜์Šค์˜ ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์—์„œ
		String hashedPassword=BCrypt.hashpw(userinfo.getPassword(), BCrypt.gensalt());
		userinfo.setPassword(hashedPassword);
		//
		userinfoDAO.insertUserinfo(userinfo);
	}
	//
	@Transactional
	@Override
	public void modifyUserinfo(Userinfo userinfo) throws UserinfoNotFoundException {
		//์ „๋‹ฌ๋ฐ”์€ ํšŒ์›์ •๋ณด์˜ ์•„์ด๋””๋กœ ๊ธฐ์กด ํšŒ์›์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
		if(userinfoDAO.selectUserinfo(userinfo.getUserid())==null) {
			throw new UserinfoNotFoundException("์•„์ด๋””์˜ ํšŒ์›์ •๋ณด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
		}
		//์ „๋‹ฌ๋ฐ›์€ ํšŒ์›์ •๋ณด์— ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์กด์žฌํ•  ๊ฒฝ์šฐ - ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ
		if(userinfo.getPassword()!=null && !userinfo.getPassword().equals("")) {
			String hashedPassword=BCrypt.hashpw(userinfo.getPassword(), BCrypt.gensalt());
			userinfo.setPassword(hashedPassword);
		}
		userinfoDAO.updateUserinfo(userinfo);//๋ณ€๊ฒฝ ์ฒ˜๋ฆฌ
	}
	//
	@Transactional
	@Override
	public void removeUserinfo(String userid) throws UserinfoNotFoundException {
		//์ „๋‹ฌ๋ฐ›์€ ์•„์ด๋””๋กœ ๊ธฐ์กด ํšŒ์›์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
		if(userinfoDAO.selectUserinfo(userid)==null) {
			throw new UserinfoNotFoundException("์•„์ด๋””์˜ ํšŒ์›์ •๋ณด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
		}
		userinfoDAO.deleteUserinfo(userid);
	}
	//
	@Override
	public Userinfo getUserinfo(String userid) throws UserinfoNotFoundException {
		//์ „๋‹ฌ๋ฐ›์€ ์•„์ด๋””๋กœ ๊ธฐ์กด ํšŒ์›์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•„ ์ €์žฅ
		Userinfo userinfo=userinfoDAO.selectUserinfo(userid);
		//๊ฒ€์ƒ‰๋œ ํšŒ์›์ •๋ณด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
		if(userinfo==null) {
			throw new UserinfoNotFoundException("์•„์ด๋””์˜ ํšŒ์›์ •๋ณด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
		}	
		return userinfo;
	}
	//
	@Override
	public List<Userinfo> getUserinfoList() {
		return userinfoDAO.selectUserinfoList();
	}
	//
	//ํšŒ์›์ •๋ณด๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ์ธ์ฆ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ - ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ๋œ ๊ฒฝ์šฐ ์ธ์ฆ ์‹คํŒจ
	//โ†’ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ธ์ฆ ์„ฑ๊ณต์œผ๋กœ ๊ฒ€์ƒ‰๋œ ํšŒ์›์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜
	@Override
	public Userinfo loginAuth(Userinfo userinfo) throws LoginAuthFailException {
		//์ „๋‹ฌ๋ฐ›์€ ํšŒ์›์ •๋ณด์˜ ์•„์ด๋””๋กœ ๊ธฐ์กด ํšŒ์›์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ๊ฒ€์ƒ‰๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•„ ์ €์žฅ
		Userinfo authUserinfo=userinfoDAO.selectUserinfo(userinfo.getUserid());
		//
		//๊ฒ€์ƒ‰๋œ ํšŒ์›์ •๋ณด๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ - ์•„์ด๋”” ์ธ์ฆ ์‹คํŒจ
		if(authUserinfo==null) {
			throw new LoginAuthFailException("์•„์ด๋””์˜ ํšŒ์›์ •๋ณด๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.", userinfo.getUserid());
		}
		//
		//์ „๋‹ฌ๋ฐ›์€ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๊ฒ€์ƒ‰๋œ ํšŒ์›์ •๋ณด์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๊ฐ™์ง€ ์•Š์€ ๊ฒฝ์šฐ - ๋น„๋ฐ€๋ฒˆํ˜ธ ์ธ์ฆ ์‹คํŒจ
		if(!BCrypt.checkpw(userinfo.getPassword(), authUserinfo.getPassword())) {
			throw new LoginAuthFailException("์•„์ด๋””๊ฐ€ ์—†๊ฑฐ๋‚˜ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋งž์ง€ ์•Š์Šต๋‹ˆ๋‹ค.", userinfo.getUserid());
		}
		return authUserinfo;
	}
}

๐ŸŒˆStep_7 Controller ํด๋ž˜์Šค ์ƒ์„ฑ

๐Ÿ“ƒUserinfoController.java

โ€ป xyz.itwill10.controller ํŒจํ‚ค์ง€์— UserinfoController.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.controller;
//
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import lombok.RequiredArgsConstructor;
import xyz.itwill10.dto.Userinfo;
import xyz.itwill10.exception.ExistsUserinfoException;
import xyz.itwill10.exception.LoginAuthFailException;
import xyz.itwill10.exception.UserinfoNotFoundException;
import xyz.itwill10.service.UserinfoService;
//
@Controller
@RequestMapping("/userinfo")
@RequiredArgsConstructor
public class UserinfoController {
	private final UserinfoService userinfoService;
	/*
	//ํšŒ์›๋“ฑ๋ก์„ ์œ„ํ•ด ํšŒ์›์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๋˜๋Š” ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•œ ๊ฒฝ์šฐ ์ธ์œ„์  ์˜ˆ์™ธ ๋ฐœ์ƒ
	//โ†’ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์— ์˜ํ•ด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ - ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” JSP ๋ฌธ์„œ๋กœ ํฌ์›Œ๋“œ ์ด๋™ํ•˜์—ฌ ์‘๋‹ต 
	@RequestMapping(value = "/write", method = RequestMethod.GET)
	public String write(HttpSession session) throws Exception {
		//์„ธ์…˜์— ์ €์žฅ๋œ ๊ถŒํ•œ ๊ด€๋ จ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•„ ์ €์žฅ
		Userinfo loginUserinfo=(Userinfo)session.getAttribute("loginUserinfo");
		if(loginUserinfo==null || loginUserinfo.getStatus()!=9) {
			throw new Exception("๋น„์ •์ƒ์ ์ธ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.");
		}
		return "userinfo/user_write";
	}
	*/
	//ํšŒ์›๋“ฑ๋ก์„ ์œ„ํ•ด ํšŒ์›์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๋˜๋Š” ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€ ์š”์ฒญํ•  ๊ฒฝ์šฐ ๊ถŒํ•œ ๊ด€๋ จ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ
	//โ†’ ๊ถŒํ•œ ๊ด€๋ จ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ด์šฉํ•  ๊ฒฝ์šฐ ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์—์„œ ๊ถŒํ•œ ๊ด€๋ จ ๋ช…๋ น ๋ฏธ์ž‘์„ฑ ๊ฐ€๋Šฅ
	@RequestMapping(value = "/write", method = RequestMethod.GET)
	public String write() {
		return "userinfo/user_write";
	}
	//
	/*
	//ํšŒ์›์ •๋ณด๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ USERINFO ํ…Œ์ด๋ธ”์— ์‚ฝ์ž…ํ•˜๊ณ  ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•œ URL ์ฃผ์†Œ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์š”์ฒญ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ UserinfoService ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ ๊ฐ€๋Šฅ(์•„์ด๋”” ์ค‘๋ณต) - try~catch ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
	@RequestMapping(value = "/write", method = RequestMethod.POST)
	public String write(@ModelAttribute Userinfo userinfo, Model model) {
		try {
			userinfoService.addUserinfo(userinfo);			
		} catch (ExistsUserinfoException e) {
			//ExistsUserinfoException ๊ฐ์ฒด์— ์ €์žฅ๋œ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์†์„ฑ๊ฐ’์œผ๋กœ ์ €์žฅ
			model.addAttribute("message", e.getMessage());
			//
			//ExistsUserinfoException ๊ฐ์ฒด์— ์ €์žฅ๋œ ํšŒ์›์ •๋ณด(์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’)๋ฅผ ์†์„ฑ๊ฐ’์œผ๋กœ ์ €์žฅ
			model.addAttribute("userinfo", userinfo);
			//์•„์ด๋”” ์ค‘๋ณต์œผ๋กœ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ๋œ ๊ฒฝ์šฐ ํšŒ์›์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜
			return "userinfo/user_write";
		}
		return "redirect:/userinfo/login";
	}
	*/
	//ํšŒ์›์ •๋ณด๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ USERINFO ํ…Œ์ด๋ธ”์— ์‚ฝ์ž…ํ•˜๊ณ  ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•œ URL ์ฃผ์†Œ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์š”์ฒญ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ UserinfoService ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์‹œ ์˜ˆ์™ธ ๋ฐœ์ƒ ๊ฐ€๋Šฅ - Front Controller์—๊ฒŒ ์˜ˆ์™ธ ์ „๋‹ฌ
	//โ†’ Front Controller๋Š” ์ „๋‹ฌ๋ฐ›์€ ์˜ˆ์™ธ๋กœ ์ธํ•ด 500 ์—๋Ÿฌ์ฝ”๋“œ ๋ฐœ์ƒํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌ 
	//โ†’ Front Controller๋Š” ํ•ด๋‹น ์˜ˆ์™ธ์— ๋Œ€ํ•œ ExceptionHandler ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ์ž‘์„ฑ๋œ ๊ฒฝ์šฐ ExceptionHandler ๊ธฐ๋Šฅ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
	@RequestMapping(value = "/write", method = RequestMethod.POST)
	public String write(@ModelAttribute Userinfo userinfo) throws ExistsUserinfoException {
		userinfoService.addUserinfo(userinfo);
		return "redirect:/userinfo/login";
	}
	//
	//๋กœ๊ทธ์ธ์„ ์œ„ํ•ด ์ธ์ฆ์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String login() throws Exception {
		return "userinfo/user_login";
	}
	//
	//์ธ์ฆ์ •๋ณด๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ํ›„ ํ™˜์˜ ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๊ธฐ ์œ„ํ•œ ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String login(@ModelAttribute Userinfo userinfo, HttpSession session) throws LoginAuthFailException {
		//์ธ์ฆ ์‹คํŒจ์‹œ LoginAuthFailException ๋ฐœ์ƒํ•˜๊ณ  ์ธ์ฆ ์„ฑ๊ณต์‹œ ๊ฒ€์ƒ‰๋œ ํšŒ์›์ •๋ณด ๋ฐ˜ํ™˜๋ฐ›์•„ ์ €์žฅ
		Userinfo authUserinfo=userinfoService.loginAuth(userinfo);
		//
		//์„ธ์…˜์— ๊ถŒํ•œ ๊ด€๋ จ ์ •๋ณด๋ฅผ ์†์„ฑ๊ฐ’์œผ๋กœ ์ €์žฅ
		session.setAttribute("loginUserinfo", authUserinfo);
		//
		return "userinfo/user_login";
	}
	//
	//๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌ ํ›„ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•œ URL ์ฃผ์†Œ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	@RequestMapping("/logout")
	public String login(HttpSession session) {
		//session.removeAttribute("loginUserinfo");
		session.invalidate();
		//
		return "redirect:/userinfo/login";
	}
	/*
	//USERINFO ํ…Œ์ด๋ธ”์— ์ €์žฅ๋œ ๋ชจ๋“  ํšŒ์›์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์†์„ฑ๊ฐ’์œผ๋กœ ์ €์žฅํ•˜์—ฌ ํšŒ์›๋ชฉ๋ก์„ ์ถœ๋ ฅํ•˜๋Š” ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•œ ๊ฒฝ์šฐ ์ธ์œ„์  ์˜ˆ์™ธ ๋ฐœ์ƒ - ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์— ์˜ํ•ด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
	@RequestMapping("/list")
	public String list(Model model, HttpSession session) throws Exception {
		Userinfo loginUserinfo=(Userinfo)session.getAttribute("loginUserinfo");
		if(loginUserinfo==null) {//๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•œ ๊ฒฝ์šฐ
			throw new Exception("๋น„์ •์ƒ์ ์ธ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.");//์ธ์œ„์  ์˜ˆ์™ธ ๋ฐœ์ƒ
		}
		//
		model.addAttribute("userinfoList", userinfoService.getUserinfoList());
		//
		return "userinfo/user_list";
	}
	*/
	//USERINFO ํ…Œ์ด๋ธ”์— ์ €์žฅ๋œ ๋ชจ๋“  ํšŒ์›์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์†์„ฑ๊ฐ’์œผ๋กœ ์ €์žฅํ•˜์—ฌ ํšŒ์›๋ชฉ๋ก์„ ์ถœ๋ ฅํ•˜๋Š” ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•  ๊ฒฝ์šฐ ๊ถŒํ•œ ๊ด€๋ จ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ  
	@RequestMapping("/list")
	public String list(Model model) {
		model.addAttribute("userinfoList", userinfoService.getUserinfoList());
		return "userinfo/user_list";
	}
	//
	//์•„์ด๋””๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ USERINFO ํ…Œ์ด๋ธ”์— ์ €์žฅ๋œ ํ•ด๋‹น ์•„์ด๋””์˜ ํšŒ์›์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์†์„ฑ๊ฐ’์œผ๋กœ ์ €์žฅํ•˜์—ฌ ํšŒ์›์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•  ๊ฒฝ์šฐ ๊ถŒํ•œ ๊ด€๋ จ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ
	@RequestMapping("/view")
	public String view(@RequestParam String userid, Model model) throws UserinfoNotFoundException {
		model.addAttribute("userinfo", userinfoService.getUserinfo(userid));
		return "userinfo/user_view";
	}
	//
	//์•„์ด๋””๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ USERINFO ํ…Œ์ด๋ธ”์— ์ €์žฅ๋œ ํ•ด๋‹น ์•„์ด๋””์˜ ํšŒ์›์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์†์„ฑ๊ฐ’์œผ๋กœ ์ €์žฅํ•˜์—ฌ ๋ณ€๊ฒฝํ•  ํšŒ์›์ •๋ณด๋ฅผ ์ž…๋ ฅ๋ฐ›๊ธฐ ์œ„ํ•œ ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๋˜๋Š” ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€ ์š”์ฒญํ•  ๊ฒฝ์šฐ ๊ถŒํ•œ ๊ด€๋ จ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ
	@RequestMapping(value = "/modify", method = RequestMethod.GET)
	public String modify(@RequestParam String userid, Model model) throws UserinfoNotFoundException {
		model.addAttribute("userinfo", userinfoService.getUserinfo(userid));
		return "userinfo/user_modify";
	}
	//
	//ํšŒ์›์ •๋ณด๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ USERINFO ํ…Œ์ด๋ธ”์— ์ €์žฅ๋œ ํšŒ์›์ •๋ณด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ํšŒ์›์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•œ URL ์ฃผ์†Œ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ ๋ณ€๊ฒฝ ์ฒ˜๋ฆฌ ํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์ธ ๊ฒฝ์šฐ ์„ธ์…˜์— ์ €์žฅ๋œ ๊ถŒํ•œ ๊ด€๋ จ ์ •๋ณด ๋ณ€๊ฒฝ 
	@RequestMapping(value="/modify", method = RequestMethod.POST)
	public String modify(@ModelAttribute Userinfo userinfo, HttpSession session) throws UserinfoNotFoundException {
		userinfoService.modifyUserinfo(userinfo);
		//
		Userinfo loginUserinfo=(Userinfo)session.getAttribute("loginUserinfo");
		//๋ณ€๊ฒฝ ์ฒ˜๋ฆฌ๋œ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์ธ ๊ฒฝ์šฐ
		if(loginUserinfo.getUserid().equals(userinfo.getUserid())) {
			session.setAttribute("loginUserinfo", userinfoService.getUserinfo(userinfo.getUserid()));
		}
		//
		return "redirect:/userinfo/view?userid="+userinfo.getUserid();
	}
	//
	//์•„์ด๋””๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ USERINFO ํ…Œ์ด๋ธ”์— ์ €์žฅ๋œ ํ•ด๋‹น ์•„์ด๋””์˜ ํšŒ์›์ •๋ณด๋ฅผ ์‚ญ์ œํ•˜๊ณ  ํšŒ์›๋ชฉ๋ก์„ ์ถœ๋ ฅํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๊ธฐ ์œ„ํ•œ URL ์ฃผ์†Œ๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ
	//โ†’ ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๋˜๋Š” ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€ ์š”์ฒญํ•  ๊ฒฝ์šฐ ๊ถŒํ•œ ๊ด€๋ จ ์ธํ„ฐ์…‰ํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌ
	@RequestMapping("/remove")
	public String remove(@RequestParam String userid, HttpSession session) throws UserinfoNotFoundException {
		userinfoService.removeUserinfo(userid);
		//
		Userinfo loginUserinfo=(Userinfo)session.getAttribute("loginUserinfo");
		//๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ญ์ œ๋œ ๊ฒฝ์šฐ
		if(loginUserinfo.getUserid().equals(userid)) {
			return "redirect:/userinfo/logout";
		}
		//
		return "redirect:/userinfo/list";
	}
	//
	//๋‚ด๊บผ๋งŒ ์ฒ˜๋ฆฌ
	//@ExceptionHandler : Controller ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ์— ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋„๋ก ์„ค์ •ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜
	//โ†’ Controller ํด๋ž˜์Šค์˜ ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒ๋˜์–ด Front Controller์—๊ฒŒ ์ „๋‹ฌ๋œ ๊ฒฝ์šฐ ์˜ˆ์™ธ ๊ด€๋ จ ๊ฐ์ฒด๋ฅผ ์ œ๊ณต๋ฐ›์•„ ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ
	//value ์†์„ฑ : ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํด๋ž˜์Šค(Class ๊ฐ์ฒด)๋ฅผ ์†์„ฑ๊ฐ’์œผ๋กœ ์„ค์ •
	//โ†’ ๋‹ค๋ฅธ ์†์„ฑ์ด ์—†๋Š” ๊ฒฝ์šฐ ์†์„ฑ๊ฐ’๋งŒ ์„ค์ • ๊ฐ€๋Šฅ
	//์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์—์„œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋ฐ›์•„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋ทฐ์ด๋ฆ„์„ ๋ฐ˜ํ™˜ํ•ด JSP ๋ฌธ์„œ๋กœ ์‘๋‹ต ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ - ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์ด๋™ ๊ฐ€๋Šฅ
	@ExceptionHandler(value = ExistsUserinfoException.class)
	public String userinfoExceptionHandler(ExistsUserinfoException exception, Model model) {
		model.addAttribute("message", exception.getMessage());
		model.addAttribute("userinfo",exception.getUserinfo());
		return "userinfo/user_write";
	}
	//
	@ExceptionHandler(LoginAuthFailException.class)
	public String userinfoExceptionHandler(LoginAuthFailException exception, Model model) {
		model.addAttribute("message", exception.getMessage());
		model.addAttribute("userid",exception.getUserid());
		return "userinfo/user_login";
	}
	//
	@ExceptionHandler(UserinfoNotFoundException.class)
	public String userinfoExceptionHandler(UserinfoNotFoundException exception) {
		return "userinfo/user_error";
	}
	//
	/*
	@ExceptionHandler(Exception.class)
	public String userinfoExceptionHandler() {
		return "userinfo/user_error";
	}
	*/
}

๐Ÿ“ข@ControllerAdvice

๐Ÿ“ƒExceptionController.java

โ€ป xyz.itwill10.controller ํŒจํ‚ค์ง€์— ExceptionController.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.controller;
//
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
//
//@ControllerAdvice : ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ๋งŒ ์ž‘์„ฑ๋œ Controller ํด๋ž˜์Šค๋ฅผ Spring Bean์œผ๋กœ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•œ ์–ด๋…ธํ…Œ์ด์…˜
//โ†’ ๋ชจ๋“  Controller ํด๋ž˜์Šค์˜ ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์—์„œ ๋ฐœ์ƒ๋˜์–ด ์ „๋‹ฌ๋œ ์˜ˆ์™ธ๋ฅผ ์ œ๊ณต๋ฐ›์•„ ์ฒ˜๋ฆฌ
@ControllerAdvice
public class ExceptionController {
	private static final Logger logger=LoggerFactory.getLogger(ExceptionController.class);
	//
	@ExceptionHandler(value = Exception.class)
	public String userinfoExceptionHandler(Exception exception) {
		exception.printStackTrace();
		logger.error(exception.getMessage());
		return "userinfo/user_error";
	}
}

๐ŸŒˆStep_8 JSP ์ž‘์„ฑ

๐Ÿ“ƒuser_write.jsp

โ€ป WEB-INF/views/userinfo ํด๋”์— user_write.jsp ์ž‘์„ฑ

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SPRING</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<c:url value="/css/user.css"/>" type="text/css">
<script language="JavaScript">
function userCreate() {
	if ( f.userid.value == "" ) {
		alert("์•„์ด๋””๋ฅผ ์ž…๋ ฅํ•˜์‹ญ์‹œ์š”.");
		f.userid.focus();
		return;
	} 
	if ( f.password.value == "" ) {
		alert("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์‹ญ์‹œ์š”.");
		f.password.focus();
		return;
	}
	if ( f.name.value == "" ) {
		alert("์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์‹ญ์‹œ์š”.");
		f.name.focus();
		return;
	}
	//
	f.action = "<c:url value="/userinfo/write"/>";
	f.submit();
}
</script>
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
	<tr>
	  <td width="20"></td>
	  <td style="color: red;">${message }</td>			
	</tr>
	<tr>
	  <td width="20"></td>
	  <td>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>ํšŒ์›๊ด€๋ฆฌ - ํšŒ์›๋“ฑ๋ก</b></td>
		  </tr>
	  </table>  
	  <br>
	  <form name="f" method="post">
	  <table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์•„์ด๋””</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:150" name="userid" value="${userinfo.userid }">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">๋น„๋ฐ€๋ฒˆํ˜ธ</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="password" style="width:150" name="password" value="${userinfo.password }">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์ด๋ฆ„</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:240" name="name" value="${userinfo.name }">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์ด๋ฉ”์ผ</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:240" name="email" value="${userinfo.email }">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">ํšŒ์›๋“ฑ๊ธ‰</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<select name="status">
					<option value="1" <c:if test="${userinfo.status == 1 }">selected</c:if>>์ผ๋ฐ˜ํšŒ์›</option>
					<option value="9" <c:if test="${userinfo.status == 9 }">selected</c:if>>๊ด€๋ฆฌ์ž</option>
				</select>
			</td>
		  </tr>		  
	  </table>
	  </form>
	  <br>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td align=center>
				<input type="button" value="ํšŒ์›๋“ฑ๋ก" onClick="userCreate();">
				<input type="button" value="๋กœ๊ทธ์ธ"token tag"><c:url value="/userinfo/login"/>';">
			</td>
		  </tr>
	  </table>
	  </td>
	</tr>
</table>  
</body>
</html>

๐Ÿ“ƒuser_error.jsp

โ€ป WEB-INF/views/userinfo ํด๋”์— user_error.jsp ์ž‘์„ฑ

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
<style type="text/css">
body {
	text-align: center;
}
.message {
	color: red;
	font-size: 1.5em;
}
</style>
</head>
<body>
	<h1>์—๋ŸฌํŽ˜์ด์ง€</h1>
	<hr>
	<p class="message">ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์— ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ ํ•˜์˜€๊ฑฐ๋‚˜ ๋น„์ •์ƒ์  ๋ฐฉ๋ฒ•์œผ๋กœ
	ํ”„๋กœ๊ทธ๋žจ์„ ์š”์ฒญํ•˜์—ฌ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.</p>
	<button type="button"token tag"><c:url value="/userinfo/login"/>';">๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ์ด๋™</button>
</body>
</html>

๐Ÿ“ƒuser_login.jsp

โ€ป WEB-INF/views/userinfo ํด๋”์— user_login.jsp ์ž‘์„ฑ

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SPRING</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<c:url value="/css/user.css"/>" type="text/css">
<script language="JavaScript">
function userLogin() {
	if ( f.userid.value == "" ) {
		alert("์•„์ด๋””๋ฅผ ์ž…๋ ฅํ•˜์‹ญ์‹œ์š”.");
		f.userid.focus();
		return;
	} 
	if ( f.password.value == "" ) {
		alert("๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์‹ญ์‹œ์š”.");
		f.password.focus();
		return;
	}	
	//
	f.action = "<c:url value="/userinfo/login"/>";
	f.submit();
}
</script>
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
	<tr>
	  <td width="20"></td>
	  <td style="color: red;">${message }</td>			
	</tr>
	<tr>
		<td width="20"></td>
		<td>
		  	<!--contents-->
			<table width=590 border=0 cellpadding=0 cellspacing=0>
				<tr>
					<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>ํšŒ์›๊ด€๋ฆฌ - ๋กœ๊ทธ์ธ</b></td>
				</tr>
			</table>
			<br>
		  	<c:choose>
			  	<c:when test="${empty(loginUserinfo) }"><%-- ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์ธ ๊ฒฝ์šฐ --%>
					<!-- login Form  -->
					<form name="f" method="post">
					<table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
						<tr>
							<td width=100 align=center bgcolor="E6ECDE" height="22">์‚ฌ์šฉ์ž ์•„์ด๋””</td>
							<td width=490 bgcolor="ffffff" style="padding-left:10px;">
								<input type="text" style="width:150" name="userid" value="${userid }">
							</td>
						</tr>
						<tr>
							<td width=100 align=center bgcolor="E6ECDE" height="22">๋น„๋ฐ€๋ฒˆํ˜ธ</td>
							<td width=490 bgcolor="ffffff" style="padding-left:10px;">
								<input type="password" style="width:150" name="password">
							</td>
						</tr>
					</table>
					</form>
					<br>
					<table width=590 border=0 cellpadding=0 cellspacing=0>
						<tr>
							<td align=center>
								<input type="button" value="๋กœ๊ทธ์ธ" onClick="userLogin();"> &nbsp;
							</td>
						</tr>
					</table>
				</c:when>
				<c:otherwise><%-- ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์ธ ๊ฒฝ์šฐ --%>
					<table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
						<tr>
							<td align=center bgcolor="E6ECDE" height="22">
								${loginUserinfo.name }๋‹˜, ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.
							</td>
						</tr>
					</table>
					<br>
					<table width=590 border=0 cellpadding=0 cellspacing=0>
						<tr>
							<td align=center>
								<button type="button"token tag"><c:url value="/userinfo/list"/>';">ํšŒ์›๋ชฉ๋ก</button>
								<button type="button"token tag"><c:url value="/userinfo/logout"/>';">๋กœ๊ทธ์•„์›ƒ</button>
								<c:if test="${loginUserinfo.status == 9 }">
									<button type="button"token tag"><c:url value="/userinfo/write"/>';">ํšŒ์›๋“ฑ๋ก</button>
								</c:if>
							</td>
						</tr>
					</table>
				</c:otherwise>
			</c:choose>
		</td>
	</tr>
</table>  
</body>
</html>

๐Ÿ“ƒuser_list.jsp

โ€ป WEB-INF/views/userinfo ํด๋”์— user_list.jsp ์ž‘์„ฑ

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SPRING</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<c:url value="/css/user.css"/>" type="text/css">
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
<tr>
	<td width="20"></td>
	<td>
	  	<table width=590 border=0 cellpadding=0 cellspacing=0>
		  	<tr>
				<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>ํšŒ์›๊ด€๋ฆฌ - ํšŒ์›๋ชฉ๋ก</b></td>
		  	</tr>
	  	</table>  
	  	<br>
	  	<table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  	<tr>
				<td width=190 align=center bgcolor="E6ECDE" height="22">์•„์ด๋””</td>
				<td width=200 align=center bgcolor="E6ECDE">์ด๋ฆ„</td>
				<td width=200 align=center bgcolor="E6ECDE">์ด๋ฉ”์ผ</td>
		  	</tr>
		  	<c:forEach var="userinfo" items="${userinfoList }">
			  	<tr>
					<td width=190 align=center bgcolor="ffffff" height="20">
						${userinfo.userid }
					</td>
					<td width=200 align=center bgcolor="ffffff">
						<a href="<c:url value="/userinfo/view"/>?userid=${userinfo.userid }" class="user">
							${userinfo.name }
						</a>
					</td>
					<td width=200 align=center bgcolor="ffffff">
						${userinfo.email }
					</td>
			  	</tr>
		  	</c:forEach>
	  	</table>
		<br>
	  	<table border="0" cellpadding="0" cellspacing="1" width="590">
			<tr>
				<td align="right">
					<c:if test="${loginUserinfo.status == 9 }">
						<input type="button" value="ํšŒ์›๋“ฑ๋ก"token tag"><c:url value="/userinfo/write"/>';"/>
					</c:if>
					<input type="button" value="๋กœ๊ทธ์•„์›ƒ"token tag"><c:url value="/userinfo/logout"/>';"/>
				</td>
			</tr>
		</table>		
	</td>
</tr>
</table>  
</body>
</html>

๐Ÿ“ƒuser_view.jsp

โ€ป WEB-INF/views/userinfo ํด๋”์— user_view.jsp ์ž‘์„ฑ

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SPRING</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<c:url value="/css/user.css"/>" type="text/css">
<script language="JavaScript">
function userRemove(userid) {
	if (confirm("์ •๋ง๋กœ ์‚ญ์ œ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?") ) {
		location.href='<c:url value="/userinfo/remove"/>?userid='+userid;
	}
}
</script>
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
	<tr>
	  <td width="20"></td>
	  <td>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>ํšŒ์›๊ด€๋ฆฌ - ํšŒ์›์ •๋ณด</b></td>
		  </tr>
	  </table>  
	  <br>
	  <table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์•„์ด๋””</td>
			<td width=490 bgcolor="ffffff"  style="padding-left:10px;">
				${userinfo.userid }
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์ด๋ฆ„</td>
			<td width=490 bgcolor="ffffff"  style="padding-left:10px;">
				${userinfo.name }
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์ด๋ฉ”์ผ</td>
			<td width=490 bgcolor="ffffff"  style="padding-left:10px;">
				${userinfo.email }
			</td>
		  </tr>		  
	  </table>
	  <br>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td align=center>
			<c:if test="${loginUserinfo.status == 9 }">
				<input type="button" value="์ˆ˜์ •"token tag"><c:url value="/userinfo/modify"/>?userid=${userinfo.userid}';">
				<input type="button" value="์‚ญ์ œ" onClick="userRemove('${userinfo.userid}');">
			</c:if>
			<input type="button" value="๋ชฉ๋ก"token tag"><c:url value="/userinfo/list"/>';"> 
			</td>
		  </tr>
	  </table>
	  </td>
	</tr>
</table>  
</body>
</html>

๐Ÿ“ƒuser_modify.jsp

โ€ป WEB-INF/views/userinfo ํด๋”์— user_modify.jsp ์ž‘์„ฑ

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SPRING</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href="<c:url value="/css/user.css"/>" type="text/css">
<script language="JavaScript">
function userModify() {
	if ( f.name.value == "" ) {
		alert("์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์‹ญ์‹œ์š”.");
		f.name.focus();
		return false;
	}
	f.action = "<c:url value="/userinfo/modify"/>";
	f.submit();
}
</script>
</head>
<body bgcolor=#FFFFFF text=#000000 leftmargin=0 topmargin=0 marginwidth=0 marginheight=0>
<br>
<table width=780 border=0 cellpadding=0 cellspacing=0>
	<tr>
	  <td width="20"></td>
	  <td>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td bgcolor="f4f4f4" height="22">&nbsp;&nbsp;<b>ํšŒ์›๊ด€๋ฆฌ - ํšŒ์›์ •๋ณด์ˆ˜์ •</b></td>
		  </tr>
	  </table>  
	  <br>
	  <form name="f" method="post">
	  <input type="hidden" name="userid" value="${userinfo.userid }">
	  <table border="0" cellpadding="0" cellspacing="1" width="590" bgcolor="BBBBBB">
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์•„์ด๋””</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				${userinfo.userid }
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">๋น„๋ฐ€๋ฒˆํ˜ธ</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="password" style="width:150" name="password">
				<span style="color: red;">** ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์ž…๋ ฅํ•˜์ง€ ๋งˆ์„ธ์š”. **</span>
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์ด๋ฆ„</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:240" name="name" value="${userinfo.name }">
			</td>
		  </tr>
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">์ด๋ฉ”์ผ ์ฃผ์†Œ</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<input type="text" style="width:240" name="email" value="${userinfo.email }">
			</td>
		  </tr>		  
		  <tr>
			<td width=100 align=center bgcolor="E6ECDE" height="22">ํšŒ์›๋“ฑ๊ธ‰</td>
			<td width=490 bgcolor="ffffff" style="padding-left:10px;">
				<select name="status">
					<option value="1" <c:if test="${userinfo.status == 1 }">selected</c:if>>์ผ๋ฐ˜ํšŒ์›</option>
					<option value="9" <c:if test="${userinfo.status == 9 }">selected</c:if>>๊ด€๋ฆฌ์ž</option>
				</select>
			</td>
		  </tr>	
	  </table>
	  </form>
	  <br>
	  <table width=590 border=0 cellpadding=0 cellspacing=0>
		  <tr>
			<td align=center>
			<input type="button" value="์ˆ˜์ •" onClick="userModify();">
			<input type="button" value="๋ชฉ๋ก"token tag"><c:url value="/userinfo/list"/>';">
			</td>
		  </tr>
	  </table>
	  </td>
	</tr>
</table>  
</body>
</html>

๐Ÿง์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•

โ‘ jbcrypt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ”„๋กœ์ ํŠธ์— ๋นŒ๋“œ ์ฒ˜๋ฆฌ - ๋ฉ”์ด๋ธ : pom.xml

๐Ÿ“ƒpom.xml

<!-- https://mvnrepository.com/artifact/org.mindrot/jbcrypt -->
<!-- โ†’ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ -->
<dependency>
    <groupId>org.mindrot</groupId>
    <artifactId>jbcrypt</artifactId>
    <version>0.4</version>
</dependency>

โ‘กBCrypt.hashpw(String password, String salt) ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„๋ฐ€๋ฒˆํ˜ธ์˜ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ
โ†’ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฌธ์ž์—ด๊ณผ ์ฒจ๊ฐ€๋ฌผ์„ ์ „๋‹ฌ๋ฐ›์•„ ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ - ์ฒจ๊ฐ€๋ฌผ์— ์˜ํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋‹ค๋ฅด๊ฒŒ ๋ณ€ํ™˜
โ†’ BCrypt ํด๋ž˜์Šค : BlowFish ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„๋œ ๋‹จ๋ฐฉํ–ฅ ์•”ํ˜ธํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค
โ†’ BCrypt.gensalt(int log_bounds) : ์ฒจ๊ฐ€๋ฌผ(Salt - String)์˜ ๊ธธ์ด๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ์ฒจ๊ฐ€๋ฌผ์„ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์†Œ๋“œ
โ†’ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์—†๋Š” ๋ฉ”์†Œ๋“œ๋กœ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ ์ฒจ๊ฐ€๋ฌผ์˜ ๊ธฐ๋ณธ ๊ธธ์ด๋Š” [10]์œผ๋กœ ์ž๋™ ์„ค์ •

โ‘ขBCrypt.checkpw(String plaintext, String hashed)๋กœ ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋น„๊ตํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•„ ์ฒ˜๋ฆฌ
โ†’ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„ ๋น„๊ตํ•˜์—ฌ ๋‹ค๋ฅธ ๊ฒฝ์šฐ [false]๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฐ™์€ ๊ฒฝ์šฐ [true] ๋ฐ˜ํ™˜

๐ŸงInterceptor ํด๋ž˜์Šค

โ€ป src/main/java ํด๋”์— xyz.itwill10.util ํŒจํ‚ค์ง€ ์ƒ์„ฑ

๐Ÿ“ข๊ด€๋ฆฌ์ž ๊ด€๋ จ ๊ถŒํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ž‘์„ฑ๋œ Interceptor ํด๋ž˜์Šค

๐Ÿ“ƒAdminAuthInterceptor.java

โ€ป xyz.itwill10.util ํŒจํ‚ค์ง€์— AdminAuthInterceptor.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.util;
//
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import xyz.itwill10.dto.Userinfo;
//
//Interceptor ํด๋ž˜์Šค : Front Controller์— ์˜ํ•ด ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ์‹คํ–‰๋˜๊ธฐ ์ „ ๋˜๋Š” ํ›„์— ์‚ฝ์ž…๋˜์–ด ์‹คํ–‰๋  ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค
//โ†’ Interceptor ํด๋ž˜์Šค๋Š” ๋ฐ˜๋“œ์‹œ HandlerInterceptor ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›์•„ ์ž‘์„ฑ - ํ•„์š”ํ•œ ๋ฉ”์†Œ๋“œ๋งŒ ์˜ค๋ฒ„๋ผ์ด๋“œ ์„ ์–ธํ•ด์„œ ์ž‘์„ฑ
//โ†’ Spring Bean Configuration File(servlet-context.xml)์— Spring Bean์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ์ „ํ›„์— ์ธํ„ฐ์…‰ํ„ฐ๊ฐ€ ๋™์ž‘๋  ์ˆ˜ ์žˆ๋„๋ก ํ™˜๊ฒฝ ์„ค์ •
//
//๊ด€๋ฆฌ์ž ๊ด€๋ จ ๊ถŒํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ž‘์„ฑ๋œ Interceptor ํด๋ž˜์Šค
//โ†’ ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ๋ช…๋ น ์‹คํ–‰ ์ „์— ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์ด๊ฑฐ๋‚˜ ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•œ ๊ฒฝ์šฐ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํŽ˜์ด์ง€์˜ URL ์ฃผ์†Œ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ธฐ๋Šฅ ์ œ๊ณต
public class AdminAuthInterceptor implements HandlerInterceptor {
	//preHandle : ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ๋ช…๋ น์ด ์‹คํ–‰๋˜๊ธฐ ์ „์— ์‹คํ–‰๋  ๋ช…๋ น์„ ์ž‘์„ฑํ•˜๋Š” ๋ฉ”์†Œ๋“œ
	//โ†’ false ๋ฐ˜ํ™˜ : ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ๋ช…๋ น ๋ฏธ์‹คํ–‰
	//โ†’ true ๋ฐ˜ํ™˜ : ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ๋ช…๋ น ์‹คํ–‰
	//โ†’ ๊ถŒํ•œ ๊ด€๋ จ ๋ช…๋ น์„ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HttpSession session=request.getSession();//์„ธ์…˜ ๊ฐ์ฒด ๋ฐ˜ํ™˜
		//
		Userinfo loginUserinfo=(Userinfo)session.getAttribute("loginUserinfo");
		//
		//๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์ด๊ฑฐ๋‚˜ ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž์ธ ๊ฒฝ์šฐ
		if(loginUserinfo==null || loginUserinfo.getStatus()!=9) {
			//๋ฐฉ๋ฒ•1
			//request.getRequestDispatcher("userinfo/user_error.jsp").forward(request, response);
			//return false;//๊ถŒํ•œ์ด ์—†๋Š” ๊ฒฝ์šฐ ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ ๋ฏธํ˜ธ์ถœ
			//
			//๋ฐฉ๋ฒ•2
			throw new Exception("๋น„์ •์ƒ์ ์ธ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.");//์ธ์œ„์  ์˜ˆ์™ธ ๋ฐœ์ƒ - ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ๋กœ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
		}
		return true;//๊ถŒํ•œ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
	}
	//
	//postHandle : ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ๋ช…๋ น์ด ์‹คํ–‰๋˜๊ณ  ๋ทฐ๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ์ „์— ์‹คํ–‰๋  ๋ช…๋ น์„ ์ž‘์„ฑํ•˜๋Š” ๋ฉ”์†Œ๋“œ
	//โ†’ ModelAndView ๊ฐ์ฒด๋ฅผ ์ œ๊ณต๋ฐ›์•„ ViewName ๋˜๋Š” Model ๊ฐ์ฒด์˜ ์†์„ฑ๊ฐ’ ๋ณ€๊ฒฝํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}
	//
	//afterCompletion : ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ๋ช…๋ น์ด ์‹คํ–‰๋˜๊ณ  ๋ทฐ์—์„œ ์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ์ด ์ƒ์„ฑ๋œ ํ›„ ์‹คํ–‰๋  ๋ช…๋ น์„ ์ž‘์„ฑํ•˜๋Š” ๋ฉ”์†Œ๋“œ
	//โ†’ ์‘๋‹ต ๊ฒฐ๊ณผ๋ฅผ ๋ณ€๊ฒฝํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}
}

๐Ÿ“ƒLoginAuthInterceptor.java

โ€ป xyz.itwill10.util ํŒจํ‚ค์ง€์— LoginAuthInterceptor.java ํด๋ž˜์Šค ์ƒ์„ฑ

package xyz.itwill10.util;
//
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
import xyz.itwill10.dto.Userinfo;
//
//๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๊ด€๋ จ ๊ถŒํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ์ž‘์„ฑ๋œ Interceptor ํด๋ž˜์Šค
//โ†’ ์š”์ฒญ ์ฒ˜๋ฆฌ ๋ฉ”์†Œ๋“œ์˜ ๋ช…๋ น ์‹คํ–‰ ์ „์— ๋น„๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž์ด๊ฑฐ๋‚˜ ๊ด€๋ฆฌ์ž๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•œ ๊ฒฝ์šฐ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ํŽ˜์ด์ง€์˜ URL ์ฃผ์†Œ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ธฐ๋Šฅ ์ œ๊ณต
public class LoginAuthInterceptor implements HandlerInterceptor {
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		HttpSession session=request.getSession();
		Userinfo loginUserinfo=(Userinfo)session.getAttribute("loginUserinfo");
		if(loginUserinfo==null) {
			throw new Exception("๋น„์ •์ƒ์ ์ธ ์š”์ฒญ์ž…๋‹ˆ๋‹ค.");
		}
		//
		return true;
	}
}

๐Ÿ“ƒservlet-context.xml

โ€ป WEB-INF/spring/appServlet ํด๋”์— ์žˆ๋Š” servlet-context.xml ์ˆ˜์ •

<!-- Interceptor ๊ด€๋ จ ํด๋ž˜์Šค๋ฅผ Spring Bean์œผ๋กœ ๋“ฑ๋ก -->
<beans:bean class="xyz.itwill10.util.AdminAuthInterceptor" id="adminAuthInterceptor"/>
<beans:bean class="xyz.itwill10.util.LoginAuthInterceptor" id="loginAuthInterceptor"/>
<!-- interceptors : interceptor ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•œ ์—˜๋ฆฌ๋จผํŠธ -->
<interceptors>
	<!-- interceptor : ์ธํ„ฐ์…‰ํ„ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•œ ๊ทœ์น™์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•œ ์—˜๋ฆฌ๋จผํŠธ -->
	<interceptor>
		<!-- mapping : ์ธํ„ฐ์…‰ํ„ฐ๊ฐ€ ๋™์ž‘๋  ์š”์ฒญ ํŽ˜์ด์ง€์˜ URL ์ฃผ์†Œ๋ฅผ ์„ค์ •ํ•˜๋Š” ์—˜๋ฆฌ๋จผํŠธ -->
		<!-- path ์†์„ฑ : ์š”์ฒญ URL ์ฃผ์†Œ๋ฅผ ์†์„ฑ๊ฐ’์œผ๋กœ ์„ค์ • -->
		<mapping path="/userinfo/write"/>
		<mapping path="/userinfo/modify"/>
		<mapping path="/userinfo/remove"/>
		<!-- ref : ์ธํ„ฐ์…‰ํ„ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ๊ฐ์ฒด(Spring Bean)๋ฅผ ์„ค์ •ํ•˜๋Š” ์—˜๋ฆฌ๋จผํŠธ -->
		<!-- bean ์†์„ฑ : Spring Bean์˜ ์‹๋ณ„์ž(beanName)๋ฅผ ์†์„ฑ๊ฐ’์œผ๋กœ ์„ค์ • -->
		<beans:ref bean="adminAuthInterceptor"/>
	</interceptor>
	<interceptor>
		<!-- ์ธํ„ฐ์…‰ํ„ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•  ์š”์ฒญ URL ์ฃผ์†Œ์—๋Š” [*] ํŒจํ„ด๋ฌธ์ž ์‚ฌ์šฉ ๊ฐ€๋Šฅ -->
		<!-- โ†’ * : ํ˜„์žฌ ํด๋”์˜ ์š”์ฒญ ํŽ˜์ด์ง€, ** : ํ˜„์žฌ ํด๋” ๋ฐ ํ•˜์œ„ ํด๋” -->
		<!-- <mapping path="/*"/> -->
		<!-- <mapping path="/**"/> -->
		<!-- <mapping path="/userinfo/*"/> -->
		<!-- exclude-mapping : ์ธํ„ฐ์…‰ํ„ฐ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•œ ์š”์ฒญ URL ์ฃผ์†Œ๋ฅผ ์„ค์ •ํ•˜๋Š” ์—˜๋ฆฌ๋จผํŠธ -->
		<!-- <exclude-mapping path="/userinfo/login"/> -->
		<!--                                                                          -->
		<mapping path="/userinfo/list"/>
		<mapping path="/userinfo/view"/>
		<beans:ref bean="loginAuthInterceptor"/>
	</interceptor>
</interceptors>

0๊ฐœ์˜ ๋Œ“๊ธ€