고래씌
[Spring] 2-1. 로그인, 로그아웃 페이지 본문
1. 로그인 페이지
=> member 폴더
▶ Member.java
package com.kh.spring.member.model.vo;
import java.sql.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class Member {
private int userNo;
private String userId;
private String userPwd;
private String userName;
private String birthday;
private String gender;
private String phone;
private String address;
private Date enrollDate;
private Date modifyDate;
private String status;
}
▶ MemberController.java
@Controller => spring의 빈스캐너가 자동으로 빈객체로 만들어준다. (servlet-context.xml안에 있는 태그)
☞ 기존객체 생성 방식
private MemberService mService = new MemberServiceImpl();
☞ Spring의 DI(Dependecy Injection) → 객체를 개발자가 생성하는게 아니라, 스프링이 생성한 객체를
주입받아서 사용하는 방식.
new 연산자를 쓰지말고, 선언만 한후 @Autowird어노테이션을 붙여서 주입을 받음
☞ 필드방식 의존성 주입
@Autowired private MemberService mService; |
장점 : 이해하기 편하다. 사용하기 편하다.
단점 : 1) 순환 의존성 문제가 발생할 수 있다.
2) 무분별한 주입시 의존관계 확인이 어렵다.
☞ 생성자 주입방식 => 생성자 주입방식을 권장!
생성자에 참조할 클래스를 인자(매개변수)로 받아서 필드에 매핑시킨다.
장점 : 현재클래스에서 내가 주입시킬 객체들을 모아서 관리할 수 있기 때문에 한눈에 알아보기 편함. 예약어로 final필드를 쓸 수 있다.
public MemberController() { } // 의존성을 매개변수 있는 생성자로 주입함. 위에 Autowired 썼던 것은 주석처리! @Autowired public MemberController(MemberService mService) { this.mService = mService; } /* * setter방식 의존성 주입 : setter메서드로 빈을 주입받는 방식 */ public void setMemberService(MemberService mService) { this.mService = mService; } |
▶ MemberServiceImpl.java
@Service 어너테이션 추가
▶ MemberServiceImpl.java
@Repository 어너테이션 추가
1-1) 스프링에서 paramter를 받는 방법들
1) HttpServletRequest를 이용해서 전달받기
해당 메소드의 매개변수로 HttpServletRequest를 작성해놓으면 스프링 컨테이너가 해당 메소드를 호출할 때 자동으로 request객체를 생성해서 매개변수에 주입해준다.
@RequestMapping(value="login.me", method=RequestMethod.POST) // 요청해서 mapping할 수 있는 어노테이션. 사용자가 login.me라는 값이 들어왔을때 감지됨 public String loginMember(HttpServletRequest reqeust) { // userId, userPwd System.out.println("userId : " + reqeust.getParameter("userId")); System.out.println("userPwd : " + reqeust.getParameter("userPwd")); return "main"; } |
2) @ReqeustParam어노테이션을 이용하는 방법
servlet의 request.getParameter("키")로 뽑은 역할을 대신 수행해주는 어노테이션
ReqeustParam속성의 value로 jsp에서 작성했던 name값을 입력해주면 알아서 매개변수로 값을 담아옴.
넘어온 값이 비어있다면 기본값도 지정가능하다.
@RequestMapping(value="login.me", method=RequestMethod.POST) // 요청해서 mapping할 수 있는 어노테이션. 사용자가 login.me라는 값이 들어왔을때 감지됨 public String loginMember( @RequestParam(value="userId", defaultValue="mmm") String userId, @RequestParam(value="userPwd") String userPwd) { // value에는 input태그의 name속성값을 넣으면됨. // userId, userPwd System.out.println(userId + "||||||||||" + userPwd); return "main"; } |
3) @ReqeustParam를 생략하는 방법
단, 기본값을 사용불가.
@RequestMapping(value="login.me", method=RequestMethod.POST) // 요청해서 mapping할 수 있는 어노테이션. 사용자가 login.me라는 값이 들어왔을때 감지됨 public String loginMember( String userId, String userPwd) { // userId, userPwd System.out.println(userId + "||||||||||" + userPwd); return "main"; } |
4) 커맨드 객체 방식
- 해당 메소드의 매개변수로 요청시 전달하고자하는 VO클래스타입의 변수를 세팅하고, 요청시 전달값의 name속성을 VO클래스의 필드명과 일치시켜서 작성(userId, userPwd)
- 스프링컨테이너에서 해당객체를 "기본 생성자"를 호출해서 객체를 생성한 후, 내부적으로 전달받은 key값에 해당하는 setter메서드를 찾아서 전달한 값을 생성된객체의 필드에 담아준다. 따라서 반드시 name속성값과, 필드명이 일치해야한다.
@RequestMapping(value="login.me", method=RequestMethod.POST) // 요청해서 mapping할 수 있는 어노테이션. 사용자가 login.me라는 값이 들어왔을때 감지됨 public String loginMember(Member m) { // userId, userPwd System.out.println(m.getUserNo()); System.out.println(m.getUserId() + "||||||||||" + m.getUserPwd()); return "main"; } |
우리는 5번 방식으로 할 예정 !!! ★ ★ ★ ★ ★ ★ ★ ★ ★
5) 로그인 요청 처리 완료 후, "응답 데이터"를 담고 응답페이지로 url재요청할 예정
■ 1) Model객체를 이용하는 방법
포워딩할 응답뷰페이지로 전달하고자 하는 데이터를 맵형식으로 담아주기
→ request, session 스코프 두개를 가지고 있음
- 기본 scope : reqeust
session scope : 클래스 위쪽에 @SessionAttribute을 추가 한후 작성하면된다.
■ 2) ModelAndView객체 이용
- ModelAndView에서 Model은 데이터를 담을 수 있는 맵형태의 객체(위 Model과 동일)
View는 이동하고자흔 페이지에 대한 정보를 담고있는 객체. 두개를 합쳐서 ModelAndView가 된다.
- Model은 내부에 데미터를 추가하고자 할 때 addAttribute()함수를 이용
ModelAndView는 데이터를 추가할 때 addObject()를 사용. view를 지정할때는 setViewName()를 사용
@RequestMapping(value="login.me", method=RequestMethod.POST) // 요청해서 mapping할 수 있는 어노테이션. 사용자가 login.me라는 값이 들어왔을때 감지됨
public ModelAndView loginMember(Member m, HttpSession session, Model model, ModelAndView mv) {
// model.addAttribute("errorMsg", "오류발생");
mv.addObject("errorMsg", "오류발생");
mv.setViewName("common/errorPage"); // 접두어로 다 붙기때문에 /WEB-INF/views와 .jsp는 생략가능. /WEB-INF/views/common/errorPage.jsp
return mv;
}
☞ common > erroerPage.jsp(에러페이지 만들기)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<jsp:include page="header.jsp"></jsp:include>
<br>
<div align="center">
<img src="https://cdn0.iconfinder.com/data/icons/small-n-flat/24/678069-sign-error-64.png">
<br><br>
<h1 style="font-weight:bold;">${errorMsg }</h1>
</div>
<jsp:include page="footer.jsp"></jsp:include>
</body>
</html>
☞ 로그인 기능 만들기
▶ MemberController.java
@PostMapping("login.me")
public ModelAndView loginMember(@ModelAttribute Member m, HttpSession session, Model model, ModelAndView mv) {
// 암호화 전 로그인 요처리
Member loginUser = mService.loginMember(m);
String url = "";
if(loginUser == null) { // 로그인 실패시
mv.addObject("errorMsg", "오류발생");
mv.setViewName("common/errorPage");
}else { // 성공시
model.addAttribute("loginUser", loginUser);
// session.setAttribute("loginUser", loginUser);
mv.setViewName("redirect:/");
}
return mv;
}
- 클래스 맨위에 @SessionAttributes({"loginUser"}) 추가
☞ 현재 Model안에 추가된 값의 key값과 일치하는 값이 있으면 해당값을 session scope로 이관
=> 이렇게 추가하면 model.addAttribute에 담긴 값이 session scope로 이관되어서 로그인을 하게되면 새로고침을 해도 로그아웃을 클릭하지 않는한, 로그인이 유지된다. 단, 로그아웃이 되지않는 문제가 발생하게 되는데 로그아웃이 되게하려면 logout.me에서 status.setComplete();를 해주어야 안에 있는 session이 비어지면서 로그아웃이 가능하게 된다.
▶ MemberService.java
package com.kh.spring.member.model.service;
import com.kh.spring.member.model.vo.Member;
public interface MemberService {
Member loginMember(Member m);
}
▶ MemberServiceImpl.java
=> SqlSession객체를 bean으로 등록한 후에는 스프링컨테이너가 자원 사용후 자동으로 반납을 해주기 때문에 close()할 필요가 없음
package com.kh.spring.member.model.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.kh.spring.member.model.dao.MemberDao;
import com.kh.spring.member.model.vo.Member;
@Service
public class MemberServiceImpl implements MemberService {
// 순환 문제 발생함
// @Autowired
// private MemberController mController;
@Autowired
private MemberDao memberDao;
@Override
public Member loginMember(Member m) {
/*
* SqlSession객체를 bean으로 등록한 후에는 스프링컨테이너가 자원 사용후 자동으로 반납을 해주기 때문에
* close()할 필요가 없음
*/
return memberDao.loginUser(m);
}
}
▶ MemberDao.java
package com.kh.spring.member.model.dao;
import com.kh.spring.member.model.vo.Member;
public interface MemberDao {
Member loginUser(Member m);
}
▶ MemberDaoImpl.java
package com.kh.spring.member.model.dao;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.kh.spring.member.model.vo.Member;
@Repository
public class MemberDaoImpl implements MemberDao{
@Autowired
private SqlSessionTemplate sqlSession;
@Override
public Member loginUser(Member m) {
return sqlSession.selectOne("memberMapper.loginUser", m);
}
}
=> DB에 저장된 admin, 1234로 로그인한 결과 정상적으로 로그인 되는 것을 확인
3. 로그아웃
▶ MemberController.java
@GetMapping("/logout.me")
public String logoutMember(HttpSession session, SessionStatus status) {
session.invalidate();
status.setComplete(); // @SessionAttribute와 model로 session scope에 이관된 데이터는 SessionStatus를 이용해서 바꿔줘야한다.
// 로그인한 유저가 비어지게됨
return "redirect:/"; // 메인 url로 이동
}
'Server > Spring' 카테고리의 다른 글
[Spring] 4. 예외처리 (0) | 2024.01.23 |
---|---|
[Spring] 3. 마이페이지 수정하기, alertMsg 띄우기 (0) | 2024.01.23 |
[Spring] 2-2. 회원가입 페이지, 비밀번호 암호화 저장 (0) | 2024.01.22 |
[Spring] 1. header, footer만들기 (1) | 2024.01.22 |
[Spring] 0. Spring 환경설정 (2) | 2024.01.19 |