2018년 4월 2일 월요일

Intellij 에서 Java Maven Web 프로젝트 - DB없이 파일로 데이터 유지하기

1. Mudule 에서 Maven을 선택 후 'Create from archetype' 를 선택 후 'maven-archetype-webapp'를 선택한다.

2. id에 프로젝트명을 적는다.
3. 'Next'를 선택한다.

4. 'main' 폴더에 'java' 와 'examples' 폴더를 만들고 File - Project Structure 메뉴에 들어가서 'java' 폴더를 선택 후 Mark as 에 있는 'source'를 선택하여 파랑색 폴더로 변경한다.


5. 단순 입력하고 출력하는 소스를 작성한다.

5.1 리스트 CLASS
package examples;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Iterator;

@WebServlet(name = "/BoardListServlet", urlPatterns = "/list")
public class BoardListServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        RequestDispatcher requestDispatcher =
                    req.getRequestDispatcher("/list.jsp");

        BoardService service = BoardService.getService();

        Iterator iter = service.getBoard();
        req.setAttribute("iter", iter);

        requestDispatcher.forward(req, resp);
    }

}
5.2 쓰기 CLASS
package examples;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet(name = "BoardWriteServlet", urlPatterns = "/write")
public class BoardWriteServlet extends HttpServlet{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("UTF-8");
        String name = req.getParameter("name");
        String content = req.getParameter("content");
        Date date = new Date();
        String regDate = new SimpleDateFormat("yyyy-MM-dd").format(date);

        BoardVO boardVO = new BoardVO();
        boardVO.setName(name);
        boardVO.setContent(content);
        boardVO.setRegDate(regDate);

        BoardService boardService = BoardService.getService();
        boardService.addBoard(boardVO);

        resp.sendRedirect("/list");
    }
}

5.3 공통 CLASS
package examples;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class BoardService {
    //리스트
    List list;

    private BoardService(){
        list = Collections.synchronizedList(new ArrayList());
    }

    public static BoardService service = new BoardService();

    public static BoardService getService() { return service; }

    public void addBoard(BoardVO boardVO){ list.add(boardVO); }

    public Iterator getBoard(){ return list.iterator(); }



}
5.4 VO CLASS
package examples;

public class BoardVO {
    private String name;
    private String content;
    private String regDate;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getRegDate() {
        return regDate;
    }

    public void setRegDate(String regDate) {
        this.regDate = regDate;
    }
}
5.5 POM.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>firstweb_sub</groupId>
  <artifactId>firstweb_sub</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>firstweb_sub Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope> <!-- compile 할때만 사용하겠다.(tomcat이 서블릿을 가지고 있기 때문에) -->
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope> <!-- test드가 실행될때만 라이브러리를 사용하겠다. -->
    </dependency>

    <!-- https://mvnrepository.com/artifact/jstl/jstl -->
    <dependency>
      <groupId>jstl</groupId> <!-- <scope></scope> 가 없는 경우는 모든경우 사용하는 라이브러리 -->
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

  </dependencies>
  <build>
    <finalName>firstweb_sub</finalName>
    <!-- jdk 8사용 -->
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

5.6 list.jsp 를 webapp 폴더 안에 만든다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false"%><%-- isELIgnored : el문 사용안할것이지 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<form method="post" id="form" action="/write">
    <input type="hidden" id="page" name="page" value="${pagingInfo.page}">
    이름 : <input type="text" name="name">
    내용 : <textarea cols="60" rows="7" name="content"></textarea>
    <input type="submit" value="확인">
</form>
<c:forEach var="list" items="${iter}" >
    이름 : ${list.name} <br>
    내용 : ${list.content} <br>
    날짜 : ${list.regDate}<br>
    <br>
</c:forEach>
</body>
</html>


6. tomcat 서버를 local로 선택하여 추가하고 다운 받은 파일에 대한 경로를 설정하고 NAME을 설정한다.
7. 'Deplyment' 탭 에서 '+' 버튼을 선택후 'Arifact'를 클릭하여 프로젝트를 추가한다.
8. 톰캣을 실행하여 'http://localhost:8080/list' 에 접속하여 이름과 내용을 추가해본다.


