수업(국비지원)/Spring
[Spring] (MVC 2) 상품 주문 정보 보기(UserController, ShopService, SaleDao, SaleItemDao)
byeolsub
2023. 4. 21. 00:17
📌 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.dao.EmptyResultDataAccessException;
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 방식 요청
public ModelAndView getUser() {
ModelAndView mav = new ModelAndView();
mav.addObject(new User());
return mav;
}
@PostMapping("join")
public ModelAndView join (@Valid User user, BindingResult bresult) {
ModelAndView mav = new ModelAndView();
if(bresult.hasErrors()) { //입력값 오류 발생
mav.getModel().putAll(bresult.getModel());
//전반적인 오류코드 등록
bresult.reject("error.input.user");
return mav;
}
//db에 회원정보 등록
try {
service.userInsert(user);
mav.addObject("user", user);
//DataIntegrityViolationException : 중복키 오류
// 같은 이름의 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에 로그인 정보 등록하기
* session.setAttribute("loginUser", user 객체)
*/
@PostMapping("login")
public ModelAndView login(@Valid User user, BindingResult bresult, HttpSession session) {
ModelAndView mav = new ModelAndView();
//1. 유효성 검증
if(bresult.hasErrors()) {
mav.getModel().putAll(bresult.getModel());
bresult.reject("error.input.login");
return mav;
}
//2. 입력받은 userid, password로 db에서 해당 정보를 읽기.
try {
User dbUser = service.getUser(user.getUserid());
if(user.getPassword().equals(dbUser.getPassword())) { //정상적인 사용자 인 경우
session.setAttribute("loginUser", dbUser);
} else {
bresult.reject("error.login.password");
mav.getModel().putAll(bresult.getModel());
return mav;
}
//EmptyResultDataAccessException : 해당 레코드 없음
} catch(EmptyResultDataAccessException e) { //id가 없는 경우 예외처리
bresult.reject("error.login.id");
mav.getModel().putAll(bresult.getModel());
return mav;
}
mav.setViewName("redirect:mypage?id=" + user.getUserid());
return mav;
}
//http://localhost:8088/springmvc1/user/logout
@RequestMapping("logout") //핵심 메서드 : 기본 실행 메서드 (진짜 수행에 기본이 되는)
public String loginCheckLogout(HttpSession session) {
session.invalidate();
return "redirect:login";
}
/*
* AOP 설정하기 : UserLoginAspect 클래스의 userIdCheck 메서드로 구현하기.
* 1. pointcut : UserController 클래스의 idCheck로 시작하는 메서드이고,
* 마지막 매개변수의 id,session인 경우
* 2. 로그인 여부 검증
* - 로그인이 안된경우 로그인 후 거래하세요. 메세지 출력. login페이지 호출
* 3. admin이 아니면서, 로그인 아이디와 id값이 다른 경우
* 본인만 거래 가능합니다. 메세지 출력. item/list 페이지 호출
*/
**@RequestMapping("mypage")
public ModelAndView idCheckMypage(String id, HttpSession session) {
ModelAndView mav = new ModelAndView();
//회원 정보를 조회하여 user 이름으로 뷰 전달
User user = service.getUser(id);
//주문 정보를 조회하여 뷰에 전달
List<Sale> salelist = service.salelist(id);
mav.addObject("user", user); //사용자 정보
mav.addObject("salelist", salelist); //주문 목록
return mav;
}**
@GetMapping({"update","delete"})
public ModelAndView idCheckUser(String id, HttpSession session) {
ModelAndView mav = new ModelAndView();
//회원 정보를 조회하여 user 이름으로 뷰 전달
User user = service.getUser(id);
mav.addObject("user", user);
return mav;
}
@PostMapping("update")
public ModelAndView idcheckUpdate (@Valid User user, BindingResult bresult, HttpSession session) {
ModelAndView mav = new ModelAndView();
if(bresult.hasErrors()) {
mav.getModel().putAll(bresult.getModel());
bresult.reject("error.update.user");
return mav;
}
//비밀번호 검증 : 로그인된 정보의 비밀번호로 검증.
User loginUser = (User)session.getAttribute("loginUser");
if(!loginUser.getPassword().equals(user.getPassword())) {
mav.getModel().putAll(bresult.getModel());
bresult.reject("error.login.password");
return mav;
}
//비밀번호 일치인 경우 : DB에 내용을 수정
try {
service.userUpdate(user);
//session에 로그인 정보 수정
session.setAttribute("loginUser", user);
mav.setViewName("redirect:mypage?id=" + user.getUserid());
} catch (Exception e) {
e.printStackTrace();
throw new LoginException("고객 정보 수정 실패","update?id=" + user.getUserid());
}
return mav;
}
@PostMapping("delete")
public ModelAndView idcheckdelete (String password,String userid, HttpSession session) {
ModelAndView mav = new ModelAndView();
//관리자인 경우 탈퇴 불가
if(userid.equals("admin")) throw new LoginException("관리자는 탈퇴가 불가능합니다.","mypage?id=" + userid);
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;
}
@GetMapping("password")
public String loginCheckPassword(HttpSession session) {
return null;
}
/*
* 1. 로그인 검증
* 2. 파라미터값을 Map 객체에 저장
* @RequestParam : 요청 파라미터를 Map 객체로 저장하도록하는 어노테이션
* req.put("password",password의 파라미터값)
* req.put("chgpass",chgpass의 파라미터값)
* req.put("chgpass2",chgpass2의 파라미터값)
* 3. 현재 비밀번호와 입력된 비밀번호 검증
* 불일치 : 오류메세지 출력, password 페이지 이동
* 4. 일치 : db 수정
* 5. 성공 : 로그인 정보 변경, mypage 페이지 이동
* 실패 : 오류메세지 출력, password 페이지 이동
*/
@PostMapping("password")
public ModelAndView loginCheckPasswordRtn(@RequestParam Map<String, String> req, HttpSession session) {
User loginUser = (User)session.getAttribute("loginUser"); //입력된 현재 비밀번호와 로그인된 정보의 비밀번호 일치 확인?
//req.get("password") : 현재 비밀번호
//loginUser.getPassword() : 등록된 비밀번호
if(!req.get("password").equals(loginUser.getPassword())) {
throw new LoginException("비밀번호 오류 입니다.", "password");
}
//비밀번호가 일치하는 경우
ModelAndView mav = new ModelAndView();
try {
//loginUser.getUserid() : 로그인 사용자 아이디
//req.get("chgpass") : 변경할 비밀번호
service.userChgPass(loginUser.getUserid(), req.get("chgpass")); //db 변경 완료
loginUser.setPassword(req.get("chgpass")); //session의 loginUser객체의 비밀번호 수정
mav.addObject("message","비밀번호가 변경 되었습니다.");
mav.setViewName("redirect: login");
} catch (Exception e) { //예외 발생
e.printStackTrace();
throw new LoginException("비밀번호 수정 시 db 오류 발생","password");
}
return mav;
}
/*
* "{url}search" : *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;
try {
//result : 사용자 id, 또는 비밀번호 값
//user : 화면에서 입력된 파라미터 값 저장 (email. phoneno, userid)
result = service.getSearch(user,url);
} catch (EmptyResultDataAccessException e) {
//EmptyResultDataAccessException : 조회결과가 없는 경우 발생되는 예외.
//뷰의 ${errors.globalErrors} 목록에 추가됨
//<spring:message code="${error.code}" /> 영역에 표시됨
bresult.reject(code); //global 오류 영역에 저장
mav.getModel().putAll(bresult.getModel());
return mav;
}
mav.addObject("result",result);
mav.addObject("title",title);
mav.setViewName("/user/search"); // /WEB-INF/view/user/search.jsp
return mav;
}
}
📌 ShopService.java 내용 추가
package logic;
import java.io.File;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import dao.ItemDao;
import dao.SaleDao;
import dao.SaleItemDao;
import dao.UserDao;
/*
* @Component : 해당 클래스를 객체화
* - Service 기능 : Controller 와 Model사이의 중간 역할의 클래스
*/
@Service //@Component + Service 기능
public class ShopService {
@Autowired //현재 내 컨테이너(객체)들 중에 itemDao 객체를 주입.
private ItemDao itemDao;
@Autowired
private UserDao userDao;
@Autowired
private SaleDao saleDao;
@Autowired
private SaleItemDao saleItemDao;
public List<Item> itemList() {
return itemDao.list();
}
public Item getItem(Integer id) {
return itemDao.getItem(id);
}
//db에 내용 저장. 파일 업로드.
//item : 저장 정보. 입력된 파라미터 값 + 업로드 된 파일의 내용
public void itemCreate(@Valid Item item, HttpServletRequest request) {
//item.getPicture() : 업로드 된 파일의 내용
if(item.getPicture() != null && !item.getPicture().isEmpty()) { //업로드 된 파일이 있는 경우
String uploadPath = request.getServletContext().getRealPath("/") + "img/"; //업로드 위치
uploadFileCreate(item.getPicture(), uploadPath); //업로드 구현 완료
item.setPictureUrl(item.getPicture().getOriginalFilename()); //파일의 이름
}
//maxid : item테이블 중 최대 id 값
int maxid = itemDao.maxId();
item.setId(maxid+1);
itemDao.insert(item);
}
private void uploadFileCreate(MultipartFile file, String uploadPath) {
//uploadPath : 파일이 업로드 되는 폴더
String orgFile = file.getOriginalFilename(); //업로드 된 파일의 이름
File fpath = new File(uploadPath);
if(!fpath.exists()) fpath.mkdirs(); //업로드 폴더를 생성(없으면)
try {
//파일의 내용 => uploadPath + orgFile 로 파일 저장
file.transferTo(new File(uploadPath + orgFile)); //파일업로드
} catch(Exception e) {
e.printStackTrace();
}
}
public void itemUpdate(Item item, HttpServletRequest request) {
//item.getPicture() : 업로드 된 파일의 내용
if(item.getPicture() != null && !item.getPicture().isEmpty()) { //업로드 된 파일이 있는 경우
String uploadPath = request.getServletContext().getRealPath("/") + "img/"; //업로드 위치
uploadFileCreate(item.getPicture(), uploadPath); //파일 업로드 : 업로드된 내용을 서버에 파일로 저장
item.setPictureUrl(item.getPicture().getOriginalFilename()); //파일의 이름을 db에 등록하기 위해 설정
}
itemDao.update(item);
}
public void itemDelete(Integer id) {
itemDao.delete(id);
}
public void userInsert(@Valid User user) {
userDao.insert(user);
}
public User getUser(String userid) {
return userDao.selectOne(userid);
}
public void userUpdate(@Valid User user) {
userDao.update(user);
}
public void userDelete(String userid) {
userDao.delete(userid);
}
public void userChgPass(String userid, String pass) {
userDao.chgpass(userid,pass);
}
public String getSearch(User user, String url) {
return userDao.search(user, url);
}
public List<User> userlist() {
return userDao.list();
}
/*
* 로그인 정보, 장바구니 정보에서 sale, saleitem 테이블에 데이터 저장
* 결과를 Sale 객체로 저장
* 1. sale 테이블의 saleid의 최대 값 조회
* 2. sale 테이블에 최대값+1, userid,sysdate 등록
* 3. Cart 데이터에서 saleitem 데이터 추출. insert
* 4. saleitem 정보를 sale객체에 모든 데이터 저장
* 5. sale 데이터 리턴
*/
public Sale checkend(User loginUser, Cart cart) {
//1. sale 테이블의 saleid의 최대 값 조회
int maxid = saleDao.getMaxSaleId();
//2. sale 테이블 등록
Sale sale = new Sale();
sale.setSaleid(maxid + 1);
sale.setUserid(loginUser.getUserid());
sale.setUser(loginUser);
saleDao.insert(sale); //sale 테이블에 데이터 저장
//3. Cart 데이터에서 saleitem 데이터 추출. insert
int seq = 0;
for(ItemSet is : cart.getItemSetList()) {
SaleItem saleItem = new SaleItem(sale.getSaleid(), ++seq, is);
sale.getItemList().add(saleItem);
saleItemDao.insert(saleItem); //saleitem 테이블에 저장
}
return sale;
}
**public List<Sale> salelist(String id) {
//Sale 테이블의 내용 저장
List<Sale> list = saleDao.list(id); //sale 테이블에서 id에 해당하는 목록 조회
for(Sale sa : list) {
//주문 번호에 해당하는 주문상품 조회
List<SaleItem> saleitemlist = saleItemDao.list(sa.getSaleid());
//SaleItem 객체에 Item 객체 저장
for(SaleItem si : saleitemlist) {
Item item = itemDao.getItem(si.getItemid()); //주문상품의 상품데이터(item) 조회
si.setItem(item); //Item 객체를 SaleItem 객체에 추가
}
sa.setItemList(saleitemlist); //Sale 객체에 SaleItem 목록 추가
}
return list;
}**
}
📌 SaleDao.java 내용 추가
package dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import logic.Sale;
@Repository
public class SaleDao {
private NamedParameterJdbcTemplate template;
private Map<String, Object> param = new HashMap<>();
private RowMapper<Sale> mapper = new BeanPropertyRowMapper<>(Sale.class);
@Autowired
public void setDataSource(DataSource dataSource) {
template = new NamedParameterJdbcTemplate(dataSource);
}
public int getMaxSaleId() {
return template.queryForObject("select nvl(max(saleid),0) from sale", param, Integer.class);
}
public void insert(Sale sale) {
String sql = "insert into sale (saleid, userid, saledate) values (:saleid, :userid, sysdate)";
SqlParameterSource param = new BeanPropertySqlParameterSource(sale);
template.update(sql, param);
}
**public List<Sale> list(String id) { //id : 사용자 아이디
String sql = "select * from sale where userid=:userid order by saleid desc";
param.clear();
param.put("userid", id);
return template.query(sql, param, mapper);
}**
}
📌 SaleItemDao.java 내용 추가
package dao;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import logic.Sale;
import logic.SaleItem;
@Repository
public class SaleItemDao {
private NamedParameterJdbcTemplate template;
private Map<String, Object> param = new HashMap<>();
private RowMapper<SaleItem> mapper = new BeanPropertyRowMapper<>(SaleItem.class);
@Autowired
public void setDataSource(DataSource dataSource) {
template = new NamedParameterJdbcTemplate(dataSource);
}
public void insert(SaleItem saleitem) {
String Sql = "insert into saleitem (saleid, seq, itemid, quantity, price)"
+ " values(:saleid, :seq, :itemid, :quantity, :item.price)";
SqlParameterSource param = new BeanPropertySqlParameterSource(saleitem);
template.update(Sql, param);
}
public List<SaleItem> list(int saleid) { //saleid 별 상품목록 가져오는
param.clear();
param.put("saleid", saleid);
String sql = "select * from saleitem where saleid = :saleid";
return template.query(sql, param, mapper);
}
}