안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
검색 페이징 처리
Content 영역
Controller
AdminMemberFinder
@WebServlet("/admin/memberFinder")
public class AdminMemberFinder extends HttpServlet {
private static final long serialVersionUID = 1L;
private MemberService memberService = new MemberService();
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// 1. 사용자 입력값 처리
int cPage = 1;
int numPerPage = 10;
try {
cPage = Integer.parseInt(request.getParameter("cPage"));
} catch(NumberFormatException e) {}
String searchType = request.getParameter("searchType");
String searchKeyword = request.getParameter("searchKeyword");
int start = ((cPage - 1) * numPerPage) + 1;
int end = cPage * numPerPage;
Map<String, Object> param = new HashMap<>();
param.put("searchType", searchType);
param.put("searchKeyword", searchKeyword);
param.put("start", start);
param.put("end", end);
// 2. 업무로직
// a. content 영역
List<Member> memberList = memberService.findMemberLike(param);
// 3. view단 처리
request.setAttribute("memberList", memberList);
request.getRequestDispatcher("/WEB-INF/views/admin/memberList.jsp").forward(request, response);
} catch(Exception e) {
e.printStackTrace();
throw e;
}
}
}
cPage는 현재페이지, numPerPage는 보여줄 정보의 수를 의미합니다.
이 값들을 이용하여 between ? and ? 으로 start, end값을 지정해주어 한 페이지에 보여지는 개수를 조정해주었습니다.
Service
MemberService
public List<Member> findMemberLike(Map<String, Object> param) {
Connection conn = getConnection();
List<Member> memberList = memberDao.findMemberLike(conn, param);
close(conn);
return memberList;
}
Dao
MemberDao
// findMemberLike = select * from (select row_number() over (order by enroll_date desc) rnum, m.* from member m where # like ?) m where rnum between ? and ?
public List<Member> findMemberLike(Connection conn, Map<String, Object> param) {
PreparedStatement pstmt = null;
ResultSet rset = null;
List<Member> memberList = new ArrayList<>();
String sql = prop.getProperty("findMemberLike");
sql = sql.replace("#", (String)param.get("searchType"));
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "%" + param.get("searchKeyword") + "%");
pstmt.setInt(2, (int)param.get("start"));
pstmt.setInt(3, (int)param.get("end"));
rset = pstmt.executeQuery();
while(rset.next()) {
memberList.add(handleMemberResultSet(rset));
}
} catch (SQLException e) {
throw new MemberException("관리자 회원 검색 오류!", e);
} finally {
close(rset);
close(pstmt);
}
return memberList;
}
일반 페이징과 달리 검색어가 있는 페이징 처리이기 때문에 지정한 타입과 검색어를 where 조건으로 두어 필터링을 거치도록 하였습니다.
content영역이 지정한 10개씩 보여지는 것을 확인할 수 있으며, 링크가 걸려있지 않기 때문에 '&cPage='로 지정해주어 페이지를 이동해보았습니다.
pagebar 영역
Controller
AdminMemberFinder
// b. pagebar 영역
int totalContent = memberService.getTotalContentLike(param);
System.out.println("toatlaContent" + totalContent);
String url = request.getRequestURI(); // /mvc2/admin/memberFinder
String pagebar = HelloMvcUtils.getPagebar(cPage, numPerPage, totalContent, url);
// 3. view단 처리
request.setAttribute("memberList", memberList);
request.setAttribute("pagebar", pagebar);
request.getRequestDispatcher("/WEB-INF/views/admin/memberList.jsp").forward(request, response);
getPagebar()
public static String getPagebar(int cPage, int numPerPage, int totalContent, String url) {
StringBuilder pagebar = new StringBuilder();
url += "?cPage=";
int totalPage = (int)Math.ceil((double)totalContent / numPerPage);
int pagebarSize = 5;
int pagebarStart = ((cPage - 1) / pagebarSize * pagebarSize) + 1;
int pagebarEnd = pagebarStart + pagebarSize - 1;
int pageNo = pagebarStart;
// 이전영역
if(pageNo == 1) {
} else {
pagebar.append("<a href='" + url + (pageNo -1) + "'>이전</a>\n");
}
// pageNo영역
while(pageNo <= pagebarEnd && pageNo <= totalPage) {
// 현재페이지
if(pageNo == cPage) {
pagebar.append("<span class='cPage'>" + pageNo + "</span>\n");
}
// 현재페이지가 아닌 경우
else {
pagebar.append("<a href='" + url + pageNo + "'>" + pageNo + "</a>\n");
}
pageNo++;
}
// 다음영역
if(pageNo > totalPage) {
} else {
pagebar.append("<a href='" + url + pageNo + "'>다음</a>\n");
}
return pagebar.toString();
}
Service
MemberService
public int getTotalContentLike(Map<String, Object> param) {
Connection conn = getConnection();
int totalContentLike = memberDao.getTotalContentLike(conn, param);
close(conn);
return totalContentLike;
}
Dao
MemberDao
// getTotalContentLike = select count(*) from member where # like ?
public int getTotalContentLike(Connection conn, Map<String, Object> param) {
PreparedStatement pstmt = null;
ResultSet rset = null;
String sql = prop.getProperty("getTotalContentLike");
int totalContentLike = 0;
sql = sql.replace("#", (String)param.get("searchType"));
try {
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "%" + (String)param.get("searchKeyword") + "%");
rset = pstmt.executeQuery();
if(rset.next()) {
totalContentLike = rset.getInt(1);
}
} catch (SQLException e) {
throw new MemberException("관리자 검색 회원 수 조회 오류!", e);
} finally {
close(rset);
close(pstmt);
}
return totalContentLike;
}
pagebar가 잘 생성되었지만, 페이지 이동을 하면, 위와 같이 검색이 풀려버려 500오류가 발생하는 것을 확인할 수 있습니다.
현재 넘겨준 uri는 /mvc2/admin/memberFinder이기 때문에 해당 uri로 처리하면 풀려버리는 것이죠.
따라서 아래와 같이 수정해줍니다.
String url = request.getRequestURI() + "?searchType=" + searchType + "&searchKeyword=" + searchKeyword;
하지만 이렇게 uri를 변경해도 페이지 이동을 하면 위와 같이 검색이 이루어집니다.
기본적인 path와 queryString의 구분자는 '?'인데, '?cPage=2'가 또 나와버리기 때문에 규격에 맞지 않아 원하는 값들을 못 가져오는 것입니다.
getPagebar() 메소드의 url 값을 아래와 같이 수정해줍니다.
url += (url.indexOf("?") < 0 ) ? "?cPage=" : "&cPage=";
넘어온 url에 "?"가 없다면 url 뒤에 "?cPage="를 추가해주고, 있다면 url 뒤에 "&cPage="를 추가해주도록 하였습니다.
'Java > Servlet & JSP' 카테고리의 다른 글
JSP) 게시판 페이지 구현 및 페이징 처리 (0) | 2022.07.02 |
---|---|
JSP) 관리자 권한 변경 - Referer, dataset (0) | 2022.07.02 |
JSP) 검색기능 구현하기 (0) | 2022.07.01 |
JSP) 기본 페이징 처리 (0) | 2022.06.28 |
JSP) 관리자 모드 - 회원 정보 조회하기 (0) | 2022.06.27 |