9. 톰캣을 재구동하면 데이터가 저장되지 않는다. DB가 없으니 파일로 저장하여 데이터를 유지해보자. 톰캣 종료시 리스트에 있던 내용을 파일로 저장하여 재시작 하여도 데이터를 유지해보자.

9.1 공통 CLASS

package examples;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class BoardService {
    //리스트
    List list;

    private BoardService(){
        File file = new File("board.dat");
        if(file.exists()){
            ObjectInputStream ois = null;
            System.out.println("파일 경로 : " + file.getAbsolutePath()); //파일경로
            try {
                ois = new ObjectInputStream(new FileInputStream(file));
                list = (List)ois.readObject(); //파일에 저장한 리스트 읽어어와서 저장하기
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try{ ois.close(); }catch(Exception e){}

            }
        }else{
            list = Collections.synchronizedList(new ArrayList());
        }
    }

    public static BoardService service = new BoardService();

    public static BoardService getService() { return service; }

    public void addBoard(BoardVO boardVO){ list.add(boardVO); }

    public Iterator getBoard(){ return list.iterator(); }

    public void save(){
        ObjectOutputStream os = null;
        try{
            os = new ObjectOutputStream((new FileOutputStream("board.dat"))); //리스트를 파일로 저장
            os.writeObject(list);
            os.close();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
9.2 리스트 CLASS

package examples;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Iterator;

@WebServlet(name = "/BoardListServlet", urlPatterns = "/list")
public class BoardListServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        RequestDispatcher requestDispatcher =
                    req.getRequestDispatcher("/list.jsp");

        BoardService service = BoardService.getService();

        Iterator iter = service.getBoard();
        req.setAttribute("iter", iter);

        requestDispatcher.forward(req, resp);
    }
    @Override
    public void destroy() {
        System.out.println("destory가 호출합니다.");
        BoardService service = BoardService.getService();
        service.save();
    }
}
9.3 VO CLASS

package examples;

import java.io.Serializable;

public class BoardVO implements Serializable{
    private String name;
    private String content;
    private String regDate;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getRegDate() {
        return regDate;
    }

    public void setRegDate(String regDate) {
        this.regDate = regDate;
    }
}
10. 톰캣을 재구동 하여 실행해보자. 특정 위치에 파일이 생성되고 톰캣 재구동시 데이터가 유지되어 출력된다. 데이터를 직렬화를 통해 bat파일로 저장하고 불러오는 것이다. 저장되는 위치는 console에 출력된다(경로는 사람마다 다를수 있다.)
11. tld파일을 활용하여 페이징 처리도 추가해보자

11-1 리스트 CLASS
package examples;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@WebServlet(name = "/BoardListServlet", urlPatterns = "/list")
public class BoardListServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        RequestDispatcher requestDispatcher =
                req.getRequestDispatcher("/list.jsp");

        BoardService service = BoardService.getService();

        int pageSize = service.list.size();

        BoardPagingInfo pagingInfo = new BoardPagingInfo();
        if(req.getParameter("page") != null){
            pagingInfo.setPage(Integer.parseInt(req.getParameter("page")));
        }else{
            pagingInfo.setPage(1);
        }

        pagingInfo.setTotCount(pageSize);
        req.setAttribute("pagingInfo", pagingInfo);
        ArrayList list = new ArrayList();
        for( Iterator itr = service.getBoard(); itr.hasNext(); ) { //리스트 담기
            list.add( itr.next() );
        }
        int startPage = pagingInfo.getPageVal(); //시작페이지
        int endPage = startPage + pagingInfo.getPageSize();
        if( pageSize < endPage ){
            endPage = pageSize;
        }
        List resultList = list.subList(startPage, endPage); //startPage 이상 endPage 미만

        req.setAttribute("iter", resultList);

        requestDispatcher.forward(req, resp);
    }

    @Override
    public void destroy() {
        System.out.println("destory가 호출합니다.");
        BoardService service = BoardService.getService();
        service.save();
    }
}
11-2 POM.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>firstweb_sub</groupId>
  <artifactId>firstweb_sub</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>firstweb_sub Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>

   <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope> <!-- compile 할때만 사용하겠다.(tomcat이 서블릿을 가지고 있기 때문에) -->
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope> <!-- test드가 실행될때만 라이브러리를 사용하겠다. -->
    </dependency>

    <!-- https://mvnrepository.com/artifact/jstl/jstl -->
    <dependency>
      <groupId>jstl</groupId> <!-- <scope></scope> 가 없는 경우는 모든경우 사용하는 라이브러리 -->
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId> <!-- taglib 사용 -->
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>
  <build>
    <finalName>firstweb_sub</finalName>
    <!-- jdk 8사용 -->
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
11-3 Custom Tag (WEB-INF폴더에 ui폴더를 만들고 ui.tld파일을 생성한다.)
<?xml version="1.0" encoding="UTF-8"?>
<taglib
        xsi:schemaLocation="
            http://java.sun.com/xml/ns/javaee
            http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        version="2.1">

    <tlib-version>1.0</tlib-version>
    <short-name>BoardUiTagLibrary</short-name>
    <uri>boardUiLib</uri>

    <tag>
        <name>paging</name>
        <tag-class>examples.BoardPaginTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>pagingInfo</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>linkFunction</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>


