✍ Today I Learned
- 지금까지 JSP의 기능에 대해 공부했다면, 이번엔 제대로 웹페이지를 만들어보자.
- 기본 게시판 기능, 로그인/로그아웃 기능, 파일 업로드 기능, 댓글 기능 등이 포함될 예정이다.
- MyBatis 프레임워크를 사용할 것이다.
[환경 설정]
- New → Dynamic Web Project로 새로운 프로젝트를 생성한다. (Generate web.xml deplyment descriptor 체크 필수)
- 기본으로 생성되던 주석을 삭제한다.
Window → Prefernces → Java → Code Style → Code Templates에서 Code에 있는 주석 부분을 전부 지워준다.
[web.xml 설정]
- WEB-INF 폴더에 web.xml 파일을 만들고 다음과 같이 작성한다.
- 이번엔 web.xml에서 Controller와 servlet의 맵핑을 설정하지 않고, WebServlet annotation을 이용할 것이다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>04_final_jsp_crud</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>log4j2Config</param-name>
<param-value>/WEB-INF/log4j2.xml</param-value>
</context-param>
<context-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
</web-app>
[context.xml 설정]
- Servers → Tomcat → contex.xml 파일에 추가했던 Resource 부분을 주석 처리한다. (Mybatis를 사용할 예정)
[라이브러리 설정]
- 새롭게 설치할 라이브러리는 5개이다.
- commons-fileupload - 파일 첨부
- commons-io - 파일 첨부
- mybatis - 데이터베이스를 효율적으로 접근하고 사용하기 위한 DB 전용 퍼시스턴트 프레임워크
- json-simple - json 데이터 처리
- thumbnailator - 썸네일 이미지 생성
- 저번에 다운받은 라이브러리까지 총 9개의 라이브러리를 장착시켜준다.
[데이터베이스 구조]
- 데이터 베이스에 생성할 테이블은 다음과 같다
- memeber - 회원
- board - 게시판
- comment - 댓글
[프로젝트 구조]
- 저번과 비슷하게 src/mian/java 폴더에 6개의 패키지를 생성한다.
- mapper패키지에는 SQL문을 작성한 xml 파일들이 담기게 된다.(MyBatis)
[MyBatisConfig.xml 설정]
- MyBatis 공식문서를 참고하여 orm 패키지에 config를 작성한다.
- 후에 작성할 mapper 파일의 위치를 미리 정의해둔다.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias type="domain.MemberVO" alias="mvo"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jspdb"/>
<property name="username" value="jspuser"/>
<property name="password" value="mysql"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/memberMapper.xml"/>
</mappers>
</configuration>
[DataBaseBuilder.java 설정]
- SqlSessionFactory 타입의 factory를 리턴하는 getFactory 메서드를 생성한다.
- static 블록에서 SqlSessionFactoryBuiler를 이용해 factory 값을 설정한다.
package orm;
import java.io.IOException;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DataBaseBuilder {
private static Logger log = LoggerFactory.getLogger(DataBaseBuilder.class);
private static SqlSessionFactory factory;
static {
try {
factory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsReader("orm/MybatisConfig.xml"));
} catch (IOException e) {
log.info(">>> Mybatis configuration Error");
e.printStackTrace();
}
}
public static SqlSessionFactory getFactory() {
return factory;
}
}
[DB schema.sql]
- src > main > webapp > resources 폴더에 schema.sql 파일을 생성한다.
- member, board, comment 테이블과 각 컬럼을 생성한다.
- 개발 전에 pk - fk 관계를 설정하면 개발할 때 수정, 삭제 테스트에 제한이 있으므로 개발 후 수정 및 삭제 기능에 이상이 없는지 테스트하고 관계 설정을 추가하여 최종 테스트 후에 완료하는 것이 효율적이다.
[부트스트랩 템플릿 이용]
- 효율성을 위해 프론트엔드쪽은 부트스트랩 템플릿을 이용해보자. 부트스트랩 5를 이용하는 무료 템플릿 중 로그인폼, 회원가입 폼, 리스트 폼(게시판용)이 있는 템플릿을 선택했다. (부트스트랩 무료 템플릿)
[JSP 페이지 영역 분리]
- 부트스트랩 템플릿의 부분 부분을 사용하여 header, footer로 나누고, 편리한 사용을 위해 템플릿으로 설정한다.
- 페이지 내 a 태그의 이동경로는 모두 "/"로 변경한다.
- jsp 템플릿으로 index.jsp를 생성한다.
[톰캣 서버 설정]
- 톰캣 서버에 이전 프로젝트는 Remove 하고 현재 프로젝트를 Add 한다.
- 톰캣 서버 더블 클릭 → Modules로 이동하여 Path를 "/"로 설정한다. (/는 루트를 의미한다.)
[MemberVO.java]
- 가장 먼저 member 관련 기능을 구현해보자.
- join, modify, login 상황별 생성자를 만들고 getter, setter를 생성한다.
- detail은 따로 생성하지 않는다.
[REST API]
- REST란? Representational State Transfer의 약자로 자원의 이름을 구분하여 해당 자원의 상태를 주고받는 모든 것을 의미한다.
- HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고,
- HTTP Method(POST, GET, PUT, DELETE)를 통해
- 해당 자원(URI)에 대한 CRUD Operation을 적용하는 것!
- REST API란? REST의 원리를 따라 HTTP 프로토콜을 활용한 소프트웨어 개발 아키텍처의 한 형식을 의미한다. 최근 플랫폼의 형태가 다양해지면서 멀티 디바이스의 통신에 대응해야 했기 때문에 REST API가 등장하게 되었다.
- REST API 설계를 위한 규칙은 다음과 같다.
- URI는 동사보다 명사를, 대문자보다 소문자를 사용한다.
- URI 마지막 문자로 슬래시(/)를 포함하지 않는다.
- 언더바 대신 하이픈을 사용한다.
- 파일 확장자는 URI에 포함하지 않는다.
- 행위를 포함하지 않는다.
- RESTful API란? REST API의 설계 규칙을 올바르게 지킨 시스템을 의미한다.
- JSP에서 RESTful을 완벽하게 구현하기에는 어려움이 있다.
[MemberCtrl.java]
- Controller는 class가 아닌 servlet으로 생성한다. URL mappings는 /mem/*로 설정하고,
doPost()
,doGet()
,service()
메서드를 선택한다. service()
에 모든 로직을 작성한다. 먼저 request와 response객체를 UTF-8로 인코딩하고, path 경로를 추출하여 switch문을 작성한다.- action은 따로 만들지고 않고 controller에 로직을 처리한다.
- 각 switch case에서 역할을 수행하고, RequestDisptcher 클래스를 이용해 destPage로 데이터를 전달한다.
- 모든 경로는 절대 경로로 설정한다.
[MemberDAO]
- 설정해둔 빌더를 이용해 SqlSession을 생성한다.
- SqlSession에서 제공하는 메서드를 통해 DB를 조작할 수 있다. 메서드의 첫 번째 파라미터는 실행시킬 쿼리의 주소 값을 작성해야 한다.
package repository;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import domain.MemberVO;
import orm.DataBaseBuilder;
public class MemberDAOImpl implements MemberDAO {
private static Logger log = LoggerFactory.getLogger(MemberDAOImpl.class);
private SqlSession sql;
private final String NS = "MemberMapper."; // NS = NAMESAPCE 내가 정한 공간 이름
public MemberDAOImpl() { // 싱글톤 패턴
new DataBaseBuilder();
sql = DataBaseBuilder.getFactory().openSession();
}
@Override
public int insert(MemberVO mvo) {
int isUp = sql.insert(NS+"reg", mvo); // 첫번째 파라미터는 내가 실행시킬 쿼리의 주소값
if(isUp > 0) {
sql.commit(); // DB에 변경사항이 있다면 커밋 명령어를 작동시켜야 함
}
return isUp;
}
}
[memberMapper.xml]
- 클래스나 인터페이스를 제외한 나머지의 파일 이름은 가급적 소문자로 시작하는 것이 좋다.
- MyBatis 공식문서를 참고하여 mapper 패키지에 memberMapper.xml을 생성하고 member에 관한 쿼리를 작성한다.
- DAOImpl에서 작성했던 namespace="MemberMapper"를 그대로 작성하고, 각 쿼리에 id를 지정한다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="MemberMapper">
<insert id="reg" parameterType="mvo">
insert into member (email, pwd, nick_name)
values (#{email}, #{pwd}, #{nick_name})
</insert>
</mapper>
[CRUD, 로그인/로그아웃 기능 구현]
- 여태까지 했던 방식으로 member에 관한 CRUD를 구현하고, 저번 시간에 배운 Session을 이용하여 로그인/로그아웃 기능을 구현하였다.
- 권한에 따라 다르게 보이는 화면도 모두 처리해주었다.
- 로그인 후, 로그인 버튼 로그아웃으로 변경
- 로그인 후, 화면에 회원 email, nick_name, grade 출력
- 로그인 후, 본인의 nick_name을 클릭하면 회원 수정 페이지로 이동
- 회원가입 성공 → 로그인 페이지로 이동하면서 성공 메시지
- 회원 수정 성공 → 회원 리스트 페이지로 이동하면서 성공 메시지
- 회원 탈퇴 성공 → 회원 리스트 페이지로 이동하면서 성공 메시지
- 로그아웃 성공 → 인덱스 페이지로 이동하면서 성공 메시지
- 로그인 실패 → 인덱스 페이지로 이동하면서 실패 메시지
- 한참을 찾아 헤매던 에러는 역시 오타였다😂 특히나 쿼리문에서의 오타는 치명적이기 때문에 주의 또 주의하자!
'📝 TIL' 카테고리의 다른 글
[TIL] JSP 댓글 기능 구현 (Comment) (1) | 2022.06.21 |
---|---|
[TIL] JSP 웹페이지 만들기2 (Board) (0) | 2022.06.20 |
[TIL] JSP 세션(session)으로 로그인/로그아웃 구현 (0) | 2022.06.16 |
[TIL] JSP로 CRUD 구현2 (0) | 2022.06.15 |
[TIL] JSP로 CRUD 구현 (0) | 2022.06.14 |