휴먼교육센터 개발자과정 81일차

조하영·2022년 12월 1일
0

Spring : 프레임워크의 정의, version //기능이 많다. 버전별 지원하는 기능이 차이가 있다.

현업은 많은 기능을 경험한 사람을 좋아한다(30%정답, 절대적이지 않다.)
기능이 많기 때문에 프로젝트마다 반드시 사용하는 기능을 중점으로 타겟.
DI, 컨테이너, 컨트롤러>서비스>DAO구조, MVC2패턴 + 인터셉터 + 추가적인 기능(페이징, 파일첨부 등)
<추가>스프링시큐리티, 다양한 API사용

클라이언트의 요청> 컨트롤러(파라미터 받기,DB작업요청, view선택, 세션처리) >
View선택(데이터전달)> forward or redirect

로그인시 1)세션에 등록여부 판단 2)세션에 로그인정보를 저장

이것을 컨트롤러에서 할것인가? 이렇게 하면 어떤 불편한 점이 있을까?
불편한점: 서비스를 먼저 처리해준다고 하고 세션 등록여부 판단을 매번 해야한다.
개선점: 컨트롤러에 서비스를 처리해 주기전에 로그인 검사를 한 후 컨트롤러가 서비스를 처리
인터셉터는 컨트롤러에 처리하기 전이나 후에 동작하는 것. 대부분 컨트롤러 처리전에 많이 사용한다.

AOP:관점지향 프로그래밍(주 로직, 보조 로직, 미리규칙을 만든다. 주 로직이 특정시점에서 실행될 때
보조 로직이 특정시점에서 실행될때 보조로직이 동작하도록 미리 설정. 주로직은 자기일에 집중할 수 있다.
부수적인 작업을 할 필요없다.)

Maven: 프로젝트 관리, 라이브러리 관리방법, 디렉토리 구조이해

Mybatis: version, 정의(프레임워크), dao와 쿼리를 매핑하는 구조,sqlsession, sessionFactory, Datasource
Tomcat: 웹서버- 서버가 갖고 있는 데이터로 응답해주는 구조
was서버- 서버가 DB에 데이터를 요청하고 응답받아서 처리
Java : version, 버전에 따라 제공하는 문법이 있다. 8버전이 가장 많이 사용됨. 제네릭
Oracle : version, 관계형 데이터베이스, DDL, DML, DCL

세션: 네트워크 환경에서, 두 개 이상의 통신 장치들 사이의 대화 연결.
컴퓨터 프로세서들 사이에서, 서로를 인식한 후에 데이터 송수신을 마칠 때까지의 기간.
클라이언트의 정보를 웹서버에 저장하여 클라이언트가 요청을 할때 어떤 클라이언트의 요청인지 확인하기 위한 정보.

인터셉터
1.인터셉터 설정(servlet-context)

	<!-- 인터셉터 빈 생성 -->
	<beans:bean id="authenInterceptor" class="com.human.interceptor.AuthenticationInterceptor"></beans:bean>
	<!-- 인터셉터 설정, 인터셉터에 적용될 턴크롤러를 매핑으로 설정 -->
	<interceptors>
		<interceptor>
			<mapping path="/**"/><!-- /시작되는 모든것 -->
			<exclude-mapping path="/"/>
			<exclude-mapping path="/login**"/>
			<exclude-mapping path="/logout**"/>
			<exclude-mapping path="/resources/**" />
			<exclude-mapping path="/css/**" />
			<exclude-mapping path="/img/**" />
			<exclude-mapping path="/js/**" />
			<beans:ref bean="authenInterceptor"/>
		</interceptor>
	</interceptors>
  1. 인터셉터 클래스 생성
package com.human.interceptor;

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

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

public class AuthenticationInterceptor extends HandlerInterceptorAdapter{
	//인터셉터 기능을 활용하기 위해 상속받음
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		//클라이언트마나 세션이있다. 클라이언트가 보낸 쿠키의 아이디와 일치하는 세션의 객체를 가져와롸.
		HttpSession session = request.getSession();
		//가져온 세션에서 login 변수를 찾아서 리턴받아라. 리턴타입을 모르니 오브젝트 타입으로 받는다.
		Object obj = session.getAttribute("login");
		
		if(obj==null) {//로그인을 하지 않은 경우
			response.sendRedirect(request.getContextPath()+"/");
			return false;
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("PostHandle start");
		System.out.println("PostHandle end");
		super.postHandle(request, response, handler, modelAndView);
	}
}

페이징

