본문 바로가기
코딩/수업 정리

21.02.10 [056] Wed

by 6^6 2021. 2. 10.
728x90

+수업전 번외) 오류날수 있는 설정

[root-context.xml]
		....
	<mybatis-spring:scan
      base-package="edu.bit.board.mapper" />
		....
        //이 부분이 mapper를 스캔하는건데
        //만약 "edu.bit.board" 라고만 지정한다면 해당 모~~든 파일 다 검사한다.(오류남)
        //만약 매퍼위치가 두군데 이상이다 하면 ,로 구분해서 하나 더쓴다.

 

 

인터셉터

↓이거 생성

 

authorities - 권한

 

 

 

일단 이 sql문 커밋하기

create table users(
   username varchar2(50) not null primary key,
   password varchar2(100) not null,
   enabled char(1) DEFAULT '1'
);
create table authorities (
   username varchar2(50) not null,
   authority varchar2(50) not null,
   constraint fk_authorities_users foreign key(username) references users(username)
);
create unique index ix_auth_username on authorities (username,authority);

commit;

insert into users (username,password) values('user','user');
insert into users (username,password) values('member','member');
insert into users (username,password) values('admin','admin');

commit;

insert into AUTHORITIES (username,AUTHORITY) values('user','ROLE_USER');
insert into AUTHORITIES (username,AUTHORITY) values('member','ROLE_MANAGER');
insert into AUTHORITIES (username,AUTHORITY) values('admin','ROLE_MANAGER');
insert into AUTHORITIES (username,AUTHORITY) values('admin','ROLE_ADMIN');

commit;

 

 

 

<Filter, Interceptor, AOP의 흐름>

dispatcher Servlet에서 controller를 가는데 중간에 가로챈다.그게 preHandler와 postHandler

preHandler와 postHandler이 두개 함수 컨트롤만 하면 끝이다. 얘네 두개는 스프링이 생성한다.(?)

 

로그인 식별하는것 구현하기

 

-세션(Session)을 구현하기 위한 HttpServletRequest 사용-

스프링 MVC에서 세션은 HttpServletRequest혹은HttpSession을사용해서 구현할 수 있다.

여기서는 HttpServletRequest를 통한 세션 생성방법을 알아보겠다.

[UserVO.java]
package edu.bit.board.vo;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class UserVO {
	private String username;
	private String password;
	private int enambled;	

}
[LoginMapper.java]
package edu.bit.board.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import edu.bit.board.vo.UserVO;

@Mapper//넣어도 되고 안넣어도 되고
public interface LoginMapper {

	//자바문법을 마이바티스 문법이랑 연결해줘야하는데 이 파라미터이름(@Param("이부분"))을 넘겨준다는 뜻이다.
	   @Select("select * from users where username = #{username} and password = #{password}")
	   public UserVO logInUser(@Param("username") String username,@Param("password") String password);
	}
	

 

[login.jsp]
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
   <title>로그인</title>
</head>
<body>
<%
   String path = request.getContextPath();
%>
<%=path%>
<c:if test="${user == null}"><!-- controller에서 model로 넘어온다. 컨트롤러에서 setAttribute로 세션에 등록했기때문에 넘어올수 있는것-->
<form role="form" method="post" autocomplete="off" action="${pageContext.request.contextPath}/login"><!--"<%=path%>/login"> -->
   <p>
      <label for="userId">아이디</label>
      <input type="text" id="userId" name="id" />
   </p>
   <p>
      <label for="userPass">패스워드</label>
      <input type="password" id="userPass" name="pw" />
   </p>
   <p><button type="submit">로그인</button></p>
<!--    <p><a href="/member/register">회원가입</a></p> -->
</form>
</c:if>

<c:if test="${msg == false}">
   <p style="color:#f00;">로그인에 실패했습니다. 아이디 또는 패스워드를 다시 입력해주십시오.</p>
</c:if>

