아래 샘플을 참고 하자.


/**
 * 파일 명 생성
 *
 * @param fileName
 * @param request HttpServletRequest
 * @param response HttpServletResponse
 * @throws UnsupportedEncodingException
 */
private void setDownloadFileName(String fileName, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
    fileName = URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20");

    if (logger.isDebugEnabled()) {
        logger.debug("fileName: " + fileName);
    }

    response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\";");
    response.setHeader("Content-Transfer-Encoding", "binary");
}


URLEncoder 를 사용하여 encode 한다. 파일 다운로드 시 공백이 + 로 표현 되기 때문에 replaceAll 을 사용하여 추가로 변환 하면 해결 된다.


참고 사이트


작업 시 MultipartHttpServletRequest.getFileMap() 을 사용하여, 파일을 받았다. 하지만 또 다시 호출 하였다.


이와 같은 상황에서 발생 한다. getFileMap() 이 아니라도, 비슷한 기능의 메소드 라고 하면, 같은 상황 일 것 이다. 파일 만이 아니라, IO 작업 시 getInputStream() 을 두번 호출해도 같은 상황이라고 볼 수 있다.


IO 관련 메소드는 항상 작업 시 이런 점은 주의 해야 한다.


Map<String, MultipartFile> fileMap = ((MultipartHttpServletRequest) request).getFileMap();

// Doing...

fileMap = ((MultipartHttpServletRequest) request).getFileMap(); // Error 


소스를 점검 하고, 같은 메소드를 두번 호출 하지는 않는 지 확인 하자.


서버에서 Paging 에 대한 로직 처리 후, jsp include, param 기능을 사용하여 구현 한다.


1. Paging

Paging 기능을 구현하는 VO Class 이다. setTotalCount(int totalCount) 호출 시 makePaging() 함수 호출 한다.


/**
 * Paging
 *
 * @author whitelife
 * @since 2014.10.05
 * @version 0.1
 */
public class Paging {
    private int pageSize; // 게시 글 수
    private int firstPageNo; // 첫 번째 페이지 번호
    private int prevPageNo; // 이전 페이지 번호
    private int startPageNo; // 시작 페이지 (페이징 네비 기준)
    private int pageNo; // 페이지 번호
    private int endPageNo; // 끝 페이지 (페이징 네비 기준)
    private int nextPageNo; // 다음 페이지 번호
    private int finalPageNo; // 마지막 페이지 번호
    private int totalCount; // 게시 글 전체 수

    /**
     * @return the pageSize
     */
    public int getPageSize() {
        return pageSize;
    }

    /**
     * @param pageSize the pageSize to set
     */
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    /**
     * @return the firstPageNo
     */
    public int getFirstPageNo() {
        return firstPageNo;
    }

    /**
     * @param firstPageNo the firstPageNo to set
     */
    public void setFirstPageNo(int firstPageNo) {
        this.firstPageNo = firstPageNo;
    }

    /**
     * @return the prevPageNo
     */
    public int getPrevPageNo() {
        return prevPageNo;
    }

    /**
     * @param prevPageNo the prevPageNo to set
     */
    public void setPrevPageNo(int prevPageNo) {
        this.prevPageNo = prevPageNo;
    }

    /**
     * @return the startPageNo
     */
    public int getStartPageNo() {
        return startPageNo;
    }

    /**
     * @param startPageNo the startPageNo to set
     */
    public void setStartPageNo(int startPageNo) {
        this.startPageNo = startPageNo;
    }

    /**
     * @return the pageNo
     */
    public int getPageNo() {
        return pageNo;
    }

    /**
     * @param pageNo the pageNo to set
     */
    public void setPageNo(int pageNo) {
        this.pageNo = pageNo;
    }

    /**
     * @return the endPageNo
     */
    public int getEndPageNo() {
        return endPageNo;
    }

    /**
     * @param endPageNo the endPageNo to set
     */
    public void setEndPageNo(int endPageNo) {
        this.endPageNo = endPageNo;
    }

    /**
     * @return the nextPageNo
     */
    public int getNextPageNo() {
        return nextPageNo;
    }

    /**
     * @param nextPageNo the nextPageNo to set
     */
    public void setNextPageNo(int nextPageNo) {
        this.nextPageNo = nextPageNo;
    }

    /**
     * @return the finalPageNo
     */
    public int getFinalPageNo() {
        return finalPageNo;
    }

    /**
     * @param finalPageNo the finalPageNo to set
     */
    public void setFinalPageNo(int finalPageNo) {
        this.finalPageNo = finalPageNo;
    }

    /**
     * @return the totalCount
     */
    public int getTotalCount() {
        return totalCount;
    }