1. 뷰작업
	<table id="pageNoTable">
		<tr style="text-align: center;">
			<td id="pageNo"><c:if test="${pvo.prev }">
					<span><a href="bbsList?page=${pvo.startPage -1 }">[이전]</a></span>
				</c:if> <c:forEach begin="${pvo.startPage }" end="${pvo.endPage }"
					var="idx">
					<a href="bbsList?page=${idx }"
						<c:if test="${pvo.page==idx }">style="color:yellowgreen;"</c:if>>${idx }</a>
				</c:forEach> <c:if test="${pvo.next }">
					<span><a href="bbsList?page=${pvo.endPage +1 }">[다음]</a></span>
				</c:if></td>
		</tr>
	</table>
  1. 컨트롤러작업
	@RequestMapping(value = "/bbsList", method = RequestMethod.GET)
	public String bbsList(Locale locale, Model model, @ModelAttribute("pvo") PageVO pvo) throws Exception {
		if(pvo.getPage()==null) {//클라이언트가 페이지 정보를 주지 않을때 기본값 1로 셋팅
			pvo.setPage(1);
		}
		int tatalpageCnt = bsrv.countBoard();
		pvo.setTotalCount(tatalpageCnt);
		List<BoardVO> bList = bsrv.selectAll(pvo);
		model.addAttribute("bList", bList);
		model.addAttribute("pvo", pvo);
		return "bbs/bbsList";
	}

3.페이지VO생성

package com.human.vo;

public class PageVO {
		   private int startNo;// 게시판테이블,회원테이블의 필드와는 직접관계없음.
		   private int endNo;
		   private int perPageNum=10;
		   private Integer page;// jsp단에서 null로 값이 올때 에러가 발생하지 않도록 Integer사용
		   private int totalCount;
		   private int endPage;
		   private int startPage;
		   private boolean prev;
		   private boolean next;
		   // 검색용 변수 2개 추가
		   private String searchType;
		   private String searchKeyword;

		   public int getEndNo() {
		      return endNo;
		   }

		   public void setEndNo(int endNo) {
		      this.endNo = endNo;
		   }

		   public String getSearchType() {
		      return searchType;
		   }

		   public void setSearchType(String searchType) {
		      this.searchType = searchType;
		   }

		   public String getSearchKeyword() {
		      return searchKeyword;
		   }

		   public void setSearchKeyword(String searchKeyword) {
		      this.searchKeyword = searchKeyword;
		   }

		   private void calcPage() {
		      // DB쿼리에서 사용... 시작데이터번호 = (jsp클릭한 페이지번호-1)*페이지당 보여지는 개수
			  endNo = this.page * perPageNum;
		      startNo = endNo-(perPageNum-1);


		      // page변수는 현재 jsp에서 클릭한 페이지번호
		      int tempEnd = (int) (Math.ceil(page / (double) this.perPageNum) * this.perPageNum);
		      // ceil함수는 천장 함수로 1.1 = 2, 2.1 = 3 으로 출력된다.
		      // 반대되는 바닥함수로 floor(), 반올림 함수로 round()가 있다.
		      // jsp에서 클릭한 페이지번호를 기준으로 끝 페이지를 계산한다.
		      this.startPage = (tempEnd - this.perPageNum) + 1;
		      // 시작 페이지 계산 클릭한page번호 10일때 까지 시작페이지는 1
		      if (tempEnd * this.perPageNum > this.totalCount) {
		         // 클릭한 page번호로 계산된 게시물수가 실제게시물개수 totalCount 클때
		         this.endPage = (int) Math.ceil(this.totalCount / (double) this.perPageNum);

		      } else {
		         // 클릭한 page번호로 계산된 게시물수가 실제게시물개수 totalCount 작을때
		         this.endPage = tempEnd;
		      }
		      this.prev = this.startPage != 1;// 시작페이지 1보다 크면 무조건 이전 페이지가 있음. true
		      this.next = this.endPage * this.perPageNum < this.totalCount;
		      // 클릭한 page번호로 계산된 게시물수가 실제 게시물 개수보다 작다면 다음페이지가 있음. true
		   }

		   public int getTotalCount() {
		      return totalCount;
		   }

		   public void setTotalCount(int totalCount) {
		      this.totalCount = totalCount;
		      calcPage();// totalCount 전제게시물개수가 있어야지 페이지계산을 할 수 있기 때문에
		   }

		   public int getEndPage() {
		      return endPage;
		   }

		   public void setEndPage(int endPage) {
		      this.endPage = endPage;
		   }

		   public int getStartPage() {
		      return startPage;
		   }

		   public void setStartPage(int startPage) {
		      this.startPage = startPage;
		   }

		   public boolean isPrev() {
		      return prev;
		   }

		   public void setPrev(boolean prev) {
		      this.prev = prev;
		   }

		   public boolean isNext() {
		      return next;
		   }

		   public void setNext(boolean next) {
		      this.next = next;
		   }

		   public Integer getPage() {
		      return page;
		   }

		   public void setPage(Integer page) {
		      this.page = page;
		   }

		   public int getStartNo() {

		      return startNo;
		   }

		   public void setStartNo(int startNo) {
		      this.startNo = startNo;
		   }

		   public int getPerPageNum() {
		      return perPageNum;
		   }

		   public void setPerPageNum(int perPageNum) {
		      this.perPageNum = perPageNum;
		   }
}

4.Mapper설정

	<select id="selectAll" parameterType="com.human.vo.PageVO" resultType="com.human.vo.BoardVO">
		select * from(select rownum count, a.* from (select * from board1 order by num desc) a) 
		where count between ${startNo} and ${endNo}
	</select> 

	<select id="countBoard" resultType="int">
		select count(*) from board1
	</select>
profile
공부하는 개발자

0개의 댓글