create table userinfo(userid varchar2(100) primary key, password varchar2(100), name varchar2(200), email varchar2(300), status number(1));
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;
}
<?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>
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();
}
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();
}
package xyz.itwill10.dao;
@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();
}
}
Service 클래스의 메소드는 데이터 처리시 발생되는 문제에 대한 인위적 예외 발생
사용자 정의 예외 클래스로 인위적 예외 발생
회원정보에 대한 등록 명령이 실행될때 사용자로부터 입력받아 전달된 회원정보의 아이디가 이미 회원정보의 아이디로 존재하는 경우 발생되어 처리하기 위한 예외 클래스
예외처리에 필요한 값을 저장하기 위한 필드
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);//message를 전달받아 부모(Exception)에게 전달하겠다
this.userinfo=userinfo;
}
}
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);
}
}
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;
}
}
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;
}
<!-- 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) 메소드를 호출하여 비밀번호의 암호화 처리
String hashedPassword=BCrypt.hashpw(userinfo.getPassword(), BCrypt.gensalt());
BCrypt.checkpw(String plaintext, String hashed)로 암호화된 비밀번호를 비교하여 결과를 반환받아 처리
Service 클래스의 메소드는 데이타 처리시 발생되는 문제에 대한 인위적 예외 발생
사용자 정의 예외 클래스로 인위적 예외 발생
package xyz.itwill10.service;
//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;
}
}
Interceptor 클래스 : Front Controller에 의해 요청 처리 메소드가 호출되어 실행되기 전 또는 후에 삽입되어 실행될 기능을 제공하는 클래스
filter (was에 의해 관리) → front controller → interceptor (front controller가 관리) → 요청처리메소드
Interceptor 관련 클래스를 Spring Bean으로 등록
interceptor : 인터셉터 기능을 제공하기 위한 규칙을 설정하는 엘리먼트
<mapping path="/userinfo/write"/>
<beans:ref bean="adminAuthInterceptor"/>
인터셉터 기능을 제공할 요청 URL 주소에는 [ * ] 패턴문자 사용 가능
<mapping path="/**"/>
<exclude-mapping path="/userinfo/login"/>
<!-- 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>
관리자 관련 권한 처리를 위해 작성된 Interceptor 클래스
- preHandle : 요청 처리 메소드의 명령이 실행되기 전에 실행될 명령을 작성하는 메소드
- false 반환 : 요청 처리 메소드의 명령 미실행, true 반환 : 요청 처리 메소드의 명령 실행
- 권한 관련 명령을 작성하기 위한 메소드
- postHandle : 요청 처리 메소드의 명령이 실행되고 뷰가 생성되기 전에 실행될 명령을 작성하는 메소드
- ModelAndView 객체를 제공받아 ViewName 또는 Model 객체의 속성값 변경할 경우 사용
- afterCompletion : 요청 처리 메소드의 명령이 실행되고 뷰에서 의해 최종 결과물이 생성된 후 실행될 명령을 작성하는 메소드
- 응답 결과를 변경할 경우 사용
package xyz.itwill10.util;
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) {
//request.getRequestDispatcher("userinfo/user_error.jsp").forward(request, response);
//return false;//권한이 없는 경우 요청 처리 메소드 미호출
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);
}
}
로그인 사용자 관련 권한 처리를 위해 작성된 Interceptor 클래스
package xyz.itwill10.util;
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;
}
}
- @Controller : 요청 처리 클래스를 Spring Bean으로 등록하기 위한 어노테이션
- @RequestMapping 어노테이션으로 다수의 요청 처리 메소드를 작성하여 클라이언트의 요청에 대한 처리 가능
회원등록을 위해 회원정보를 입력받기 위한 뷰이름을 반환하는 요청 처리 메소드 (GET방식)
회원정보를 전달받아 USERINFO 테이블에 삽입하고 로그인 페이지를 요청하기 위한 URL 주소를 클라이언트에게 전달하는 요청 처리 메소드 (POST방식)
로그인을 위해 인증정보를 입력받기 위한 뷰이름을 반환하는 요청 처리 메소드 (write-GET방식)
인증정보를 전달받아 로그인 처리 후 환영 메세지를 출력하기 위한 뷰이름을 반환하는 요청 처리 메소드 (write-POST방식)
로그아웃 처리 후 로그인 페이지를 요청하기 위한 URL 주소를 클라이언트에게 전달하는 요청 처리 메소드 (logout)
회원정보를 전달받아 USERINFO 테이블에 저장된 회원정보를 변경하고 회원정보를 출력하는 페이지를 요청하기 위한 URL 주소를 클라이언트에게 전달하는 요청 처리 메소드
아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보를 삭제하고 회원목록을 출력하는 페이지를 요청하기 위한 URL 주소를 클라이언트에게 전달하는 요청 처리 메소드
USERINFO 테이블에 저장된 모든 회원정보를 검색하여 속성값으로 저장하여 회원목록을 출력하는 뷰이름을 반환하는 요청 처리 메소드 (list)
아이디를 전달받아 USERINFO 테이블에 저장된 해당 아이디의 회원정보를 검색하여 속성값으로 저장하여 회원정보를 출력하는 뷰이름을 반환하는 요청 처리 메소드 (view)
- @ExceptionHandler : 메소드에 예외 처리 기능을 제공하도록 설정하는 어노테이션
- Controller 클래스의 요청 처리 메소드에서 예외가 발생되어 Front Controller에게 전달된 경우 예외 관련 객체를 제공받아 예외 처리하기 위한 메소드 (ExceptionHandler Mothod)
- value 속성 : 예외 처리하기 위한 클래스(Class 객체)를 속성값으로 설정
- 다른 속성이 없는 경우 속성값만 설정 가능
- 예외 처리 메소드에서 예외 처리를 위해 필요한 객체를 매개변수로 전달받아 사용 가능하며 뷰이름을 반환해 JSP 문서로 응답 처리 가능 (리다이렉트 이동 가능)
package xyz.itwill10.controller;
@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() {
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 클래스의 요청 처리 메소드에서 예외가 발생되어 Front Controller에게 전달된
//경우 예외 관련 객체를 제공받아 예외 처리하기 위한 메소드 - ExceptionHandler Mothod
//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";
}
*/
}
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
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";
}
}
href="<c:url value="/css/user.css"/>"
<%@ 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"> <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>
<%@ 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"> <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();">
</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>
<%@ 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>
<%@ 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"> <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>
<%@ 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"> <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>
<%@ 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"> <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>