<c:if test="${user != null}">
   <p>${user.username}님 환영합니다.</p>
   
   <!-- <a href="member/modify">회원정보 수정</a>, <a href="member/withdrawal">회원탈퇴</a><br/> -->
   <a href="<%=path%>/list">게시판 리스트</a><br>
   <a href="<%=path%>/logout">로그아웃</a>
   
</c:if>

</body>
</html>
[LoginService.java]
package edu.bit.board.service;

import org.springframework.stereotype.Service;

import edu.bit.board.mapper.LoginMapper;
import edu.bit.board.vo.UserVO;
import lombok.AllArgsConstructor;

@Service
@AllArgsConstructor
public class LoginService {

	private LoginMapper loginMapper;

	public UserVO loginUser(String id, String pw) {
		return loginMapper.logInUser(id, pw);
	}

}
[LoginController.java]
package edu.bit.board.controller;

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

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import edu.bit.board.page.Criteria;
import edu.bit.board.page.PageVO;
import edu.bit.board.service.BoardService;
import edu.bit.board.service.LoginService;
import edu.bit.board.vo.BoardVO;
import edu.bit.board.vo.UserVO;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;

@Log4j // 롬복이
@AllArgsConstructor // 롬복이
@Controller
public class LoginController {

	private LoginService loginService;

	@GetMapping("/")
	public String home() {
		log.info("home");
		return "login";
	}
	
	
	// 로그인
	//@RequestMapping(value = "/login", method = RequestMethod.POST)
	@PostMapping("/login")
	public String login(HttpServletRequest req, RedirectAttributes rttr) throws Exception {
	//public String login(UserVO userVO){//안에 command객체(BoardVO)를 적어주면 된다.-스프링이 알아서 불러오기때문
	//이 방법이 최신방법. 그 위에건 옛날방법인데 수업은 옛날방식으로 코드짬.
		log.info("post login");

		

		String id = req.getParameter("id");
		String pw = req.getParameter("pw");
		
		// Session 처리를 위한 Session 객체 HttpServletRequest 안에 있음
		HttpSession session = req.getSession();//세션으로 id와 pw를 넣어준다.
		//각각의 유저가 치고 들어오게되면 각 유저마다 session영역(메모리할당)을 줘서 30분간 유지되게하게끔 그 영역을 서버가 가지고있다.
		//이 session영역 모르겠으면 다시 공부. 복습 필수임★★
		
	
		UserVO login = loginService.loginUser(id, pw);
		//login이 결국 해당 user를 말하는것.

		if (login == null) {
			session.setAttribute("user", null);
			/*
			 * Spring3 에서 제공하는 RedirectAttributes를 사용하면 redirect post 구현이 가능합니다.
			 * 
			 * 하지만 일회성입니다. 새로고침하면 날라가는 데이터이므로 사용목적에 따라서 사용/불가능 판단을 잘 하셔야 할거 같습니다.
			 */
			rttr.addFlashAttribute("msg", false);
			//rttr은 새로고침하면 로그인된거 로그아웃되는 설정. 있어도되고 없어도되고.
			
		} else {
			session.setAttribute("user", login);
		}
		return "redirect:/";
	}

	// 로그아웃
	//'/logout'는 로그아웃을 하라는 요청을 나타내는 url이다. 
	//request 객체의 세션을 얻은 후 그 세션을 invalidate 메서드로 비활성화 시키면 세션이 끊긴다(로그아웃 됨).
	//이때부터 웹사이트에 연결이 되도 새로운 사용자 정보를 통해 로그인을 해야한다.
	@RequestMapping(value = "/logout")
	public String logout(HttpSession session) throws Exception {
		log.info("/member/logout");

		session.invalidate();
		//메모리로 날려주는것.

		return "redirect:/";
	}
}

engkimbs.tistory.com/696 관련 설명볼것

 

[BoardInterceptor.java]
package edu.bit.board.controller;

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

import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import edu.bit.board.vo.UserVO;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;