</taglib>
11-4 Paging CLASS
package examples;

public class BoardPagingInfo {
    private int page =1;
    private int pageVal = 0;
    private int pageSize = 3;
    private int totCount;

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
        this.pageVal = (page - 1) * pageSize;
    }

    public int getPageVal() {
        return pageVal;
    }

    public void setPageVal(int pageVal) {
        this.pageVal = pageVal;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotCount() {
        return totCount;
    }

    public void setTotCount(int totCount) {
        this.totCount = totCount;
    }
}


package examples;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;

public class BoardPaginTag extends TagSupport {

    private static final long serialVersionUID = 1L;
    private String linkFunction;
    private BoardPagingInfo pagingInfo;

    private final int PREVIOUS = -1;
    private final int INDEX = 0;
    private final int NEXT = 1;

    private int maxPage;
    private int pageIndex;
    private int lastPage;

    public void setLinkFunction(String linkFunction){
        this.linkFunction = linkFunction;
    }

    public void setPagingInfo(BoardPagingInfo pagingInfo){
        this.pagingInfo = pagingInfo;
    }

    @Override
    public int doEndTag() throws JspException {
        try{
            JspWriter out = pageContext.getOut();
            String contents = getContents();
            out.println(contents);
        }catch (IOException e){
            throw new JspException();
        }
        return EVAL_PAGE;
    }

    private String getContents() {
        StringBuffer html = new StringBuffer();
        if (this.pagingInfo.getTotCount() == 0) {
            return "";
        }
        this.maxPage = this.pagingInfo.getTotCount() / this.pagingInfo.getPageSize() + (this.pagingInfo.getTotCount() % this.pagingInfo.getPageSize() > 0 ? 1 : 0);
        this.pageIndex = (this.pagingInfo.getPage() - 1) / 5;
        this.lastPage = this.pageIndex * 5 + 5 >= this.maxPage ? this.maxPage : this.pageIndex * 5 + 5;


        html.append("총 " + this.pagingInfo.getTotCount() + " 건<br>");
        if (this.pageIndex != 0) {
            html.append("<a href='javascript:;' onclick='javascript:" + navFunction(this.PREVIOUS, -1) + ";'>");
        }
        for (int i = this.pageIndex * 5 + 1 ; i < this.lastPage + 1 ; i++) {
            if (i == this.pagingInfo.getPage()) {
                html.append("<b><a href='javascript:;' onclick='javascript:" + navFunction(this.INDEX, i) + ";'>" + i + "</a></b> ");
            }else{
                html.append("<a href='javascript:;' onclick='javascript:" + navFunction(this.INDEX, i) + ";'>" + i + "</a> ");
            }

        }
        if (this.lastPage + 1 <= this.maxPage) {
            html.append("<a href='javascript:;' onclick='javascript:" + navFunction(this.NEXT, -1) + ";'>></a>");
        }

        return html.toString();
    }

