Controller에서는 앞서 구현한 엔티티, 레포지토리, 서비스를 가지고 화면과 직접적으로 데이터를 주고 받는 기능들을 담당하기 때문에 경우에 따라 처리해줘야 할 부분이 많았다. 각 Controller에서 주요 기능의 코드, 로직에 대해 정리해보았다.
(1) HomeController
@GetMapping("/") // 로그인 정보 저장위해 세션에 저장
public String home(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember, Model model) {
if(loginMember == null) {
return "home";
}
// 메인 페이지에서 필요할 데이터 model에 담아서 view에 전달
// 소속 지역에 해당하는 상품 목록
List<Product> products = productService.findByLocation(loginMember.getLocation()).orElseGet(ArrayList::new);
model.addAttribute("products", products);
// 카테고리 설정을 위한 모든 카테고리 정보
List<Category> allCategory = categoryService.findAll();
model.addAttribute("allCategory", allCategory);
// 계정 정보
model.addAttribute("member", loginMember);
return "mains/mainPage";
}
(2) MainController
@PostMapping("/") // 상품 조회 시 카테고리 설정 기능 메소드
public String setCategory(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER_LOCATION, required = false) Location loginLocation, Model model, @RequestBody Map<String, String> map) {
String category = map.get("category");
Category category1 = categoryService.findByName(category).get();
// 설정한 카테고리에 해당하는 상품 목록들
List<Product> products = productService.findByLocationAndCategory(loginLocation, category1).orElseGet(ArrayList::new);
model.addAttribute("products", products);
return "mains/mainPage :: #resultTable";
}
@GetMapping("/mains/register")
public String productRegisterForm(Model model) {
// '게시물 등록' 시 카테고리 설정 위해 데이터 전송
model.addAttribute("allCategory", categoryService.findAll());
return "mains/productForm";
}
@PostMapping("/mains/register") // 게시물(상품) 등록 메소드
public String register(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember, ProductForm productForm,
@RequestParam(defaultValue = "/mains/mainPage") String redirectURL ) {
Product product = new Product();
Category category = categoryService.findByName(productForm.getCategory()).get();
Location location = locationService.find(loginMember.getLocation().getLocationId()).get();
product.setProductName(productForm.getProductName());
product.setPrice(productForm.getPrice());
product.setCategory(category);
product.setContents(productForm.getContents());
product.setMember(loginMember);
product.setProductStatus(ProductStatus.SALE);
product.setLocation(location);
product.setTime(fomatDate());
productService.register(product);
return "redirect:/";
}
// 게시시간 설정
public String fomatDate() {
Date now = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd, HH:mm");
return format.format(now);
}
(3) MemberController
// 지역 검색 기능 메소드
// 키워드로 검색하면 키워드가 포함된 지역 목록이 조회될 수 있도록 구현
@RequestMapping(value = "/test", method = RequestMethod.POST)
public String getAll(Model model, @RequestParam("address") String address) {
if(address.length() == 0) { // 키워드가 없을 때 처리
model.addAttribute("locationList", null);
}else {
model.addAttribute("locationList", locationService.findByName(address).orElseGet(ArrayList::new));
}
return "members/createMemberForm :: #resultLocationList";
}
// 회원가입 기능 메소드
@PostMapping("/members/new")
public String create(MemberForm memberForm) {
Member member = new Member();
member.setName(memberForm.getName());
member.setEmail(memberForm.getEmail());
member.setPassword(memberForm.getPassword());
member.setPhoneNumber(memberForm.getPhoneNumber());
member.setNickName(memberForm.getNickName());
// 화면에서 String형으로 지역 이름을 받아오기 때문에 서비스 처리 필요
// Optional형이지만 드롭다운 리스트에서 선택했기 때문에 무조건 지역 정보 DB 테이블에 존재
Location location = locationService.findByName(memberForm.getLocation()).get().get(0);
member.setLocation(location);
memberService.join(member);
return "redirect:/";
}
// 로그인 기능
@PostMapping("/members/login")
public String login(@ModelAttribute @Validated MemberForm memberForm,
BindingResult bindingResult, @RequestParam(defaultValue = "/") String redirectURL,
HttpServletRequest request) {
if(bindingResult.hasErrors()) {
return "members/loginForm";
}
Member loginMember = memberService.login(memberForm.getEmail(), memberForm.getPassword()); // 로그인 계정 세팅, memberForm에 지역 값 입력하는 거 추가해줘야함
if(loginMember == null) {
bindingResult.reject("loginFail", "아이디 또는 비밀번호가 일치하지 않습니다.");
return "members/loginForm";
}
// 로그인 시 필요 데이터 설정
productService.findByMember(loginMember).ifPresent(loginMember::setProducts);
dealService.findByMember(loginMember).ifPresent(loginMember::setDeals);
interestedService.findInterestedByMember(loginMember).ifPresent(loginMember::setInterestedProducts);
Location location = locationService.find(loginMember.getLocation().getLocationId()).get();
loginMember.setLocation(location);
HttpSession session = request.getSession(); // 세션 있으면 반환, 없으면 신규 세션 생성
session.setAttribute(SessionConstants.LOGIN_MEMBER, loginMember); // 세션에 로그인 회원 정보 보관
session.setAttribute(SessionConstants.LOGIN_MEMBER_LOCATION, location);
return "redirect:/";
}
(4) ProductController
// 상품 세부 조회 기능
@GetMapping("/products/view")
public String viewProduct(Model model, Long productId) {
Product product = productService.find(productId).orElseGet(Product::new);
model.addAttribute("product", product);
Member productOwner = product.getMember();
List<Product> productList = productService.findByMember(productOwner).orElseGet(ArrayList::new);
productList.remove(product); // 상품 등록자의 또다른 상품 목록에 중복으로 띄워져 삭제
model.addAttribute("otherProducts", productList);
model.addAttribute("productOwner", productOwner);
return "products/view";
}
// 상품 댓글 조회 기능
@GetMapping("/products/comment")
public String viewComment(Model model, Long productId) {
Product product = productService.find(productId).orElseGet(Product::new);
List<Comment> comments = commentService.findByProduct(product).orElseGet(ArrayList::new);
model.addAttribute("comments", comments);
model.addAttribute("product", product);
return "products/comment";
}
// 상품 댓글 남기기 기능
@PostMapping("/products/comment")
public String registerComment(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember, CommentForm commentForm,
Long productId, Model model) {
Product product = productService.find(productId).orElseGet(Product::new);
Comment comment = new Comment();
// 이미 댓글 단 사용자라면 업데이트 되게 구현
Optional<Long> existId = commentService.exist(loginMember, product);
existId.ifPresent(comment::setCommentId);
comment.setContents(commentForm.getContents());
comment.setMember(loginMember);
comment.setProduct(product);
commentService.register(comment);
return "redirect:/products/comment?productId=" + productId;
}
// '모두 보기' 기능
@GetMapping("/products/all")
public String all(Model model, String nickName, Product product) {
Member member = memberService.findByNickName(nickName).orElseGet(Member::new);
List<Product> products = productService.findByMember(member).orElseGet(ArrayList::new);
model.addAttribute("products", products);
model.addAttribute("member", member);
model.addAttribute("product", product);
return "products/all";
}
// 진행상태별 조회 기능(거래중, 거래완료)
@PostMapping("/products/all")
public String allByStatus(Model model, StatusProductForm statusProductForm) {
List<Product> list = new ArrayList<>();
String status = statusProductForm.getStatus();
Long memberId = Long.parseLong(statusProductForm.getMemberId());
Member member = memberService.find(memberId).orElseGet(Member::new);
if(status.equals("ALL")) {
list = productService.findByMember(member).orElseGet(ArrayList::new);
}else if(status.equals("SALE")) {
list = productService.findByMemberAndStatus(member, ProductStatus.SALE).orElseGet(ArrayList::new);
}else { // 거래완료(COMPLETE) 인 경우
for(Deal deal : member.getDeals()) {
list.add(deal.getProduct());
}
}
model.addAttribute("products", list);
model.addAttribute("member", member);
return "products/all";
}
(5) MyPageController
// 닉네임 수정 기능
@PostMapping("/mine/profile")
public String change(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember,
Model model, String nickName) {
loginMember.setNickName(nickName);
memberService.join(loginMember); // 업데이트
// 수정된 닉네임 바로 보이게 데이터 전달
model.addAttribute("nickName", loginMember.getNickName());
return "mine/profile";
}
// 마이페이지 - 판매상품 조회 기능
@PostMapping("/mine/myProductList")
public String getProductList(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember,
String status, Model model) {
List<Product> list = new ArrayList<>();
if(status.equals("SALE")) { // 판매중
list = productService.findByMemberAndStatus(loginMember, ProductStatus.SALE).orElseGet(ArrayList::new);
}else if(status.equals("COMPLETE")){ // 거래완료
for(Deal deal : loginMember.getDeals()) {
list.add(deal.getProduct());
System.out.println(deal.getProduct());
}
}
model.addAttribute("products", list);
return "mine/myProductList";
}
// 마이페이지 - 판매상품 - 진행단계 변경 기능
// 현재 진행단계 변경 기능 및 삭제 기능 제대로 동작 안되고 있음
// 화면에서 상품id가 다르게 전달되어 기능 100% 동작 안됨
// 시간 부족하여 수정완료하지 못했고 추후에 수정 예정
@PostMapping("/updateStatus")
public String updateStatus(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember,
String updateStatus, Long productId, Model model) {
List<Product> list = new ArrayList<>();
Product product = productService.find(productId).get();
setNewStatus(loginMember, product, updateStatus);
if(updateStatus.equals("RESERVATION")) {
list = productService.findByMemberAndStatus(loginMember, ProductStatus.SALE).orElseGet(ArrayList::new);
}else {
for(Deal d : loginMember.getDeals()) {
list.add(d.getProduct());
}
}
model.addAttribute("products", list);
return "mine/myProductList";
}
// 마이페이지 - 관심상품 기능
// 시간 부족으로 관심 기능 구현하지 못해 현재 빈 화면만 조회
// 추후 수정 예정
@PostMapping("/mine/myInterestedList")
public String getInterestedList(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember,
Model model, String status) {
ArrayList<InterestedProduct> list = new ArrayList<>();
if(status.equals("SALE")) {
for(InterestedProduct p : loginMember.getInterestedProducts()) {
if(p.getProduct().getProductStatus().equals(ProductStatus.SALE)) {
list.add(p);
}
}
}else {
for(InterestedProduct p : loginMember.getInterestedProducts()) {
if(p.getProduct().getProductStatus().equals(ProductStatus.COMPLETE)) {
list.add(p);
}
}
}
model.addAttribute("interestedProducts", list);
return "mine/myInterestedList";
}
// 상품 게시물 수정 기능
@GetMapping("/products/update")
public String findUpdateProduct(Model model, Long productId) {
// 카테고리 목록 데이터 화면에 전달
model.addAttribute("allCategory", categoryService.findAll());
model.addAttribute("product", productService.find(productId).get());
return "products/update";
}
// 상품 게시물 수정 기능
@PostMapping("/products/update")
public String update(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember, Model model, ProductForm productForm) {
Product product = productService.find(productForm.getProductId()).get();
Category category = categoryService.findByName(productForm.getCategory()).get();
product.setProductName(productForm.getProductName());
product.setCategory(category);
product.setPrice(productForm.getPrice());
product.setContents(productForm.getContents());
setNewStatus(loginMember,product, productForm.getStatus());
model.addAttribute("status", "SALE");
return "mine/myProductList";
}
// 진행단계 변경 기능으로 인해 중복되는 코드 메소드로 추출
public void setNewStatus(@SessionAttribute(name = SessionConstants.LOGIN_MEMBER, required = false) Member loginMember,
Product product, String status) {
if(status.equals("DELETE")) {
dealService.findByProduct(product).ifPresent(deal -> {
deal.setProduct(null);
dealService.remove(deal);
});
productService.remove(product);
return;
}
// 거래완료 -> 예약중, 판매중으로 변경 시 거래 내역 삭제
if(product.getProductStatus().equals(ProductStatus.COMPLETE)) {
dealService.findByProduct(product).ifPresent(deal -> {
deal.setProduct(null);
dealService.remove(deal);
});
}
if(status.equals("RESERVATION")) {
product.setProductStatus(ProductStatus.RESERVATION);
productService.register(product); // 업데이트
}else if(status.equals("SALE")) {
product.setProductStatus(ProductStatus.SALE);
productService.register(product); // 업데이트
}else {
product.setProductStatus(ProductStatus.COMPLETE);
Product result = productService.register(product);
Deal deal = new Deal();
deal.setMember(loginMember);
deal.setProduct(result);
dealService.register(deal);
}
}