728x90
반응형
UserDao.java
package dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import dao.mapper.UserMapper;
import logic.User;
@Repository
public class UserDao {
@Autowired //객체 주입. DI
private SqlSessionTemplate template;
private Map<String,Object> param = new HashMap<String,Object>();
private Class<UserMapper> cls = UserMapper.class;
public void insert(User user) {
template.getMapper(cls).insert(user);
}
public User selectOne(String userid) {
param.clear();
param.put("userid", userid);
return template.getMapper(cls).selectOne(userid);
}
public void update(User user) {
template.getMapper(cls).update(user);
}
public void passwordupdate(String userid, String chgpass) {
param.clear();
param.put("userid", userid);
param.put("password", chgpass);
template.getMapper(cls).passwordupdate(param);
}
public void delete(String userid) {
param.clear();
param.put("userid", userid);
template.getMapper(cls).delete(userid);
}
public List<User> list() {
return template.getMapper(cls).select();
}
public String search(User user, String url) {
param.clear();
param.put("email", user.getEmail());
param.put("phoneno", user.getPhoneno());
if(url.equals("id")) { //아이디 찾기
param.put("col", "substr(userid, 1, length(userid) -2) || '**'");
}
else if(url.equals("pw")) { //비밀번호 찾기
param.put("userid", user.getUserid());
param.put("col", "'**' || substr(password, 3, length(password) -2)");
}
return template.getMapper(cls).search(param);
}
}
UserMapper.java
package dao.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import logic.User;
public interface UserMapper {
@Insert("insert into useraccount "
+ " (userid, password, username, phoneno, postcode, address, email, birthday)"
+ " values (#{userid}, #{password}, #{username}, #{phoneno}, #{postcode}, #{address}, #{email}, #{birthday})")
void insert(User user);
@Select("select * from useraccount where userid=#{value}")
User selectOne(String userid);
@Update("update useraccount set username=#{username}, birthday=#{birthday}, "
+ " phoneno=#{phoneno}, postcode=#{postcode}, address=#{address}, email=#{email} "
+ " where userid=#{userid}")
void update(User user);
@Update("update useraccount set password= #{password} where userid=#{userid}")
void passwordupdate(Map<String, Object> param);
@Delete("delete from useraccount where userid=#{userid}")
void delete(String userid);
@Select("select * from useraccount")
List<User> select();
@Select({"<script>",
"select ${col} from useraccount",
"<trim prefix='where' prefixOverrides='AND||OR'>"
+ "<if test='userid != null'> and userid=#{userid}</if>"
+ "and email=#{email} and phoneno=#{phoneno}</trim>",
"</script>"})
String search(Map<String, Object> param);
}
UserController.java
package controller;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import exception.LoginException;
import logic.Sale;
import logic.ShopService;
import logic.User;
@Controller
@RequestMapping("user")
public class UserController {
@Autowired
private ShopService service;
//@GetMapping : Get 방식 요청인 경우
//@PostMapping : Post 방식 요청인 경우
//@RequestMapping : Get/Post 방식 상관없이 모든 요청
//http://localhost:8088/springmvc1/user/userEntry
@GetMapping("*") //그 외 모든 Get 방식요청
public ModelAndView getUser() {
ModelAndView mav = new ModelAndView();
mav.addObject(new User());
return mav; // /WEB-INF/view/user/userEntry.jsp 뷰로 설정
}
@PostMapping("userEntry") // POST 방식으로 user/userEntry url 요청시
public ModelAndView userEntry(@Valid User user, BindingResult bresult) {
ModelAndView mav = new ModelAndView();
if(bresult.hasErrors()) {
mav.getModel().putAll(bresult.getModel());
//reject : 뷰의 globalErrors의 내용으로 저장
bresult.reject("error.input.user");
return mav; // /WEB-INF/view/user/userEntry.jsp
}
try {
service.userInsert(user);
mav.addObject("user", user);
//userid가 기본키 설정됨. userid 중복된 경우 예외 발생
} catch(DataIntegrityViolationException e) {
e.printStackTrace();
bresult.reject("error.duplicate.user");
mav.getModel().putAll(bresult.getModel());
return mav;
}
mav.setViewName("redirect:login");
return mav;
}
/* 로그인 - POST 방식 요청
* 1. 유효성검증
* User객체에 저장된 파라미터값을 이용하여 유효성검증.
* 2. 입력받은 userid,password 로 db에서 해당 정보를 읽기.
* - userid가 없는 경우
* - password가 틀린 경우
* - 정상적인 사용자인경우 : session에 로그인 정보 등록하기
*/
@PostMapping("login") // POST 방식으로 user/userEntry url 요청시
public ModelAndView login(@Valid User user, BindingResult bresult, HttpSession session) {
ModelAndView mav = new ModelAndView();
if(bresult.hasErrors()) {
mav.getModel().putAll(bresult.getModel());
bresult.reject("error.input.login");
return mav;
}
//dbuser : userid에 해당하는 db의 레코드 값 저장
User dbUser = service.userSelectOne(user.getUserid());
if (dbUser == null) {
bresult.reject("error.login.id");
mav.getModel().putAll(bresult.getModel());
return mav;
}
if(user.getPassword().equals(dbUser.getPassword())){
session.setAttribute("loginUser", dbUser);
} else {
bresult.reject("error.login.password");
mav.getModel().putAll(bresult.getModel());
return mav;
}
mav.setViewName("redirect:mypage?id=" + user.getUserid());
return mav;
}
//loginCheck * 로 시작하는 메서드명이 실행시 로그인 여부 검증하기 => AOP사용
@RequestMapping("logout")
public String loginChecklogout(HttpSession session) {
session.invalidate();
return "redirect:login"; //view 리턴
}
// http://localhost:8088/springmvc1/user/main
// http://localhost:8088/springmvc1/user/password
/*
* 1. 로그인필요
* 2.password.jsp 페이지 출력
*/
@GetMapping({"main","password"})
public String loginCheckmain(HttpSession session) {
return null; //url과 같은 이름의 view 리턴 : user/main.jsp or user/password.jsp
}
// @GetMapping("password")
// public String loginCheckpassword(HttpSession session) {
// return null; //url과 같은 이름의 view 리턴 : user/main.jsp
// }
/*
* AOP 설정하기 : UserLoginAspect 클래스의 userIdCheck 메서드로 구현하기.
* 1. pointcut : UserController 클래스의 idCheck로 시작하는 메서드이면서 마지막 매개변수가 id, session인 경우
* 2. 로그인 여부 검증. 로그인이 안된 경우 "로그인 후 거래하세요." 메세지 출력하고 login페이지 호출.
* 3. admin이 아니면서, 로그인 아이디와 id값이 다른 경우 "본인 정보만 거래 가능합니다." 메세지 출력하고 main페이지 호출.
*/
@RequestMapping("mypage")
public ModelAndView idCheckmypage(String id, HttpSession session) {
ModelAndView mav = new ModelAndView();
//1. db에서 id 해당하는 User 객체조회
User user = service.userSelectOne(id);
//2. 주문목록 조회
//salelist : 주문목록, 주문번호별 주문상품목록, 주문상품별 상품정보 저장
List<Sale> salelist = service.salelist(id);
mav.addObject("user", user);
mav.addObject("salelist", salelist);
return mav;
}
@GetMapping({"update","delete"})
public ModelAndView idCheckupdate(String id, HttpSession session) {
ModelAndView mav = new ModelAndView();
User user = service.userSelectOne(id);
mav.addObject("user", user);
return mav;
}
/*
* 1. 유효성 검증하기.
* 2. 비밀번호 검증
* - 비밀번호 오류 : error.login.password 코드를 입력하여, update.jsp 페이지로 이동.
* 3. userid에 해당하는 고객 정보를 수정하기 : ShopService.userUpdate 함수
* 4. 수정 성공 : session의 로그인 정보 수정
* main 페이지 이동
* 수정 실패 : 수정실패 메세지 출력. update 페이지 이동하기
*/
@PostMapping("update") // POST 방식으로 user/userEntry url 요청시
public ModelAndView update(@Valid User user, BindingResult bresult, HttpSession session) {
ModelAndView mav = new ModelAndView();
//1. 유효성 검증하기
if(bresult.hasErrors()) {
mav.getModel().putAll(bresult.getModel());
return mav;
}
//2. 비밀번호 검증
//admin 로그인시 비밀번호는 admin 비밀번호로 검증
//본인 로그인시 비밀번호는 본인 비밀번호로 검증
User loginUser = (User)session.getAttribute("loginUser");
if(!loginUser.getPassword().equals(user.getPassword())) {
bresult.reject("error.login.password");
mav.getModel().putAll(bresult.getModel());
}
//3. userid에 해당하는 고객 정보를 수정하기
try {
service.userUpdate(user);
if(user.getUserid().equals(loginUser.getUserid())) //본인정보 수정시에만 로그인정보 수정
session.setAttribute("loginUser", user);
// 4. 수정 성공, 수정 실패
mav.setViewName("redirect:main");
} catch (Exception e) {
e.printStackTrace(); //수정 실패
throw new LoginException("고객 정보 수정 실패", "update?id="+user.getUserid());
}
return mav;
}
/*
* 1. loginCheckPassword : 로그인 여부 검증
* 2. @RequestParam : 요청파라미터를 Map객체로 저장
* req.put("password",password 파라미터값)
* req.put("chgpass",chgpass 파라미터값)
* req.put("chgpass2",chgpass2 파라미터값)
* 3. 입력된 현재 비밀번호와 로그인 된 정보의 비밀번호 일치 검증
* 4. db 변경하기
* 5. 성공시 : 로그인 정보 변경. main 페이지 이동
* 실패시 : 오류 메세지 출력. password 페이지 이동
*/
@PostMapping("password")
public ModelAndView loginCheckPassword(@RequestParam Map<String,String> req, HttpSession session) {
User loginUser = (User)session.getAttribute("loginUser");
//3. 입력된 현재 비밀번호와 로그인 된 정보의 비밀번호 일치 검증
//req.get("password") : 현재 비밀번호
//loginUser.getPassword() : 등록된 비밀번호
if(!req.get("password").equals(loginUser.getPassword())) {
throw new LoginException("비밀번호 오류 입니다.","password");
}
//비밀번호가 일치하는 경우 실행
ModelAndView mav = new ModelAndView();
try {
//req.get("chgpass") : 변경할 비밀번호
service.userChgPassword(loginUser.getUserid(),req.get("chgpass")); //db변경
loginUser.setPassword(req.get("chgpass")); //session의 loginUser 객체의 비밀번호 수정
mav.addObject("message", "비밀번호가 변경되었습니다.");
mav.setViewName("redirect:main");
} catch (Exception e) {
throw new LoginException("비밀번호 수정시 오류가 있습니다.", "password");
}
return mav;
}
/*
* 회원탈퇴
* 1.파라미터 정보 저장.
* - 관리자인 경우 탈퇴 불가
* 2.비밀번호 검증
* 본인탈퇴 : 본인 비밀번호
* 관리자가 타인 탈퇴 : 관리자 비밀번호
* 3.비밀번호 불일치
* 메세지 출력 후 delete 페이지 이동
* 4.비밀번호 일치
* db에서 해당 사용자정보 삭제하기
* 본인탈퇴 : 로그아웃, login 페이지 이동
* 관리자탈퇴 : admin/list 페이지 이동 => 404 오류 발생
*/
@PostMapping("delete")
public ModelAndView idCheckdelete(String password, String userid, HttpSession session) {
//password 매개변수 : password 이름의 파라미터 값 저장
//userid 매개변수 : userid 이름의 파라미터 값 저장
ModelAndView mav = new ModelAndView();
if(userid.equals("admin")) throw new LoginException("관리자 탈퇴는 불가능합니다.", "main");
User loginUser = (User)session.getAttribute("loginUser"); //로그인 정보
if(!password.equals(loginUser.getPassword())) {
throw new LoginException("비밀번호를 확인하세요.", "delete?id=" + userid);
}
try {
service.userDelete(userid);
} catch (Exception e) {
e.printStackTrace();
throw new LoginException("탈퇴시 오류발생.", "delete?id=" + userid);
}
if(loginUser.getUserid().equals("admin")) { //관리자가 사용자 강제탈퇴
mav.setViewName("redirect:../admin/list");
} else { //일반사용자 본인이 탈퇴
mav.setViewName("redirect:login");
session.invalidate(); //session 무효화
return mav;
}
return mav;
}
/*
* {url}search : {url} 지정하지 않음. *search인 요청인 경우 호출되는 메서드 지정
* @PathVariable String url : {url}값을 매개변수 전달.
* http://localhost:8088/springmvc1/user/idsearch 요청
* url : id 값 저장
* http://localhost:8088/springmvc1/user/pwsearch 요청
* url : pw 값 저장
*/
@PostMapping("{url}search")
public ModelAndView search(User user, BindingResult bresult, @PathVariable String url) {
ModelAndView mav = new ModelAndView();
String code = "error.userid.search"; //아이디를 찾을 수 없습니다. 메세지의 코드값
String title = "아이디";
if(user.getEmail() == null || user.getEmail().equals("")) { //email 값이 없을 때.
//rejectValue : 컬럼별로 오류 메세지 저장
// <form:errors path="email" /> 영역에 오류 메세지 출력
bresult.rejectValue("email", "error.required"); //@Valid에서 처리해주는 방식.
}
if(user.getPhoneno() == null || user.getPhoneno().equals("")) {
// <form:errors path="phoneno" /> 영역에 오류 메세지 출력
bresult.rejectValue("phoneno", "error.required"); //message.properties에서 처리.
}
if(url.equals("pw")) {
title = "비밀번호";
code = "error.password.search"; //비밀번호를 찾을 수 없습니다. 메세지의 코드값
if(user.getUserid() == null || user.getUserid().equals("")) {
bresult.rejectValue("userid", "error.required");
}
}
if(bresult.hasErrors()) { //rejectValue 함수로 오류가 존재
mav.getModel().putAll(bresult.getModel());
return mav;
}
String result = null;
//아이디 검색 : 아이디 값
//비밀번호 검색 : 비밀번호 값
//user : 화면에서 입력된 파라미터 값 저장 (email. phoneno, userid)
result = service.getSearch(user,url);
//EmptyResultDataAccessException : mybatis에서 발생되지 않는 예외. spring jdbc에서 발생
if (result == null) {
//<spring:message code="${error.code}" /> 영역에 표시됨
bresult.reject(code); //grobals오류
mav.getModel().putAll(bresult.getModel());
return mav;
}
mav.addObject("result",result);
mav.addObject("title",title);
mav.setViewName("search"); // /WEB-INF/view/search.jsp
return mav;
}
}
User.java
package logic;
import java.util.Date;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import org.springframework.format.annotation.DateTimeFormat;
public class User {
@Size(min=3, max=10, message="아이디는 3자 이상 10자 이하로 입력하세요.")
private String userid;
@Size(min=3, max=10, message="비밀번호는 3자 이상 10자 이하로 입력하세요.")
private String password;
@NotEmpty(message="사용자 이름은 필수입니다.")
private String username;
private String phoneno;
private String postcode;
private String address;
@NotEmpty(message="email은 필수입니다.")
@Email(message="email 형식으로 입력하세요.")
private String email;
// @NotNull(message="날짜를 입력하세요.") //필수입력사항
@Past(message="생일은 과거 날짜만 가능합니다.")
@DateTimeFormat(pattern="yyyy-MM-dd") // 형식 오류 시 typeMismatch.birthday 코드값 저장
private Date birthday;
//getter, setter, toString
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPhoneno() {
return phoneno;
}
public void setPhoneno(String phoneno) {
this.phoneno = phoneno;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User [userid=" + userid + ", password=" + password + ", username=" + username + ", phoneno=" + phoneno
+ ", postcode=" + postcode + ", address=" + address + ", email=" + email + ", birthday=" + birthday
+ "]";
}
}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%-- /WEB-INF/view/user/login.jsp --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html><html><head><meta charset="UTF-8">
<title>로그인화면</title>
<script type="text/javascript">
if('${param.msg}') {
alert('${param.msg}')
}
function win_open(page) {
var op = "width=500, height=350, left=50,top=150";
open(page,"",op);
}
</script>
</head><body>
<h2>사용자 로그인</h2>
<form:form modelAttribute="user" method="post" action="login" name="loginform">
<%-- <input type="hidden" name="birthday" value="2020-01-01" > --%>
<input type="hidden" name="username" value="유효성검증을위한 파라미터" >
<input type="hidden" name="email" value="valid@aaa.bbb" >
<spring:hasBindErrors name="user">
<font color="red"><c:forEach items="${errors.globalErrors}" var="error">
<spring:message code="${error.code}" />
</c:forEach></font></spring:hasBindErrors>
<table border="1" style="border-collapse: collapse;">
<tr height="40px"><td>아이디</td><td><form:input path="userid" />
<font color="red"><form:errors path="userid" /></font></td></tr>
<tr height="40px"><td>비밀번호</td><td><form:password path="password" />
<font color="red"><form:errors path="password" /></font></td></tr>
<tr height="40px"><td colspan="2" align="center">
<input type="submit" value="로그인">
<input type="button" value="회원가입" onclick="location.href='userEntry'">
<input type="button" value="아이디찾기" onclick="win_open('idsearch')">
<input type="button" value="비밀번호찾기" onclick="win_open('pwsearch')">
</td></tr></table>
</form:form></body></html>
728x90
반응형