    private String navFunction(int type, int index) {
        String callFunction = "return false";
        switch(type){
            case PREVIOUS :
                if(this.pageIndex == 0){
                    break;
                }
                callFunction = this.linkFunction + "(" + this.pageIndex * 5 + ")";
                break;
            case INDEX :
                if(this.pagingInfo.getPage() == index){
                    break;
                }
                callFunction = this.linkFunction + "(" + index + ")";
                break;
            case NEXT :
                if(this.lastPage +1 > this.maxPage){
                    break;
                }
                callFunction = this.linkFunction + "(" + ((this.pageIndex + 1) * 5 + 1) + ")";
                break;
        }
        return callFunction;

    }
}
11-5 list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false"%><%-- isELIgnored : el문 사용안할것이지 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="boardUiLib" uri="boardUiLib"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
    function pageNavigation(page) {
        document.getElementById('page').value= page;
        window.location.href = "${contextPath}/list" + "?" + $("#form").serialize();
    }
</script>
<html>
<body>
<form method="post" id="form" action="/write">
    <input type="hidden" id="page" name="page" value="${pagingInfo.page}">
    이름 : <input type="text" name="name">
    내용 : <textarea cols="60" rows="7" name="content"></textarea>
    <input type="submit" value="확인">
</form>
<c:forEach var="list" items="${iter}" >
    이름 : ${list.name} <br>
    내용 : ${list.content} <br>
    날짜 : ${list.regDate}<br>
    <br>
</c:forEach>
<boardUiLib:paging linkFunction="pageNavigation" pagingInfo="${pagingInfo}" />
</body>
</html>

12. 톰캣을 실행후 페이징 처리가 되는지 확인한다.
13. 글 상세보기 기능도 추가해보자.

13.1 상세 CLASS
package examples;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

@WebServlet(name = "BoardDetailServlet" , urlPatterns = "/detail")
public class BoardDetailServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        RequestDispatcher requestDispatcher
                = req.getRequestDispatcher("detail.jsp");

        ArrayList list = new ArrayList();
        for(Iterator itr = BoardService.getService().getBoard(); itr.hasNext(); ) { //리스트 담기
            list.add( itr.next() );
        }
        int no = Integer.parseInt(req.getParameter("no"));
        BoardVO boardVo = (BoardVO) list.get(no);
        req.setAttribute("name", boardVo.getName());
        req.setAttribute("content", boardVo.getContent());
        req.setAttribute("regDate", boardVo.getRegDate());

        requestDispatcher.forward(req, resp);

    }
}
13.2 리스트 CLASS
package examples;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@WebServlet(name = "/BoardListServlet", urlPatterns = "/list")
public class BoardListServlet extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        RequestDispatcher requestDispatcher =
                req.getRequestDispatcher("/list.jsp");

        BoardService service = BoardService.getService();

        int pageSize = service.list.size();

        BoardPagingInfo pagingInfo = new BoardPagingInfo();
        if(req.getParameter("page") != null){
            pagingInfo.setPage(Integer.parseInt(req.getParameter("page")));
        }else{
            pagingInfo.setPage(1);
        }

        pagingInfo.setTotCount(pageSize);
        req.setAttribute("pagingInfo", pagingInfo);
        ArrayList list = new ArrayList();
        for( Iterator itr = service.getBoard(); itr.hasNext(); ) { //리스트 담기
            list.add( itr.next() );
        }
        int startPage = pagingInfo.getPageVal(); //시작페이지
        int endPage = startPage + pagingInfo.getPageSize();
        if( pageSize < endPage ){
            endPage = pageSize;
        }
        List resultList = list.subList(startPage, endPage); //startPage 이상 endPage 미만

        req.setAttribute("iter", resultList);
        req.setAttribute("startPage", startPage);

        requestDispatcher.forward(req, resp);
    }

    @Override
    public void destroy() {
        System.out.println("destory가 호출합니다.");
        BoardService service = BoardService.getService();
        service.save();
    }
}

13.3 상세 JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false"%><%-- isELIgnored : el문 사용안할것이지 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>