@Log4j // 롬복이
public class BoardInterceptor extends HandlerInterceptorAdapter {
//HandlerINterceptorAdaptor을 상속해줘야하는것은 무조건 규칙!!
	// 인터셉터 함수는 두개의 함수를 상속받을 수 있다.

	// preHandle() : 컨트롤러보다 먼저 수행되는 메서드
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("preHandle 실행");
		// session 객체를 가져옴
		HttpSession session = request.getSession();

		// login처리를 담당하는 사용자 정보를 담고 있는 객체를 가져옴
		UserVO user = (UserVO) session.getAttribute("user");

		if (user == null) {
			log.info("user가 null");
			// 로그인이 안되어 있는 상태이므로 로그인 폼으로 다시 돌려보냄(redirect)
			response.sendRedirect(request.getContextPath());

			return false; // 더이상 컨트롤러 요청으로 가지 않도록 false로 반환함
		}

		// preHandle의 return은 컨트롤러 요청 uri로 가도 되냐 안되냐를 허가하는 의미임
		// 따라서 true로하면 컨트롤러 uri로 가게 됨.
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

		super.postHandle(request, response, handler, modelAndView);
		System.out.println("postHandle 실행");
	}

}

 

 

 

==================================

위에 session관련 설명

<부하테스트>

1. 시스템테스트와 같은말

2.서버가 최대 몇명(동시접속자수)까지 견딜수 있는가?

쿠키에 session아이디를 비교해서 식별한다.

 

그럼 spring에서는 session을 어떻게 처리?

위에 코드있음..

 

 

 

그리고!!!!!가장 중요한!!!!

인터셉터 - servlet-context.xml설정

root-context에 넣어도 돌아가긴하지만 왜 servlet-context에 넣을까 하면 Controller이전에 있는부분은 servlet이라 부르는데 controller이전에 인터셉터가 들어가니까 servlet-context.xml에 넣어준다. root-context.xml은 controller이후에 있다.

[servlet-context.xml]
....
<!-- 인터셉터 객체 생성 -->
	<beans:bean id="boardInterceptor"
		class="edu.bit.board.interceptor.BoardInterceptor">
	</beans:bean>
<!--Interceptor 설정 -->
	<interceptors>
		<interceptor>
			<mapping path="/list" />
			<exclude-mapping path="/resources/**" />
			<beans:ref bean="boardInterceptor" />
		</interceptor>
	</interceptors>
    ....

 

 

 

========================================================================================================================================================

어제 restful 게시판 수정하는것 구현

[RestBoardController.java]
    // 수정
	   @PutMapping("/board/{bId}")
	   public ResponseEntity<String> rest_update(@RequestBody BoardVO boardVO, ModelAndView modelAndView) {
	// ResponseEntity는 restful을 위해 제공되는 대표적인 것 중 하나이다.

	      ResponseEntity<String> entity = null;

	      log.info("rest_update..");
	      try {
	         
	         int rn = boardService.modifyBoard(boardVO);
	         log.info("update 넘어온 숫자:::::" + rn);
		// 삭제가 성공하면 성공 상태메시지 저장
	         entity = new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
	         
	      } catch (Exception e) {
	         e.printStackTrace();
		// 댓글 삭제가 실패하면 실패 상태메시지 저장
	         entity = new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
	      }
	      
	      return entity;
	   }
[BoardService.java]
public int modifyBoard(BoardVO boardVO);
[BoardServiceImpl.java]
@Override
	public int modifyBoard(BoardVO boardVO) {
		// TODO Auto-generated method stub
		return mapper.modify(boardVO);
	}
[BoardMapper.java]
public int modify(BoardVO boardVO);

 