    /**
     * @param totalCount the totalCount to set
     */
    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
        this.makePaging();
    }

    /**
     * 페이징 생성
     */
    private void makePaging() {
        if (this.totalCount == 0) return; // 게시 글 전체 수가 없는 경우
        if (this.pageNo == 0) this.setPageNo(1); // 기본 값 설정
        if (this.pageSize == 0) this.setPageSize(10); // 기본 값 설정

        int finalPage = (totalCount + (pageSize - 1)) / pageSize; // 마지막 페이지
        if (this.pageNo > finalPage) this.setPageNo(finalPage); // 기본 값 설정

        if (this.pageNo < 0 || this.pageNo > finalPage) this.pageNo = 1; // 현재 페이지 유효성 체크

        boolean isNowFirst = pageNo == 1 ? true : false; // 시작 페이지 (전체)
        boolean isNowFinal = pageNo == finalPage ? true : false; // 마지막 페이지 (전체)

        int startPage = ((pageNo - 1) / 10) * 10 + 1; // 시작 페이지 (페이징 네비 기준)
        int endPage = startPage + 10 - 1; // 끝 페이지 (페이징 네비 기준)

        if (endPage > finalPage) { // [마지막 페이지 (페이징 네비 기준) > 마지막 페이지] 보다 큰 경우
            endPage = finalPage;
        }

        this.setFirstPageNo(1); // 첫 번째 페이지 번호

        if (isNowFirst) {
            this.setPrevPageNo(1); // 이전 페이지 번호
        } else {
            this.setPrevPageNo(((pageNo - 1) < 1 ? 1 : (pageNo - 1))); // 이전 페이지 번호
        }

        this.setStartPageNo(startPage); // 시작 페이지 (페이징 네비 기준)
        this.setEndPageNo(endPage); // 끝 페이지 (페이징 네비 기준)

        if (isNowFinal) {
            this.setNextPageNo(finalPage); // 다음 페이지 번호
        } else {
            this.setNextPageNo(((pageNo + 1) > finalPage ? finalPage : (pageNo + 1))); // 다음 페이지 번호
        }

        this.setFinalPageNo(finalPage); // 마지막 페이지 번호
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}


2. Controller

setTotalCount(totalCount) 를 호출 한다. CustomServlet 으로 처리도 가능 하다.


/**
 * 리스트 조회
 *
 * @param request
 * @return
 * @throws Exception
 */
@RequestMapping(value="/list", method=RequestMethod.GET)
public ModelAndView list(Sample sample) throws Exception {
    try {
        // (Before) Doing...

        Paging paging = new Paging();
        paging.setPageNo(1);
        paging.setPageSize(10);
        paging.setTotalCount(totalCount);


        // (After) Doing...
    } catch (Exception e) {
        throw e;
    }
}


3. paging.jsp

View 스타일에 따라 수정이 가능 하다.


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<div class="paginate">
    <a href="javascript:goPage(${param.firstPageNo})" class="first">처음 페이지</a>
    <a href="javascript:goPage(${param.prevPageNo})" class="prev">이전 페이지</a>
    <span>
        <c:forEach var="i" begin="${param.startPageNo}" end="${param.endPageNo}" step="1">
            <c:choose>
                <c:when test="${i eq param.pageNo}"><a href="javascript:goPage(${i})" class="choice">${i}</a></c:when>
                <c:otherwise><a href="javascript:goPage(${i})">${i}</a></c:otherwise>
            </c:choose>
        </c:forEach>
    </span>
    <a href="javascript:goPage(${param.nextPageNo})" class="next">다음 페이지</a>
    <a href="javascript:goPage(${param.finalPageNo})" class="last">마지막 페이지</a>
</div>


4. list.jsp

paging.jsp 를 호출 하는 부분이다.


// (Before) Doing...
<jsp:include page="paging.jsp" flush="true">
    <jsp:param name="firstPageNo" value="${paging.firstPageNo}" />
    <jsp:param name="prevPageNo" value="${paging.prevPageNo}" />
    <jsp:param name="startPageNo" value="${paging.startPageNo}" />
    <jsp:param name="pageNo" value="${paging.pageNo}" />
    <jsp:param name="endPageNo" value="${paging.endPageNo}" />
    <jsp:param name="nextPageNo" value="${paging.nextPageNo}" />
    <jsp:param name="finalPageNo" value="${paging.finalPageNo}" />
</jsp:include>
// (After) Doing...


JSTL 태그 라이브러리 fmt 를 추가 한다.


<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>


formatDate 함수를 사용 한다. value 에 Date 형 값을 넣고, 원하는 pattern 대로 넣어주면 변환되어 출력 된다.


<fmt:formatDate value="java.util.Date" pattern="yyyy.MM.dd"/>


Sample


<c:forEach var="entry" items="${sampleMap}">
    Key: <c:out value="${entry.key}"/>
    Value: <c:out value="${entry.value}"/>
</c:forEach>

참고사이트


 

 jsp 페이지를 작업 할 때. 예전에는 <% %>, <=% %> 안에 Java 코드를 직접 사용 했었다. jstl 문법을 사용하면 ${} 형태로 이용 할 수 있다. 그 방법에 대해 알아 보도록 하자.



 사용하기 전에 jsp 페이지 최 상단에 Header를 추가 하자.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> - 기본적인 함수
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> - 데이터의 포맷 관련


${test}는 <=%request.getParameter("test")%>과 일치 한다. 자바 코드 대신 jstl 문법을 이용하는 방법도 있다.

 

Core

 <c:if> 특정 조건이 참일 경우만 처리할 때 유용 하다.

<c:if test="${test}">
    <!--  조건 일치 참 인 경우  -->
</c:if>


<c:choose>는 참 인 경우, 거짓 인 경우를 다 수용이 가능 하다. <c:if> 사용 시 거짓 조건을 처리해야 할 경우 사용 하자.

<c:choose>
    <c:when test="${test}">
        <!--  조건 일치 참 인 경우  -->
    </c:when>
    <c:otherwise>
        <!--  모든 조건이 불 일치 한 경우  -->
    </c:otherwise>
</c:choose>


<c:forEach> 반복문의 형태를 띄고 있는 태그 이다. 보통 table 의 하위나, 리스트를 표현할 때 사용 한다.

<c:forEach var="test" items="${testList}">
    <!--
        반복 영역
        Map, List, Json 등 Key나 변수를 호출 하면 Value 값을 볼 수 있다.
 
        예시: ${test.title}, ${test.content}
    -->
</c:forEach>



+ Recent posts