<input type="hidden" id="page" name="page" value="${pagingInfo.page}">
이름 : <input type="text" name="name" value="${name}">
내용 : <textarea cols="60" rows="7" name="content" >${content}</textarea>
날짜 : ${regDate}
<button type="button" onclick="javscript:history.back();">뒤로가기</button>
</body>
</html>
13.4 리스트 JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false"%><%-- isELIgnored : el문 사용안할것이지 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="boardUiLib" uri="boardUiLib"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
    function pageNavigation(page) {
        document.getElementById('page').value= page;
        window.location.href = "${contextPath}/list" + "?" + $("#form").serialize();
    }
    function detail() {
        window.location.href = "${contextPath}/detail" + "?" + $("#detail").serialize();
    }
</script>
<html>
<body>
<form method="post" id="form" action="/write">
    <input type="hidden" id="page" name="page" value="${pagingInfo.page}">
    이름 : <input type="text" name="name">
    내용 : <textarea cols="60" rows="7" name="content"></textarea>
    <input type="submit" value="확인">
</form>
<c:forEach var="list" items="${iter}" varStatus="status">
    <form method="get" id="detail" action="/detail" >
        <input type="hidden" name="no" value="${startPage + status.index}">
        이름 : ${list.name} <br>
        내용 : ${list.content} <br>
        날짜 : ${list.regDate}<br>
        <input type="submit" value="상세보기">
        <br>
    </form>
</c:forEach>
<boardUiLib:paging linkFunction="pageNavigation" pagingInfo="${pagingInfo}" />
</body>
</html>
14. 톰캣을 실행하여 버튼을 눌러보자. 상세보기 버튼을 클릭을 하면 해당 글에 대한 상세내용이 보인다.

15. 게시판 ui가 예쁘지 않아서 bootstrap 적용 및 소스를 조금 수정하였다.

15.1 리스트 JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false"%><%-- isELIgnored : el문 사용안할것이지 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="boardUiLib" uri="boardUiLib"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<!-- 합쳐지고 최소화된 최신 CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- 부가적인 테마 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
    function pageNavigation(page) {
        document.getElementById('page').value= page;
        window.location.href = "${contextPath}/list" + "?" + $("#form").serialize();
    }
    function detail(no) {
        window.location.href = "${contextPath}/detail" + "?no=" + no;
    }
</script>
<!DOCTYPE html>
<html lang="ko">
<body>
<form method="post" id="form" action="/write">
    <input type="hidden" id="page" name="page" value="${pagingInfo.page}">
    <div class="form-group">
        <label for="name">이름</label>
        <input type="text" class="form-control" id="name" placeholder="이름을 입력하세요" >
    </div>
    <div class="form-group">
        <label for="name">내용</label>
        <textarea class="form-control" cols="60" rows="7" ></textarea>
    </div>
</form>
<div class="container">
    <table class="table table-striped">
        <thead>
        <tr>
            <th>이름</th>
            <th>내용</th>
            <th>날짜</th>
        </tr>
        </thead>
        <tbody>
<c:forEach var="list" items="${iter}" varStatus="status">
                <tr>
                    <td><a onclick="javascript:detail(${startPage + status.index})" onclick="return false;">${list.name}</a></td>
                    <td>${list.content}</td>
                    <td>${list.regDate}</td>
                </tr>
</c:forEach>
        </tbody>
    </table>
<boardUiLib:paging linkFunction="pageNavigation" pagingInfo="${pagingInfo}" />
</div>
</body>
</html>
15.2 상세 JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" isELIgnored="false"%><%-- isELIgnored : el문 사용안할것이지 --%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="contextPath" value="${pageContext.request.contextPath}" />
<!-- 합쳐지고 최소화된 최신 CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- 부가적인 테마 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
<!-- 합쳐지고 최소화된 최신 자바스크립트 -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="ko">
<body>
<div class="form-group">
    <label for="name">이름</label>
    <input type="text" class="form-control" id="name" name="name" placeholder="이름을 입력하세요" value="${name}">
</div>
<div class="form-group">
    <label for="name">내용</label>
    <textarea class="form-control" name="content" cols="60" rows="7" >${content}</textarea>