[rest_content_view.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE>
<html>
<head>
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
   $(document).ready(function(){
       
      //https://m.blog.naver.com/PostView.nhn?blogId=moonv11&logNo=220605582547&proxyReferer=https:%2F%2Fwww.google.com%2F
      $("#updateForm").submit(function(event){
         
         event.preventDefault();
         
           var name = $("#bName").val();
           var bTitle = $("#bTitle").val();
           var bContent = $("#bContent").val();           
           var bId = $("#bId").val();
           
           console.log(bContent);
           console.log($(this).attr("action"));
           
           
           var form = {
                 bId: bId,
                 bName: name,
                   bContent: bContent,
                   bTitle: bTitle
           };
          //dataType: 'json',
           $.ajax({
             type : "PUT",
             url : $(this).attr("action"),
             cache : false,
             contentType:'application/json; charset=utf-8',
              data: JSON.stringify(form), 
             success: function (result) {       
               if(result == "SUCCESS"){
                  //list로 
                  
                  $(location).attr('href', '${pageContext.request.contextPath}/restful/board/')                            
               }                       
             },
             error: function (e) {
                 console.log(e);
             }
         })          
   
       }); // end submit()
       
   }); // end ready()
</script>
</head>
<body>
   <table id="list-table" width="500" cellpadding="0" cellspacing="0" border="1">
      <form id="updateForm" action="${pageContext.request.contextPath}/restful/board/${content_view.bId}" method="post">
         <input type="hidden" id="bId" value="${content_view.bId}">
         <tr>
            <td> 번호 </td>
            <td> ${content_view.bId} </td>
         </tr>
         <tr>
            <td> 히트 </td>
            <td> ${content_view.bHit} </td>
         </tr>
         <tr>
            <td> 이름 </td>
            <td> <input type="text" id="bName" value="${content_view.bName}"></td>
         </tr>
         <tr>
            <td> 제목 </td>
            <td> <input type="text" id="bTitle" value="${content_view.bTitle}"></td>
         </tr>
         <tr>
            <td> 내용 </td>
            <td> <textarea rows="10" id="bContent" >${content_view.bContent}</textarea></td>
         </tr>
         <tr >
            <td colspan="2"> <input type="submit" value="수정"> &nbsp;&nbsp; <a href="list">목록보기</a> &nbsp;&nbsp; <a id="a-delete">삭제</a> &nbsp;&nbsp; <a href="reply_view?bId=${content_view.bId}">답변</a></td>
         </tr>
      </form>
   </table>
   
</body>
</html>

 

 

========================================================================================================================================================

부트스트랩

bootstrap_get_started.asp

반응형웹을 완벽지원한다.

 

제이쿼리를 사용한다.

 

 

 

www.w3schools.com/bootstrap4/bootstrap_grid_basic.asp

www.w3schools.com/bootstrap4/tryit.asp?filename=trybs_container_resp

이것들 소스는 잘 알아둘것

 

Tryit Editor v3.6

Bootstrap Example Responsive Containers Resize the browser window to see the effect. .container-sm .container-md .container-lg .container-xl

www.w3schools.com

 

타이포그래피

 

 

getbootstrap.com/docs/4.0/examples/sign-in/

 

 

 

오늘의 문제

1.restful을 적용하여 게시판을 구현을 완성하시오.(URL 설계 포함)..

 

dlwjdcks5343.tistory.com/118
2. 부트스트랩으로 로그인 화면구현후 interceptor 적용하여 로그인한 유저에게만 게시판이 보이도록 하시오.

+ 부트스트랩 이미지 -> 정적리소스 처리도 해야하고 
+오늘 배운 로그인 Interceptor 적용


3.intercptor의 개념에 대하여 설명하시오.
4.부트스트랩이란?

 

 

 

 

 

 

 

 

 

 

728x90

'코딩 > 수업 정리' 카테고리의 다른 글

21.02.16 [058] Tue  (0) 2021.02.16
21.02.15 [057] Mon  (0) 2021.02.15
21.02.09 [055] Tue  (0) 2021.02.08
21.02.08 [054] Mon  (0) 2021.02.08
21.02.05 [053] Fri  (0) 2021.02.05

댓글