본문 바로가기
Coding/spring

로그인 화면 구성

by 찡콩찡 2022. 10. 7.

로그인 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>

<style type="text/css">
 html,
body {
  height: 100%;
}

body {
  display: flex;
  align-items: center;
  padding-top: 40px;
  padding-bottom: 40px;
  background-color: #f5f5f5;
}

.form-signin {
  max-width: 330px;
  padding: 15px;
}

.form-signin .form-floating:focus-within {
  z-index: 2;
}

.form-signin input[type="email"] {
  margin-bottom: -1px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.form-signin input[type="password"] {
  margin-bottom: 10px;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
</style>
</head>
<body class="text-center">    
	<main class="form-signin w-100 m-auto">
	  <form>
	    <img class="mb-4" src="/docs/5.2/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
	    <h1 class="h3 mb-3 fw-normal">Please sign in</h1>
	
	    <div class="form-floating">
	      <input type="email" class="form-control" id="floatingInput" placeholder="name@example.com">
	      <label for="floatingInput">Email address</label>
	    </div>
	    
	    <div class="form-floating">
	      <input type="password" class="form-control" id="floatingPassword" placeholder="Password">
	      <label for="floatingPassword">Password</label>
	    </div>
	
	    <div class="checkbox mb-3">
	      <label>
	        <input type="checkbox" value="remember-me"> Remember me
	      </label>
	    </div>
	    
	    <button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
	    <p class="mt-5 mb-3 text-muted">&copy; 2017–2022</p>
	  </form>
	</main>
</body>
</html>

jsp를 실현할 method를 memberController에 추가한다. 

//언제 실행할거냐 @RequestMapping으로 get방식으로 요청이 오면은 
	@RequestMapping(path = "login.do", method = RequestMethod.GET)
	public String loginForm() {
		return "member/login";
	}

실행했을 때 나오는 화면

입력한 부분을 받아서 로그인 될 수 있도록 로직을 짜보자

name은 파라미터 이름이랑 맞춰야 해 vo에 썼던걸 맞춰준다. id는 label이랑 연결해야해서 같게 맞춰주면 됨

 

 <div class="form-floating">
	      <input type="text" class="form-control" name="memId" id="memId" placeholder="회원아이디">
	      <label for="memId">회원아이디</label>
	    </div>
	    
	    <div class="form-floating">
	      <input type="password" class="form-control" name="memPass" id="memPass" placeholder="비밀번호">
	      <label for="memPass">비밀번호</label>
	    </div>

memId 값이 잘 넘어간 걸 확인 할 수 있다.

submit을 눌렀을 때 전송될 수 있도록  form에다가 action값 넣어주기

Controller에서 name(memid, mempass)값 받아서 처리할 수 있도록 한다.

@RequestMapping(path = "login.do", method = RequestMethod.POST)
	public String login() {
		
		return "member/login";
	}

MemberVo vo을 데이터 베이스에 주면서 비교해오라는 method가 필요함

memberService.select(vo);

그런데 아이디랑 비번다 가져와야 해서select문을 다시 정의해야함

MemberVo memberVo = memberService.selectLogin(vo);

memberservice에 아래와 같이 정의된다. 

public MemberVo selectLogin(MemberVo vo);

memberserviceimpl에 아래와 같이 정의된다. 

	@Override
	public MemberVo selectLogin(MemberVo vo) {		
		return memberDao.selectLogin(vo);
	}

 

Dao를 작성해본다.

public MemberVo selectLogin(MemberVo vo);

메서드 이름과 같은 sql문을 Membermapper.xml에 추가한다.

 

controller에 아래와 같이 입력해준다. 

@RequestMapping(path = "login.do", method = RequestMethod.POST)
	public String login(MemberVo vo) {
		
		MemberVo memberVo = memberService.selectLogin(vo);
		
		if(memberVo == null) { //로그인 실패
			return "member/login";
			
		}else { //로그인 성공
			return "redirect:/member/list.do";	
		}

 

실행해본다. 짠 나왔다

session에 로그인 정보를 담아준다.

@RequestMapping(path = "login.do", method = RequestMethod.POST)
	public String login(MemberVo vo, HttpSession session) {
		
		MemberVo memberVo = memberService.selectLogin(vo);
		
		if(memberVo == null) { //로그인 실패
			return "member/login";
			
		} //로그인 성공
			session.setAttribute("loginUser", memberVo);
			
			return "redirect:/member/list.do";	
		
		
	}

 

로그인여부에 따라 보여지는 화면이 다르게 하고 싶을 때는 Head.jsp 아래와 같이 작성해준다.

보여줄 메뉴를 아래와 같이 분리해준다.

<div class="navbar-nav">
	      <!-- 로그인 해줬을 때 보여지는 화면 -->
	        <a class="nav-link" href="${pageContext.request.contextPath}/member/list.do">회원관리</a>
	        <a class="nav-link" href="${pageContext.request.contextPath}/bbs/list.do">게시판</a>
	          <a class="nav-link" href="${pageContext.request.contextPath}/member/logout.do"">로그아웃</a>
	        <a class="nav-link disabled">${sessionScope.loginUser.memName}</a>
	        <!-- 로그인 안했을 때 보여지는 화면 -->
	        <a class="nav-link" href="${pageContext.request.contextPath}/member/login.do"">로그인</a>
	        <a class="nav-link" href="${pageContext.request.contextPath}/member/add.do"">회원가입</a>
	       
	        
	      </div>
 <c:if test="${loginUser != null}"><!-- 로그인 해줬을 때 보여지는 화면 -->
	      	
	        <a class="nav-link" href="${pageContext.request.contextPath}/member/list.do">회원관리</a>
	        <a class="nav-link" href="${pageContext.request.contextPath}/bbs/list.do">게시판</a>
	        <a class="nav-link" href="${pageContext.request.contextPath}/member/logout.do"">로그아웃</a>
	        <a class="nav-link disabled">${sessionScope.loginUser.memName}</a>
	     </c:if>
	     <c:if test="${loginUser == null}"><!-- 로그인 안했을 때 보여지는 화면 -->	        
	        <a class="nav-link" href="${pageContext.request.contextPath}/member/login.do"">로그인</a>
	        <a class="nav-link" href="${pageContext.request.contextPath}/member/add.do"">회원가입</a>
	      </c:if>

로그인 안했을 때 보여지는 jsp

 

로그인 했을 때 보여지는 jsp

로그아웃 구현 controller 작성

//로그아웃누르면 세션에 있는거 지우기!summit버튼을 누르면 get으로 요청올것 
	@RequestMapping(path = "logout.do", method = RequestMethod.GET)
	public String logout(HttpSession session) {
		
         //데이터 베이스 작업 필요없으니 이 코드는 필요없읍
		//MemberVo memberVo = memberService.selectLogin(vo);
		
			//방법 1. null로 넣어주는 방법
			//session.setAttribute("loginUser", null);
			
			//방법2. loginUser로 저장된 session을 없애버리는 방법!
			//session.removeAttribute("loginUser");
			
			//방법3. session자체를 지우는 방법 : 세션자체는 유효하지 않는것이다 라고 tomcat자체가 지우는 방법
			session.invalidate();
			//로그아웃 했을 때 보여지는 화면 : 로그인 화면
			return "redirect:/member/login.do";	
	}

실행했을 때 보여지는 화면 (로그아웃을 했을 때)

 

로그인 안했을 때는 회원가입과 로그인만 할 수 있도록 구현

컨트롤러전에 로그인 검사를 하고

컨트롤러에서 공통적으로 수행해야 하는 작업은 handler interceptor나 필터를 사용한다.

handler interceptor를 만들어보자!

package com.exam.myapp.member;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;


public class LoginInterceptor extends HandlerInterceptorAdapter{
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// 컨트롤러(의 @RequestMapping 메서드) 실행 전에 공통적으로 수행하는 작업들
		
		 
		 HttpSession session = request.getSession();
		 MemberVo vo = (MemberVo) session.getAttribute("loginUser");		 
		 if (vo == null) { //로그인 하지 않은 경우
			 response.sendRedirect(request.getContextPath() + "/member/login.do"); //로그인화면으로 리다이렉트 
			 return false; //컨트롤러 미실행
		 } 
		 
		 //로그인한 경우
		return true; //컨트롤러 실행
	}
}

servlet-context에서 스프링에 등록

<interceptors>
	  <interceptor>
	  	<mapping path="/**"/>
	  	<exclude-mapping path="/memeber/login.do"/>
	  	<exclude-mapping path="/memeber/add.do"/>
	  	<exclude-mapping path="/memeber/check.do"/>
	  	<beans:bean class="com.exam.myapp.member.LoginInterceptor" />
	  </interceptor>
	</interceptors>

bbscontroller를 작성해준다. 

//세션을 받아서 회원정보를 가져와서 로그인된 사람을 작성자id로 넘기는 것 
		MemberVo mvo = (MemberVo) session.getAttribute("loginUser");	
		vo.setBbsWriter(mvo.getMemId());
	
		int num = bbsService.insert(vo);
		return "redirect:/bbs/list.do";

등록일 고쳐보자! 

bbs/list.jsp를 열어서 아래부분을 추가해준다. formatDate 태그를 사용하고 싶으면 taglib를 써준다.

게시판 첨부파일 업로드 기능 구현해보기

bbs/add.jsp

 <div class="mb-3">
	    <form:label path="bbsContent" class="form-label">첨부파일1</form:label>
	    <input type="file"  name="upfileList" class="form-control" />
	  </div> 
	  
	  <div class="mb-3">
	    <form:label path="bbsContent" class="form-label">첨부파일2</form:label>
	    <input type="file"  name="upfileList" class="form-control" />
	  </div>

file 인코딩을 해주기 위해 form 태그 안에 < enctype="multipart/form-data" >를 추가해준다.. 

<form:form enctype="multipart/form-data" modelAttribute="bbsVo" id="memForm" action="${pageContext.request.contextPath}/bbs/add.do" method="post" >

pom.xml 에 라이브러리를 등록해준다.

<!-- 파일 업로드를 위한 CommonsMultipartResolver 사용에 필요한 라이브러리 -->
			<dependency>
			    <groupId>commons-fileupload</groupId>
			    <artifactId>commons-fileupload</artifactId>
			    <version>1.4</version>
			</dependency>

이 라이브러리를 사용하려고 스프링에 알려주기 위해서 스프링 설정파일을 간다.

	<!-- 파일이 포함된 폼 데이터 처리를 담당하는 객체를 multipartResolver라는 이름으로 등록 -->
	<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		
	</beans:bean>

bbs.vo 파일관련 변수 넣기 

    //폼 데이터에 포함된 파일은 MultipartFile 변수로 받을 수 있다. 첨부파일이 여러개니까 list로 받는다.
    private List<MultipartFile> upfileList;

잘 들어갔는지 확인하기 위해 bbsController에 아래와 같이 작성해본다.

		MemberVo mvo = (MemberVo) session.getAttribute("loginUser");	
		vo.setBbsWriter(mvo.getMemId() );
		
		for(MultipartFile mf: vo.getUpfileList()) {
			System.out.println(mf.getOriginalFilename());
			System.out.println(mf.getSize());
		}
		
		int num = bbsService.insert(vo);
		return "redirect:/bbs/list.do";
	}

첨부파일 1개만 넣었기 때문에 아래와 같이 1개의 값만 나온다.

디비에 저장할 수 있게 해야한다. 

--첨부파일 테이블 생성
CREATE TABLE attach
( att_no NUMBER(10,0)--첨부파일 번호 
 ,att_org_name VARCHAR2(225) --원래파일명
 ,att_new_name VARCHAR2(225) --서버에 저장한 파일명
 ,att_bbs_no NUMBER(10,0) --첨부파일이 속한 게시글 번호
 ,PRIMARY KEY (att_no)
 ,FOREIGN KEY (att_bbs_no) REFERENCES bbs (bbs_no)
 );
 
 CREATE SEQUENCE att_seq;

attach paackage를 만들어주고 그 아래 Dao랑 Vo 를 만들어준다.

package com.exam.myapp.attach;


import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface AttachDao {

	public int insert(AttachVo vo
}
vo

package com.exam.myapp.attach;

import lombok.Getter;
import lombok.Setter;

@Getter @Setter
public class AttachVo {
	
	private int attNo;

    private String attOrgName;

    private String attNewName;

    private int attBbsNo;

}
mapper

<insert id="insert">
  	INSERT INTO attach
    (att_no, 
    att_org_name, 
    att_new_name, 
    att_bbs_no)
		VALUES
    ( att_seq.nextval
    , #{attOrgName}
    , #{attNewName}
    , #{attBbsNo}
    )

<insert id="insert">
  <!-- 자동생성되는 값은 파라미터 객체에 담아서 사용하기 위해서 selectKey사용 -->
  <!-- insert문 실쟁 전(BEFORE)에 SELECT 문을 실행하고 , 
  그 결과 INT값을 파라미터객체의 bbsNo 속성(변수)에 저장 -->
  <selectKey resultType="int" keyProperty="bbsNo" order="BEFORE">
  	select BBS_SEQ.NEXTVAL  FROM DUAL
  </selectKey>
  	INSERT INTO BBS
    (BBS_NO, 
    BBS_TITLE, 
    BBS_CONTENT, 
    BBS_WRITER, 
    BBS_REG_DATE, 
    BBS_COUNT)
	VALUES (
	  #{bbsNo},
	  #{bbsTitle},
	  #{bbsContent},
	  #{bbsWriter},
	    sysdate, 
	    0
	    )
  </insert>
serviceImpl

@Autowired
private AttachDao attachDao;

@Override
	public int insert(BbsVo vo) {
		//게시판 글 먼저쓰고 첨부파일 넣기
		int num = BbsDao.insert(vo);
		
		for(MultipartFile mf: vo.getUpfileList()) {
			System.out.println(mf.getOriginalFilename());
			System.out.println(mf.getSize());
			//MultipartFile 객체 mf의 정보를 AttachVo 객체에 담은 다음
			 AttachVo avo= new AttachVo();
			 avo.setAttOrgName(mf.getOriginalFilename());
			 
			 
			 //d드라이브에 upload 파일을 만들어준다. 경로를 아래에 넣어준다.
			 String newName = UUID.randomUUID().toString(); //중복확률이 매우 낮은 임의의 문자열 생성
			 try {
				 
				mf.transferTo(new File("D:/web/upload/" + newName) );//mf의 파일 내용을 지정한 파일로 저장
				avo.setAttNewName(newName); 		
				avo.setAttBbsNo(vo.getBbsNo());
				//AttachVo 객체의 정보를 attach테이블에 insert	
				attachDao.insert(avo);
			 }
			 catch (IllegalStateException | IOException e) {				
		     e.printStackTrace();
			} 
			
			
		}
		return num;
	}