+수업전 번외) 오류날수 있는 설정
[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="수정"> <a href="list">목록보기</a> <a id="a-delete">삭제</a> <a href="reply_view?bId=${content_view.bId}">답변</a></td>
</tr>
</form>
</table>
</body>
</html>
========================================================================================================================================================
부트스트랩
반응형웹을 완벽지원한다.
제이쿼리를 사용한다.
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.부트스트랩이란?
'코딩 > 수업 정리' 카테고리의 다른 글
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 |
댓글