[Struts1] Struts1 + iBatis 를 사용한 파일 업로드
by 무작정 개발2022.03.10(53일 차) - 목요일
3월 9일(수요일)은 대통령 선거일이라 휴무~
jsp(틀만) 만들고 FileTestForm -> struts-config_fileTest.xml(temp복사) 생성 -> web.xml에 등록 ->
-> struts-config_fileTest.xml(컨트롤러) 작성 -> 여기까진 스트럿츠 세팅 -> 이제 아이 바티스 세팅->
temp_sqlMap.xml(복사해서) fileTest_sqlMap.xml 만들고 ->sqlMapConfig.xml에 등록해주고 ->fileTest_sqlMap.xml작성
-> com.util가서 FileManager.java 수정(doFileUpload메서드 생성) -> FileTestAction 생성 후 작성 ->
오늘은 Struts1 + iBatis를 사용해서 파일 업로드 게시판을 만들 예정이다. 기존에 했던 Servlet 파일 업로드 게시판과
크게 다른점은 없다. 그래서 기존에 파일 업로드에 사용했던 테이블(DB)을 그대로 사용할 것이다.
기존에 했던 파일 업로드는 OriginalFileName와 SaveFileName을 동일하게 생성하고, 동일한 이름의 파일이
있으면 뒤에 숫자를 붙여 구분했다.
이번에는 기존과 다르게 파일의 이름을 업로드할 때 일정 규칙을 생성하여 파일을 업로드할 것이다.
오늘의 수업 내용
DB 테이블 생성
- 기존에 만들어뒀던 FILETEST 테이블이다.
CREATE TABLE FILETEST
(NUM NUMBER(7) PRIMARY KEY,
SUBJECT VARCHAR2(50) NOT NULL,
SAVEFILENAME VARCHAR2(50),
ORIGINALFILENAME VARCHAR2(50))
퀀텀 DB로 테이블을 검색했을 때 위 사진처럼 나오면 테이블은 성공적으로 만들어진 것이다.
안에 있는 DB 데이터들은 기존에 내가 넣어뒀던 데이터들이다.
JSP 파일 생성하기 - 파일 업로드 페이지(write.jsp)
- WebContent에 fileTest 폴더를 생성해주고, 그 안에 write.jsp을 생성해준다.
- list.jsp는 나중에 만들 예정
- View
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="<%=cp%>/fileTest.do" method="post"
enctype="multipart/form-data">
제목 : <input type="text" name="subject"/><br/>
파일 : <input type="file" name="upload"/><br/>
<input type="hidden" name="method" value="write_ok">
<input type="submit" value="파일 업로드"/>
<input type="button" value="리스트"
onclick="javascript:location.href='<%=cp%>/fileTest.do?method=list';">
<!-- button은 onclick 사용 / submit은 action을 찾아간다! -->
</form>
</body>
</html>
<form> 시작 부분을 보면
파일 업로드를 하기 위해 enctype="multipart/form=data"를 입력해준다.
그리고 파일을 업로드하기 위해 ' 파일 : ' 쪽 <input> type을 file로 해준다.
submit은 action을 찾아간다. 그래서 파일 업로드 버튼을 클릭하면 위에 있는
<form action="<%=cp%>/fileTest.do" method="post"으로 와서 위의 form action에 적힌 주소로 이동한다.
이동할 때 <input type="hidden" name="method" value="write_ok">에 있는 hidden 값인
method도 같이 이동한다.
FileTestForm 클래스 생성 - (DTO 클래스 역할)
- FormFile은 Apache(아피치)에서 제공하는 파일 업로드 시 사용하는 클래스
- JSP 페이지에서의 input 데이터의 name과 반드시 일치해야 함
- Model
package com.fileTest;
import org.apache.struts.action.ActionForm;
import org.apache.struts.upload.FormFile;
public class FileTestForm extends ActionForm {
private static final long serialVersionUID = 1L;
private int num;
private String subject;
private String saveFileName;
private String originalFileName;
//Struts는 파일업로드할때 FormFile을 쓴다.
private FormFile upload;
//사용자정의 변수
private int listNum; //일렬번호 재정렬
private String urlFile; //파일 다운로드 경로
getter/setter 생성
}
FileTestForm은 기존에 했던 DTO 클래스 역할을 해준다. 그래서 사용할 변수들을 선언해주면서,
getter/setter도 함께 해준다.
struts-config_fileTest.xml 생성 및 web.xml에 등록
- struts-config_fileTest.xml에 forward 경로 등록
- web.xml에 등록
struts-config_fileTest.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config
PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">
<struts-config>
<form-beans>
<form-bean name="fileTestForm" type="com.fileTest.FileTestForm"/>
</form-beans>
<action-mappings>
<action path="/fileTest" type="com.fileTest.FileTestAction"
name="fileTestForm" scope="request" parameter="method">
<forward name="write" path="/fileTest/write.jsp"/>
<forward name="write_ok" redirect="true"
path="/fileTest.do?method=list"/>
<forward name="list" path="/fileTest/list.jsp"/>
<forward name="delete_ok" redirect="true"
path="/fileTest.do?method=list"/>
</action>
</action-mappings>
</struts-config>
web.xml 등록
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>
/WEB-INF/struts-config.xml,
/WEB-INF/struts-config_test.xml,
/WEB-INF/struts-config_board.xml,
/WEB-INF/struts-config_boardTest.xml,
/WEB-INF/struts-config_fileTest.xml
</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
web.xml에 /WEB-INF/struts-config_fileTest.xml를 작성해서 등록해준다.
fileTest.sqlMap.xml 생성 및 등록
- 여기는 iBatis 세팅
- iBatis도 xml을 만들면 등록을 해줘야 한다.(sqlMapConfig.xml에 등록)
fileTest.sqlMap.xml 생성
- DB에 데이터를 넣어주는 역할
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-/ibatis.apache.org//DTO SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="fileTest">
<select id="maxNum" resultClass="int">
select nvl(max(num),0) from fileTest
</select>
<insert id="insertData" parameterClass="com.fileTest.FileTestForm">
insert into fileTest (num,subject,saveFileName,originalFileName)
values (#num#,#subject#,#saveFileName#,#originalFileName#)
</insert>
<select id="dataCount" resultClass="int">
select nvl(count(num),0) from fileTest
</select>
<select id="readData" resultClass="com.fileTest.FileTestForm"
parameterClass="int">
select num,subject,saveFileName,originalFileName
from fileTest where num=#num#
</select>
<select id="listData" resultClass="com.fileTest.FileTestForm"
parameterClass="map">
<![CDATA[
select * from (
select rownum rnum, data.* from (
select num,subject,saveFileName,originalFileName
from fileTest order by num desc) data)
where rnum>=#start# and rnum<=#end#
]]>
</select>
<delete id="deleteData" parameterClass="int">
delete filetest where num=#num#
</delete>
</sqlMap>
sqlMapConfig.xml에 위에 만든 xml 등록
<sqlMap resource="com/util/sqlMap/fileTest_sqlMap.xml"/>
FileTestAction 클래스 생성 - (DAO 클랙스 역할)
- Model
- DispatchAction 상속
- 파일 번호 재정렬 작업은 글 마지막에 작성해서 정리할 예정 - (매우 중요!!)
package com.fileTest;
import java.io.File;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.util.FileManager;
import com.util.MyUtil;
import com.util.dao.CommonDAO;
import com.util.dao.CommonDAOImpl;
public class FileTestAction extends DispatchAction {
public ActionForward write(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//write 메서드가 오면 write라는 문자를 return해주고,
//strsts-config_fileTest.xml에서 forward되어 write.jsp로 들어가며
//write.jsp가 실행된다.
return mapping.findForward("write");
}
public ActionForward write_ok(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
CommonDAO dao = CommonDAOImpl.getInstance();
//오리지날 경로를 쓸려면 세션이 필요
HttpSession session = request.getSession();
String root = session.getServletContext().getRealPath("/");
//실제 경로 만듬 - (pds파일 내 saveFile에 경로를 둠)
//File.separator : 파일과 파일 간의 분배를 해줌
String savePath = root + "pds" + File.separator + "saveFile";
FileTestForm f = (FileTestForm)form;//다운캐스팅
//파일 업로드
String newFileName =
FileManager.doFileUpload(f.getUpload(), savePath);
//파일 정보 DB에 넣기
if(newFileName!=null) {
int maxNum = dao.getIntValue("fileTest.maxNum");
//ActionForm의 form으로 선언한 f에 set을 통해 값을 넣어준다.
f.setNum(maxNum + 1);
f.setSaveFileName(newFileName);
f.setOriginalFileName(f.getUpload().getFileName());
//insertData로 입력해준다.
dao.insertData("fileTest.insertData", f);
}
return mapping.findForward("write_ok");
}
public ActionForward list(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
CommonDAO dao = CommonDAOImpl.getInstance();
MyUtil myUtil = new MyUtil();
String cp = request.getContextPath();
int numPerPage = 5;
int totalPage = 0;
int totalDataCount = 0;
String pageNum = request.getParameter("pageNum");
int currentPage = 1;
if(pageNum!=null && !pageNum.equals("")) {
currentPage = Integer.parseInt(pageNum);
}
totalDataCount = dao.getIntValue("fileTest.dataCount");
if(totalDataCount!=0) {
totalPage = myUtil.getPageCount(numPerPage, totalDataCount);
}
if(currentPage > totalPage) {
currentPage = totalPage;
}
Map<String, Object> hMap = new HashMap<String, Object>();
int start = (currentPage-1)*numPerPage+1;
int end = currentPage*numPerPage;
hMap.put("start", start);
hMap.put("end", end);
List<Object> lists =
(List<Object>)dao.getListData("fileTest.listData", hMap);
//일렬번호를 만드는 코딩
Iterator<Object> it = lists.iterator();
int listNum,n=0;
String str;
while(it.hasNext()) {
FileTestForm dto = (FileTestForm)it.next();
listNum = totalDataCount - (start + n - 1);
dto.setListNum(listNum);
n++;
//파일 다운 경로
str = cp + "/fileTest.do?method=download&num=" + dto.getNum();
dto.setUrlFile(str);
}
String urlList = cp + "/fileTest.do?method=list";
request.setAttribute("lists", lists);
request.setAttribute("pageNum", pageNum);
request.setAttribute("totalDataCount", totalDataCount);
request.setAttribute("pageIndexList",
myUtil.pageIndexList(currentPage, totalPage, urlList));
return mapping.findForward("list");
}
public ActionForward delete(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
CommonDAO dao = CommonDAOImpl.getInstance();
//오리지날 경로를 쓸려면 세션이 필요
HttpSession session = request.getSession();
String root = session.getServletContext().getRealPath("/");
//실제 경로 만듬
String savePath = root + "pds" + File.separator + "saveFile";
//num이 넘어왔으니 받아야 한다.
int num = Integer.parseInt(request.getParameter("num"));
FileTestForm dto =
(FileTestForm)dao.getReadData("fileTest.readData", num);
FileManager.doFileDelete(dto.getSaveFileName(), savePath);
//DB에있는것을 지울때는 dao
// - fileTest의 deleteData를 호출해서 삭제
dao.deleteData("fileTest.deleteData", num);
return mapping.findForward("delete_ok");
}
public ActionForward download(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
CommonDAO dao = CommonDAOImpl.getInstance();
//오리지날 경로를 쓸려면 세션이 필요
HttpSession session = request.getSession();
String root = session.getServletContext().getRealPath("/");
//실제 경로 만듬
String savePath = root + "pds" + File.separator + "saveFile";
//num이 넘어왔으니 받아야 한다.
int num = Integer.parseInt(request.getParameter("num"));
FileTestForm dto =
(FileTestForm)dao.getReadData("fileTest.readData", num);
if(dto==null) {
return mapping.findForward("list");
}
boolean flag = FileManager.doFileDownload(response, dto.getSaveFileName(),
dto.getOriginalFileName(), savePath);
if(!flag) {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("<script type='text/javascript'>");
out.print("alert('다운로드 에러!!');");
out.print("history.back()");
out.print("</script>");
}
return mapping.findForward(null);
}
}
FileManger 클래스 생성
- com.util 패키지에 생성한다.
- 기존에 만들었던 FileManger 클래스에 doFileUpload 메서드를 생성했다.
- doFileUpload 메서드 : 파일을 업로드하는 메서드
doFileUpload 메서드
public class FileManager {
//파일 업로드
//반환값이 있는 이유는 파일을 업로드할 때 a.txt를 올리면 뒤의 .txt를 빼버리고
//새롭게 저장하는 saveName으로 바꾸고 다시 확장자를 붙여
//DB에 저장(Original이랑 이름이 다름)
public static String doFileUpload(FormFile upload, String path) throws IOException {
// OriginalFileName : 클라이언트가 업로드한 파일 이름
// newFileName : 서버에 저장할 새로운 파일 이름
String newFileName = null;
if(upload==null) {
return null;
}
//클라이언트가 업로드한 파일 이름
String originalFileName = upload.getFileName();//오리지날 파일네임을 받아옴
if(originalFileName.equals("")) {
return null;
}
//확장자 추출(abc.txt)
//-> listIndexOf(",") : . 맨뒤부터 .까지의 문자를 가져온다는 뜻(확자명을 가져온다)
String fileExt =
originalFileName.substring(originalFileName.lastIndexOf("."));
//확장자가 없을 때 -검증
if(fileExt==null || fileExt.equals("")) {
return null;
}
//서버에 저장할 새로운 파일이름 생성
newFileName = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", Calendar.getInstance());
newFileName += System.nanoTime(); //나노타임까지붙여 절대 중복 x /10의 -9승
newFileName += fileExt; //확장자를 붙여줌
//파일 업로드
File f = new File(path);
if(!f.exists()) {
f.mkdirs(); //디렉토리 만들어라
}
//fileData를 fullFilePath로 내보낸다.@중요@
String fullFilePath = path + File.separator + newFileName;
//여기서 실제 업로드
// - 업로드하는 파일을 배열에 담아 출력
byte[] fileData = upload.getFileData();
//fullFilePath에 실제 경로를 담아 FileOutputStream에 넣는다.
FileOutputStream fos = new FileOutputStream(fullFilePath);
fos.write(fileData); //여기까지
fos.close();
//newFileName을 반환 - doFileUpload 메서드를 호출하면 newFileName을 반환한다.
return newFileName;
}
FileManager 클래스 전체 소스코드
package com.util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Calendar;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.upload.FormFile;
public class FileManager {
//파일 업로드
//반환값이 있는 이유는 파일을 업로드할 때 a.txt를 올리면 뒤의 .txt를 빼버리고
//새롭게 저장하는 saveName으로 바꾸고 다시 확장자를 붙여
//DB에 저장(Original이랑 이름이 다름)
public static String doFileUpload(FormFile upload, String path) throws IOException {
// OriginalFileName : 클라이언트가 업로드한 파일 이름
// newFileName : 서버에 저장할 새로운 파일 이름
String newFileName = null;
if(upload==null) {
return null;
}
//클라이언트가 업로드한 파일 이름
String originalFileName = upload.getFileName();//오리지날 파일네임을 받아옴
if(originalFileName.equals("")) {
return null;
}
//확장자 추출(abc.txt)
//-> listIndexOf(",") : . 맨뒤부터 .까지의 문자를 가져온다는 뜻(확자명을 가져온다)
String fileExt =
originalFileName.substring(originalFileName.lastIndexOf("."));
//확장자가 없을 때 -검증
if(fileExt==null || fileExt.equals("")) {
return null;
}
//서버에 저장할 새로운 파일이름 생성
newFileName = String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", Calendar.getInstance());
newFileName += System.nanoTime(); //나노타임까지붙여 절대 중복 x /10의 -9승
newFileName += fileExt; //확장자를 붙여줌
//파일 업로드
File f = new File(path);
if(!f.exists()) {
f.mkdirs(); //디렉토리 만들어라
}
//fileData를 fullFilePath로 내보낸다.@중요@
String fullFilePath = path + File.separator + newFileName;
//여기서 실제 업로드
// - 업로드하는 파일을 배열에 담아 출력
byte[] fileData = upload.getFileData();
//fullFilePath에 실제 경로를 담아 FileOutputStream에 넣는다.
FileOutputStream fos = new FileOutputStream(fullFilePath);
fos.write(fileData); //여기까지
fos.close();
//newFileName을 반환 - doFileUpload 메서드를 호출하면 newFileName을 반환한다.
return newFileName;
}
/*
파일 다운로드
saveFileName : 서버에 저장된 파일명
originalFileName : 클라이언트가 업로드한 파일명
path : 서버에 저장된 실제 경로
서버에 있는 파일을 읽어서 클라이언트에게 보내는 것이기 때문에 req가 아니라 resp가 매개변수로 사용
*/
public static boolean doFileDownload(HttpServletResponse response, String saveFileName,
String originalFileName, String path) {
try {
//파일 경로
String filePath = path + File.separator + saveFileName;
//클라이언트가 설정한 파일명이 없을 경우 서버에 저장된 파일명으로 입력
if(originalFileName==null||originalFileName.equals("")) {
originalFileName = saveFileName; //검증
}
//파일을 다운받아 클라이언트 컴에 저장할때 한글이름 깨짐방지
originalFileName = new String(originalFileName.getBytes("euc-kr"),"ISO-8859-1");//인코딩
//ISO를 생략하고 써도 된다. 그때는 언더바를 써준다.
File f = new File(filePath);
//파일이 존재하지 않으면 stop
if(!f.exists()) {
return false;
}//여기를 통과한건 파일이 왔다는거. 다운로드는 아래 리스폰스
//파일의 종류.ContentType를 설정
// .txt와 같이 파일확장자 앞에 붙는.을 octet-stream이라고 함
response.setContentType("application/octet-stream");
//헤더 정보 - setHeader로 파일 다운로드가 되는 것을 보이게 하고, 파일명을 알려줌
response.setHeader("Content-disposition", "attachment;fileName=" + originalFileName);
//서버에서 클라이언트로 보낼 때 Fileinputstream으로 파일을 읽은 후 bis에 넣은 것
//여기서 받은 정보는 인풋스트림으로 읽어서 아웃풋 스트림으로 내보낸다.
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
//읽은 파일을 내보낼 때 outputstream 사용
OutputStream out = response.getOutputStream();
int data;
byte[] bytes = new byte[4096];
//byte를 0부터 데이터가 있는만큼 내보내라
while((data=bis.read(bytes, 0, 4096))!=-1) {//바이트의 영번째, 부터 4096까지 읽어와라
out.write(bytes,0,data);//데이터에 있는 내용을 다 읽어와라
}
out.flush(); //flush 닫기
out.close();
bis.close();
} catch (Exception e) {
System.out.println(e.toString());
return false;
}
return true;
}
//파일삭제
public static void doFileDelete(String fileName, String path) {//이름과 위치를 받아서
try {
String filePath = path + File.separator + fileName;
File f = new File(filePath);
//파일한테 넘겨줘요
if(f.exists())
f.delete(); // 물리적인 파일 삭제
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
JSP 파일 생성하기 - 파일 리스트 조회 페이지(list.jsp)
- View
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
request.setCharacterEncoding("UTF-8");
String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<br/><br/>
<table width="500" align="center">
<tr height="30">
<td align="right">
<input type="button" value="파일 올리기"
onclick="javascript:location.href='<%=cp%>/fileTest.do?method=write';">
</td>
</tr>
</table>
<table width="500" align="center" border="1" style="font-size: 10pt;">
<tr height="30" align="center">
<td width="50">번호</td>
<td width="200">제목</td>
<td width="200">파일</td>
<td width="50">삭제</td>
</tr>
<c:forEach var="dto" items="${lists }">
<tr onmouseover="this.style.backgroundColor='#e4e4e4'"
onmouseout="this.style.backgroundColor=''" bgcolor="#ffffff">
<td width="50" align="center">${dto.listNum }</td>
<td width="200" align="left">${dto.subject }</td>
<td width="200" align="left"><a href="${dto.urlFile }">${dto.originalFileName }</a></td>
<td width="50" align="center">
<a href="<%=cp %>/fileTest.do?method=delete&num=${dto.num}">
삭제</a></td>
</tr>
</c:forEach>
<c:if test="${totalDataCount==0 }">
<tr bgcolor="#ffffff">
<td align="center" colspan="5">등록된 자료가 없습니다.</td>
</tr>
</c:if>
</table>
<c:if test="${totalDataCount!=0 }">
<table width="500" border="0" cellpadding="0" cellspacing="3" align="center">
<tr align="center">
<td align="center" height="30">
${pageIndexList }
</td>
</tr>
</table>
</c:if>
</body>
</html>
최종 실행화면
파일 업로드 경로
C:\java\work\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\struts\pbs\saveFile
DB
파일 업로드 페이지
파일 조회 페이지
파일을 클릭하면 다운로드가 된다. 삭제를 누르면 파일 경로(saveFile) 폴더 내에서 삭제되면서 DB의 데이터도 삭제된다.
FileAction list에 있던 파일 번호 재정렬 작업(일렬 번호) 정리
- FileAction 클래스의 list메서드에 있는 일렬 번호 재정렬 작업에 대해 정리하고자 한다.
//번호 재정렬 작업
Iterator<Object> it = lists.iterator();
int listNum,n=0;
String str;
while(it.hasNext()) {
//전체 데이터 갯수가 6개일 때
//리스트번호가 10 8 6(start=1) / 5 4 3(start=4)라 가정해보면
// 1 2 3 / 4 5 6
FileTestForm dto = (FileTestForm)it.next();
listNum = totalDataCount - (start + n - 1);
dto.setListNum(listNum);
n++;
일렬 번호(listNum) : 단, 한 페이지에 3개의 게시글이 페이징 된다는 가정
Num | 번호 재정렬 (listNum) |
listNum = totalDataCount - (start + n -1) | start |
10 | 6 | 6 - (1 + 0 -1) | start = 1 |
8 | 5 | 6 - (1 + 1 - 1) | |
6 | 4 | 6 - (1 + 2 - 1) | |
5 | 3 | 6 - (4 + 0 - 1) | start = 4 |
4 | 2 | 6 - (4 + 1 - 1) | |
3 | 1 | 6 - (4 + 2 - 1) |
오늘은 Struts1 + iBatis를 활용하여 파일 업로드, 파일 다운로드, 파일 삭제 게시판을 배워서 정리하였다.
아직 Struts1와 iBatis가 익숙하지 않지만 다시 한번 정리를 하니 점점 눈에 들어오기 시작한다!
벌써 수업을 시작한 지 50%가 되었다. 5월 말에 수료하는데 시간이 참 빠르다.
'Back-End > JSP & Struts & JDBC' 카테고리의 다른 글
[Struts2] Struts2 + iBatis를 이용한 답변 형 게시판 (0) | 2022.03.13 |
---|---|
[Struts 2] Struts2/iBatis 초기 세팅 , Struts2 예제 (2) | 2022.03.11 |
[Struts1] Struts1/iBatis 게시판 만들기 (0) | 2022.03.09 |
iBatis(2.0) 설치 및 초기 세팅 (0) | 2022.03.08 |
[Struts 1] 설치 및 초기 세팅, 게시판 만들기 (0) | 2022.03.07 |
블로그의 정보
무작정 개발
무작정 개발