</div>
<div class="form-group">
    <label for="name">날짜</label>
    <input type="text" class="form-control" id="regDate"  value="${regDate}" disabled>
</div>
<button type="submit" class="btn btn-default" onclick="javscript:history.back();">뒤로가기</button>
</body>
</html>
15.3 Paging CLASS

package examples;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;

public class BoardPaginTag extends TagSupport {

    private static final long serialVersionUID = 1L;
    private String linkFunction;
    private BoardPagingInfo pagingInfo;

    private final int PREVIOUS = -1;
    private final int INDEX = 0;
    private final int NEXT = 1;

    private int maxPage;
    private int pageIndex;
    private int lastPage;

    public void setLinkFunction(String linkFunction){
        this.linkFunction = linkFunction;
    }

    public void setPagingInfo(BoardPagingInfo pagingInfo){
        this.pagingInfo = pagingInfo;
    }

    @Override
    public int doEndTag() throws JspException {
        try{
            JspWriter out = pageContext.getOut();
            String contents = getContents();
            out.println(contents);
        }catch (IOException e){
            throw new JspException();
        }
        return EVAL_PAGE;
    }

    private String getContents() {
        StringBuffer html = new StringBuffer();
        if (this.pagingInfo.getTotCount() == 0) {
            return "";
        }
        this.maxPage = this.pagingInfo.getTotCount() / this.pagingInfo.getPageSize() + (this.pagingInfo.getTotCount() % this.pagingInfo.getPageSize() > 0 ? 1 : 0);
        this.pageIndex = (this.pagingInfo.getPage() - 1) / 5;
        this.lastPage = this.pageIndex * 5 + 5 >= this.maxPage ? this.maxPage : this.pageIndex * 5 + 5;


        html.append("<div class='row'>");
        html.append("<div class='col-sm-4'>");
        html.append("<div class='dataTables_info' role='status' aria-live='polite'>총 " + this.pagingInfo.getTotCount() + " 건</div>");
        html.append("</div>");
        html.append("<div class='col-sm-8'>");
        html.append("<div class='dataTables_paginate paging_simple_numbers'>");
        html.append("<ul class='pagination'>");
        html.append("<li class='paginate_button previous ");
        if (this.pageIndex == 0) {
            html.append("disabled");
        }
        html.append("' aria-controls='dataTables-example' tabindex='0'><a href='javascript:;' onclick='javascript:" + navFunction(this.PREVIOUS, -1) + ";'><</a></li>");
        for (int i = this.pageIndex * 5 + 1 ; i < this.lastPage + 1 ; i++) {
            html.append("<li class='paginate_button ");
            if (i == this.pagingInfo.getPage()) {
                html.append("active");
            }
            html.append("' aria-controls='dataTables-example' tabindex='0'><a href='javascript:;' onclick='javascript:" + navFunction(this.INDEX, i) + ";'>" + i + "</a></li>");
        }
        html.append("<li class='paginate_button next ");
        if (this.lastPage + 1 > this.maxPage) {
            html.append("disabled");
        }
        html.append("' aria-controls='dataTables-example' tabindex='0'><a href='javascript:;' onclick='javascript:" + navFunction(this.NEXT, -1) + ";'>></a></li>");
        html.append("</ul>");
        html.append("</div>");
        html.append("</div>");
        html.append("</div>");

        return html.toString();
    }

    private String navFunction(int type, int index) {
        String callFunction = "return false";
        switch(type){
            case PREVIOUS :
                if(this.pageIndex == 0){
                    break;
                }
                callFunction = this.linkFunction + "(" + this.pageIndex * 5 + ")";
                break;
            case INDEX :
                if(this.pagingInfo.getPage() == index){
                    break;
                }
                callFunction = this.linkFunction + "(" + index + ")";
                break;
            case NEXT :
                if(this.lastPage +1 > this.maxPage){
                    break;
                }
                callFunction = this.linkFunction + "(" + ((this.pageIndex + 1) * 5 + 1) + ")";
                break;
        }
        return callFunction;

    }
}
16. 최종 UI



*GitHub
Share:

0 개의 댓글:

댓글 쓰기