SprintTiles+Mybatis+Oracle+fileUpload,fileDown+페이징처리+검색어 구현
1.pom.xml 을 복사해서 작성
2.web.xml에서 DispatcherServlet을 지정 + DB연동하는 파일 불러오기(위치가 틀림)
3. DB에 테이블 생성
🍳메이븐 환경설정 파일이 다운로드 X
1.내 컴퓨터의 방화벽 해제하기
2.사용자계정명의 .m2의 repository폴더를 제거하고 다시 다운로드
web.xml을 읽어들여서 실행(요청이 들어왔을때 제일 먼저 읽어들이는 환경설정파일)
- 외부의 DB에 관련된 환경설정을 불러오는 경우(관련클래스,매개변수)
- 다른 경로에 DB연동파일을 설정하고 불러오는 방법
- <관례> 접두어(classpath):경로포함해서 불러올 환경설정파일명
- ex) config 폴더에 있는 applicationContext.xml 파일을 불러 오라는 의미(메모리에 로드)
- src/main/java : 환경설정(리소스번들파일,로그파일 설정,Mybatis 설정파일(DB 연동환경설정)) + 자바파일(컨트롤러 클래스,DAO,DTO)
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:config/applicationContext.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
- SpringDB 프로젝트 참고
- SpringMybatis 프로젝트 참고
- Mybatis설정이 필요(SqlSessionFactoryBean)
- (Mybatis) bean등록(SqlSessionFactoryBean)
1) configLcation->테이블에 대한 xml 파일을 불러올때
=> WEB-INF/SqlMapConfig.xml
2) dataSource->DB연결정보 멤버변수<!-- Mybatis설정이 필요(SqlSessionFactoryBean) --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:config/SqlMapConfig.xml" /> <property name="dataSource" ref="dataSource" /> </bean> <!-- 4 SqlSessionTemplate(sqlSession객체를 더 쉽게 얻어오기 위해서 설정 --> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean>
- DTO클래스의 별칭을 부여(선택)
- 접속후 불러올 파일의 리스트를 적어주는 부분을 작성한다.(DB에 관련된 파일을 불러온다.)
- 게시판의 공통적으로 사용하는 추상메서드
- List(레코드를 여러개 담을 객체)
- Map(검색분야, 검색어를 저장할 목적)
1. 글목록보기
- 총갯수 -> 페이징 처리때문에(검색분야, 검색어) -> 검색어에 대해서 갯수가 달라진다.
2. 총레코드수(검색어에 맞는 레코드수까지 포함)
✔1. springboard2 테이블에서 SQL작업(자료실의 글목록보기)
공식)
select rownum "별칭명",필드명,,,테이블별칭.*
from (
select 필드명,,,
from 테이블명
order by top-N 필드명(정렬이 되는 필드명) desc ->가장 최근
) 별칭
where 조건식(rownum<=top-N) ->에 맞는 값을 부여
서브쿼리를 주면 안쪽부터 시작(from ())
실행 순서
- boardList.jsp의 keyWord와 keyField
- 예외의 예외
- 검색은 특수기호가 붙으면 #가 아니라 $를 줘야 하지만 ||를 주면 #을 사용한다.
title like '%' || #{keyWord} || '%'
- a(별칭).* =>from안의 레코드를 전부 출력하라
- rownum rnum 앞에 정렬할 번호를 매기면서 가장 최근의 글 순서대로 정렬하라
<>
태그로 인식 되기 때문에 연산자로 인식되게 하기 위해서는<![CDATA[ sql문~ ]]>
CDATA옵션을 사용해야 한다.(where rnum>=10 AND rnum <=20
)#{start} AND rnum <=#{end}
: 범위를 지정해서 검색해서 화면에 출력하겠다.(where rnum>=#{start} AND rnum <=#{end}
)
✔2. 검색어에 해당하는 총레코드수 구하기(java.lang.Integer -> Integer -> int)
- 상속받아서 생성
- 인터페이스 상속 : BoardDao 인터페이스
- 클래스상속(Browse,,,) : sqlSessionDaoSupport 클래스
- SqlSessionDaoSupport 상속받는 이유 : SqlSession객체를 자동으로 반환 getSqlSession()
web.xml -> dispatcher-servlet.xml에서 처리
- 요청에 따라서 처리해주는 빈즈클래스만 등록
<bean class="com.board.dao.BoardDaoImpl" /> => DB객체 얻어오기 위해서 필요 <bean class="com.board.controller.ListController" /> => 자료실의 글목록보여주는 메서드를 호출하기 위해서 필요하다.(빈즈가 필요)
- tiles (ViewResolver)설정 -heder,footer,body 등 불러오기
개발자가 임의로 예외페이지 작성(화면에 출력하고 싶다.)- 예외페이지를 작성했을때 처리해주는 빈즈클래스 등록
- SimpleMappingExceptionResolver -> 웹상에서 에러가 발생(500,404,503,,,) -> 개발자가 작성한 예외처리 페이지를 출력시켜줄 수 있도록 해주는 역할
<props> <prop key="발생한 예외처리 클래스명">예외처리 페이지명</prop> java.lang.NullPointerException 부모형으로 지정한 이유 -> 상속받은 모든 자식클래스의 에러를 잡아줄수가 있기 때문이다. <props>
- tiles설정=>boardList.jsp가 출력 설정
- tiles-def.xml파일 설정부분
- css.js부분은 jsp파일로 경로를 지정해서 불러와야 된다.
- 각 영역에 대한 속성값을 부여한다.
<tiles:insertAttribute name="css" />
- 식별자(tiles), 액션태그명(insertAttribute), 속성명(name="css") => 지정한 속성명에 해당하는 파일 불러오기
//추가(com.board.util에 PagingUtil, StringUtil)
- 페이징처리 (PagingUtil 클래스),StringUtil.java
✔로그 객체
- 로그객체를 불러오겠다는 선언문
:import org.apache.log4j.Logger;
- 로그객체 생성(디버깅용으로 에러를 잡기위해서 사용되는 구문을 이용하기 위해서 필요하다.)
- log객체 생성 이유 : 디버깅 용으로 매개변수 전달되는지 확인 ex) System.out.println("출력변수="+변수명) => ?는 출력할 수 없다.
- 자동으로 Setter Method 호출X 의존성객체 넣어줌(byType)
=> @Autowired<->@Resource
@RequestParam(value="pageNum",defaultValue="1") int currentPage
- pageNum매개변수에 값을 전달 못받으면 default값으로 1을 설정해준다.(글목록 1페이지)
- 정상적으로 받으면 currentPage로 반환 받는다.
✔요청을 받아서 처리해주는 과정
✔검색분야, 검색어를 전달
- parameteType="map" (2. Map객체)
✔총레코드수 또는 검색된 글의 총레코드수
- count(*)
✔페이징 처리
1.현재페이지 2.총레코드수 3.페이지당 게시물수 4.블럭당 페이지수 5.요청명령어
검색분야,검색어
✔레코드가 없다면
- 에러유발 -> 테이블에 데이터를 하나 넣어주면 에러가 유발되지 않는다.
- count(*)의 레코드가 0, " " 이면 -> 테이블에 데이터를 임의로 하나 저장해야 에러가 안난다.
- 리소스번들을 이용해서 처리(~.properties) 글쓰기(자료실의 글쓰기 및 업로드할때 필요)
- jdbc.properties(DB)
- 공통 문자열 메세지를 파일로 등록->불러와서 출력
- 유효성 검사를 위한 에러메세지를 파일로 등록 -> 불러와서 출력
- messages.label->패키지명.불러올파일명.properties(확장자가 생략됨)
- messages.validation->messages패키지에 있는 validattion.properties파일
- 리소스번들파일을 불러오는 환경설정
- 리소스번들파일 ->웹상에서 필요로하는 문자열이나 유효성검사에 관련된 부분을 불러올 수 있도록
- 파일 : messages(패키지명).label(불러올 파일명)~.properties이 생략
<property name="defaultEncoding" value="utf-8" />
설정- @Autowired 사용을 위해
<bean class="com.board.controller.WriterController" />
추가파일 업로드 기능 추가
- CommonsMultipartResolver -> 업로드 관여하는 클래스 => 빈즈로 등록(모델2 X)
- maxUploadSize(최대 업로드 크기를 지정)
- defaultEncoding(한글처리 부분설정)
- 작성시 byte단위로 작성해야한다.(52428800 -> byte 단위)
- 50MB -> 51,200kb -> 52,428,800byte
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="52428800" /> <property name="defaultEncoding" value="utf-8" /> </bean>
- 프로젝트에서 공통으로 사용되는 기능만 모아놓은 클래스 => 공통관심 클래스(AOP)
- 파일업로드시 업로드할 경로지정 및 파일의 새이름을 부여(=공통모듈)(자바스크립트계열 언어)
✔업로드 및 다운로드 경로 -> 정적 상수
public static final String UPLOAD_PATH="C:/webtest/Jsp/sou/SpringFileBoard3/src/main/webapp/upload";
✔1. 탐색기의 원본파일명만 받아서 처리해주는 메서드
- 새이름 규칙 -> 시스템날짜 + 랜덤숫자(0~49) => 조합
✔2. 실제로 새로운 파일명을 변경하는 역할 -> 확장자 구분 -> 변경된 이름만 구해서 변경할 수 있다.
- ex) testkiamaaaaaa.txt(뒤에서 검색)->1234aDSDDA.TXT
- lastIndexOf : 뒤에서부터 인덱스 번호
- 확장자를 따로 저장하고 -> 파일명을 따로 구한다. => 둘을 합친다.
✔3. 글수정 -> 업로드된 파일도 수정 -> 기존 업로드된 파일 삭제 -> 새로 업로드
- 파일 삭제 -> 수정목적
3.글쓰기 -> 최대값 구하기
public int getNewSeq();
- 자료실의 업로드(글쓰기)
public void insert(BoardCommand board);
- id이름을 찾아서 실행한다.(메서드명과는 무관하다.)
- 파일이름은 문자로 저장한다고 타입(문자로)을 지정해주어야 한다.
tilesdef.xml
✔boardWrite.jsp
- enctype => 파일 첨부를 하기위해서 필요하다.
- spring:message 액션태그 => code="불러올 키값"
<spring:message code="키명" />
=> 타이틀 제목출력할때- form:errors 액션태그 => path="적용필드명(DTO중 입력받은 필드명)"
- Validator을 상속을 받아서 작성한다.
- com.board.validator -> BoardValidator.java
- 리소스번들=>유효성 검사=>웹에 출력(boardWrite.jsp) => jQuery를 써도 상관없다.
- validation.properties => 에러코드와 메세지(에러코드명=값)
유효성 검사를 하는 방법 : Validator을 상속을 받아서 작성한다.1.유효성 검사를 할 클래스명을 지정해주는 상속받은 메서드
- 형식) return DTO클래스명.class.isAssignableFrom
2. 유효성 검사를 해주는 상속받은 메서드 작성
- WriteController에서 호출한다.
- 유효성 검사
- 1.입력받을 대상자(DTO객체(=커맨드객체)
- 2.에러정보를 담을객체명
- 입력하지 않았거나 공백을 체크해주는 메서드 -> 에러정보를 저장(에러객체)
- 1.에러객체명(errors)
- 2.적용시킬 필드명(boardWrite.jsp)
- 3.적용시킬 에러코드명(validation.properties)
- ex) required.pwd
- 경로 -> com.board.controller
- 하나의 요청명령어 -> 하나의 컨트롤러만 사용 X
- 하나의 컨트롤러 => 여러개의 요청명렁어를 등록해서 사용이 가능 (ex - writeForm.do, write.do)
- 같은 요청 명령어 -> Get or Post방식으로 전송할지를 결정
(write.do(페이지 이동) -> write.do(저장))
- method=RequestMethod.GET => @GetMapping("/write.do")
- method=RequestMethod.POST => @PostMapping("/write.do")
1. 글쓰기 폼으로 이동(Get방식)
- 페이지 이동
2. 에러메세지 출력
다시 초기화가 가능하게 설정 -> @ModelAttribute("커맨드객체 별칭")
3. 입력해서 유효성검사
- 에러발생 -> DB저장후 -> boardList.jsp로 이동
- BindingResult -> 유효성 검사때문에 필요(에러정보 객체를 저장)
- boardWrite.jav의 input value 값을 가져와서 멤버변수(command <- 별칭)에 값이 저장되게 만든다.
- enctype->파일 첨부를 하기위해서 필요
- form:액션태그명~(에러메세지를 출력)
- spring:message 액션태그->code="불러올 키값"
- form:errors 액션태그=>path="적용필드명(DTO중 입력받은 필드명)"
- 업로드 하기위해서 form태그에
- enctype="multipart/form-data" method="post" 적용 (업로드 전송하겠다는 의미)
- <spring:hasBindErros name="커맨드객체명"/> ->에러발생시 처리
- <form:errors path="커맨드객체명" />->폼안에서의 입력받을시 처리
- src/main/java폴더에 log4j.xml파일을 복사해서 넣어주어야 한다.
pom.xml 추가
: 로그객체를 이용해서 출력
log4j.xml