01.JAVA/Java2009. 6. 16. 20:16
반응형
multipart form parser - http file upload, database 저장 java class 연재2

이번글에서는 업로드된 파일을 저장할때 database에 record를 함께 insert 하는 기능에 대해서 
설명하겠습니다. 설명하기 전에 이전 글에서 대용량 파일 업로드 기능에 대해서 다시 한번 review하고
다시 자세히 설명하겠습니다.

1. 대용량 파일 업로드 기능 (1G 이상 파일 업로드에도 문제가 없는 기능)
2. 파일 업로드시 upload 진행 상황을 Internet Explorer에서 볼수 있을것 (다음번 글에서 올리겠습니다.)

WCPage.java : JSP page context와 request parameter를 저장하는 java class
WCMultipartFormParser.java : http request stream을 parsing하는 java class
WCMultipartFormElement.java : multipart form lement를 저장하는 java class

// form html 일부분 시작
<form name="fParam" encType="multipart/form-data">
<input type="hidden" name="_cmd" value="file_data">
<input type="file" name="file">
</form>
// form html 일부분 끝

form을 javascript에서 서버로 submit하면 
아래와 같은 http request stream이 서버로 전달됩니다.

// http request stream 시작
-----------------------------7d82efc203cc
Content-Disposition: form-data; name="_cmd"

uploadFile
-----------------------------7d82efc203cc
Content-Disposition: form-data; name="file"; filename="C:\test.txt"
Content-Type: text/plain

test
-----------------------------7d82efc203cc--
// http request stream 끝

위의 request stream을 parsing하는 pseudo code 입니다.

// pseudo code 시작
JSP page
  -> WCPage.initCtrl
    -> WCPage.initCtrl
      -> WCPage.isMultipart()
      -> WCMultipartFormParser.init()
        -> WCMultipartFormParserparseContent(oRequest)
          -> WCMultipartFormParserparseContentEx(oRequest)
            -> WCMultipartFormParserfindBoundary() : -----------------------------7d82efc203cc 이 부분을 parsing합니다.
            -> WCMultipartFormParserfindHeader() : Content-Disposition: form-data; name="_cmd" 이 부분을 parsing 합니다.
              -> WCMultipartFormElement.setHeader : header 정보를 element에 저장합니다.
            -> WCMultipartFormParser.procContent() : content body를 parsing 합니다.
              -> 임시파일에 파일 저장 : content type이 file인경우
              -> parameter인경우 WCProperties m_rParam 에 parameter 이름과 value를 저장
      -> WCMultipartFormParser.saveFile(sDir)
        -> WCMultipartFormElement.saveFile(sPathFile)
// pseudo code 끝

대용량 파일을 서버에 업로드 하기 위해서는 업로드 되는 파일을 임시 directory에
임시 파일로 저장을 하고 다시 개발자가 원하는 디렉토리로 파일을 이동하는 방식을 
사용합니다. (임시로 저장하는 이유는 memory에 파일을 모두 load하고 있을 수 없기
때문입니다.)
위의 코드에서 procContent에서 파일 내용을 임시 디렉토리에 저장합니다.
WCMultipartFormParser.procContent

사용자가 파일을 임시 디렉토리에서 운영용 file directory로 이동하고자 하면
WCMultipartFormParser.saveFile(sDir) 을 호출합니다.

이 함수를 form에 있는 element들 중에서 file인 경우 이 파일을 사용자가 지정한 sDir로 
이동을 합니다.

// WCMultipartFormParser.saveFile code 시작
public void saveFile(String sDir)
{
    try
    {
        Vector vElement = this.getElements();
        int nCount = WCVector.size(vElement);
        for (int i=0;i<nCount;i++)
        {
            WCMultipartFormElement oElmt = (WCMultipartFormElement)WCVector.getObjAt(vElement,i);
            if (oElmt == null)
            {
                continue;
            }
            if (!oElmt.isFile())
            {
                continue;
            }
            String sTempFileName = oElmt.getCloneFileName();
            if (WCString.isEmpty(sTempFileName))
            {
                continue;
            }
            String sUserDirectoryFile = WCString.buildFilePath(sDir,sTempFileName,"/");
            oElmt.saveFile(sUserDirectoryFile);
        }
    }
    catch (Exception ex)
    {
        WCLog.getInstance().printLog("exception at WCMultipartFormParser.saveFile "+ex.toString());
    }
}        
// WCMultipartFormParser.saveFile code 끝

WCMultipartFormParser.saveFile 에서
WCMultipartFormElement.saveFile을 호출합니다.
WCMultipartFormElement.saveFile 함수는 임시로 저장된 file을 사용자가 지정한 path의 file로
copy한 다음 임시 파일을 삭제하는 코드입니다.

// WCMultipartFormElement.saveFile code 시작
public int saveFile(String sPathFile)
{
    try
    {
        if (sPathFile == null)
            return -1;
        String sDir = WCString.getPath(sPathFile);
        WCSystem oSys = WCSystem.getInstance();
        oSys.CreateDir(sDir);
        String sSaveFileName = sPathFile;
        setSaveFileName(sSaveFileName);
        File oSrcFile = new File(getTempFileName());
        File oDestinationFile = new File(sSaveFileName);
        FileInputStream oFIS = null;
        FileOutputStream oFOS = null;
        try
        {
            oFIS = new FileInputStream(oSrcFile);
            oFOS = new FileOutputStream(oDestinationFile);
            byte[] oBuffer = new byte[1024 * 4];
            int nRead = 0;
            while ((nRead = oFIS.read(oBuffer)) != -1) 
            {
                oFOS.write(oBuffer, 0, nRead);
            }
            oFIS.close();
            oFOS.close();
            oFIS = null;
            oFOS = null;
            oSrcFile.delete();
        }
        catch (Exception e) 
        {
            WCLog.getInstance().printLog("exception at WCMultipartFormElement.saveFile "+e.toString());
            if (oFIS != null)
            {
                oFIS.close();
            }
            if (oFOS != null)
            {
                oFOS.close();
            }
            e.printStackTrace(); 
        }
    }
    catch(IOException ioe)
    {
        WCLog.getInstance().printLog("exception at WCMultipartFormElement.saveFile "+ioe.toString());
        ioe.printStackTrace();
    }
    return 0;
}
// WCMultipartFormElement.saveFile code 시작

파일을 사용자가 원하는 디렉토리로 복사를 하면서 file 관련 정보를 database에 insert하기 위해서는
WCMultipartFormParser 로 부터 상속받은 class를 정의합니다.
그리고 saveFile method를 재 정의합니다.
그리고 아래와 같이 함수를 정의합니다.

// WCMultipartFormParser에서 상속받은 MyFormParser java class sample 시작
public class MyFormParser extends WCMultipartFormParser 
{
    public void saveFile(String sDir)
    {
        try
        {
            super.saveFile(sDir);
            
            Vector vElement = this.getElements();
            int nCount = WCVector.size(vElement);
            for (int i=0;i<nCount;i++)
            {
                WCMultipartFormElement oElmt = (WCMultipartFormElement)WCVector.getObjAt(vElement,i);
                if (oElmt == null)
                {
                    continue;
                }
                if (!oElmt.isFile())
                {
                    continue;
                }
                String sPhyFile = oElmt.getSaveFileName();
                String sOrgName = oElmt.getName();
                WCStmt oStmt = new WCStmt();
                oStmt.executeUpdate("insert into tb_file (xxx) values(xxx,'"+sFile+"')",null,"WDLDatabasePool");
            }
        }
        catch (Exception ex)
        {
            WCLog.getInstance().printLog("exception at MyFormParser.saveFile "+ex.toString());
        }
    }
}
// WCMultipartFormParser에서 상속받은 MyFormParser java class sample 끝

물론 이와 같이 OOP의 inheritance와 overriding 기법을 사용하지 않고

// inheritance와 overriding 기법을 사용하지 않고 직접 호출방식으로 구현한 소스 일부분 시작
    WCMultipartFormParser oFormParser = new WCMultipartFormParser(this);
    oFormParser.setDebug(true);
    oFormParser.init();
    oFormParser.saveFile(sDir);
    
    Vector vElement = this.getElements();
    int nCount = WCVector.size(vElement);
    for (int i=0;i<nCount;i++)
    {
        WCMultipartFormElement oElmt = (WCMultipartFormElement)WCVector.getObjAt(vElement,i);
        if (oElmt == null)
            continue;
        if (oElmt.isFile())
        {
            String sName = oElmt.getName();
            String sPhyFileName = oElmt.getSaveFileName();
            WCStmt oStmt = new WCStmt();
            oStmt.executeQuery("insert into table(xxx,xxx) values(xxx,'"+sPhyFileName+"')",null,sDsn);
        }
    }
// inheritance와 overriding 기법을 사용하지 않고 직접 호출방식으로 구현한 소스 일부분 끝
    
이와 같이 직접 호출하는 방식을 사용해도 됩니다.

아래의 소스는 Web Development Library(http://www.webdevlib.net)에서 소스의 일부분만을 추출하여
재구성한 sample입니다. 첨부한 소스만으로도 어느정도 동작이 가능하지만 WCProperties,WCVector,WCLog,WCSystem,WCEnv
등의 파일은 http://www.webdevlib.net에서 다운받아 사용하십시요
소스의 일부분은 고의로 누락한 것은 아닙니다. 모든 소스를 설명하려니 너무 많기때문에
중요한 부분을 추출하여 sample로 구성하면서 최대한 이해가 쉽도록 재구성을 하였습니다.

제공하는 sample code는 3개의 파일로 구성됩니다

file_upload_progress1.jsp
WCMultipartFormParser.java
WCMultipartFormElement.java

아래의 sample에서 개발자는 WCMultipartFormParser.java 이부분에서 multipart form을 parsing하는 부분만을
참고하여 사용할 수도 있을 것입니다.

아무튼 개발자에게 유용한 코드가 되길 바랍니다.

// file_upload_progress1.jsp 소스 시작
<%@ page language="java" import="wdl.*,java.util.*,java.sql.*,java.lang.*,java.io.*,java.io.File " contentType="text/html; charset=EUC-KR"%>
<%
    WCPage oPage = new WCPage();
    if (oPage.initCtrl(pageContext) > 0)
    {
        return;
    }
%>
<%@ include file="/wdl/src/java/WCMultipartFormParser.java"%>
<%@ include file="/wdl/src/java/WCMultipartFormElement.java"%>
<%!
public class WCPage
{
    public int initCtrl(javax.servlet.jsp.PageContext oPageContext)
    {
        return initCtrl(
            (javax.servlet.http.HttpServletRequest)oPageContext.getRequest()
            ,(javax.servlet.http.HttpServletResponse)oPageContext.getResponse()
            ,(javax.servlet.jsp.JspWriter)oPageContext.getOut()
            ,(javax.servlet.http.HttpSession)oPageContext.getSession()
            ,(javax.servlet.ServletContext)oPageContext.getServletContext()
            ,oPageContext
            ,(javax.servlet.ServletConfig)oPageContext.getServletConfig()
            );
    }
    public int initCtrl(
        javax.servlet.http.HttpServletRequest oRequest
        ,javax.servlet.http.HttpServletResponse oResponse
        ,javax.servlet.jsp.JspWriter oOut
        ,javax.servlet.http.HttpSession oSession
        ,javax.servlet.ServletContext oApplication
        ,javax.servlet.jsp.PageContext oPageContext
        ,javax.servlet.ServletConfig oConfig)
    {
        try
        {
            m_request = oRequest;
            m_response = oResponse;
            m_out = oOut;
            m_session = oSession;
            m_application = oApplication;
            m_pageContext = oPageContext;
            m_config = oConfig;
            
            if (isMultipart())
            {
                WCMultipartFormParser oFormParser = new WCMultipartFormParser(this);
                oFormParser.setDebug(true);
                oFormParser.init();
                byte[] btDebugBuf = oFormParser.getDebugBuf();
                String sDebug = new String(btDebugBuf);
                this.printOut("<pre>");
                this.printOut(sDebug);
                this.printOut("</pre>");
                
                WCProperties rParam = oFormParser.getParam();
                this.printOut(rParam.serializeOut());

                String sDir = "c:/tmp3";
                oFormParser.saveFile(sDir);
                return 1;
            }
        }
        catch (Exception ex)
        {
        }
        return 0;
    }
    public javax.servlet.http.HttpServletRequest m_request = null; 
    public javax.servlet.http.HttpServletResponse m_response = null; 
    public javax.servlet.jsp.JspWriter m_out = null; 
    public javax.servlet.http.HttpSession m_session = null; 
    public javax.servlet.ServletContext m_application = null; 
    public javax.servlet.jsp.PageContext m_pageContext = null; 
    public javax.servlet.ServletConfig m_config = null; 
    
    public javax.servlet.http.HttpSession getSession()
    {
        return m_session;
    }
    public javax.servlet.http.HttpServletRequest getRequest()
    {
        return m_request;
    }
    public javax.servlet.jsp.PageContext getPageContext()
    {
        return m_pageContext;
    }

    public boolean isMultipart()
    {
        HttpServletRequest oRequest = (javax.servlet.http.HttpServletRequest)m_request;
        String content_type = oRequest.getHeader("content-type");
        if (WCString.indexOf(WCString.toUpper(content_type),"MULTIPART") == 0)
        {
            return true;
        }
        return false;
    }
}
%>
<form name="fParam" encType="multipart/form-data">
<input type="hidden" name="_cmd" value="file_data">
<input type="file" name="file">
</form>
<a href="javascript:uploadFile();">upload the file</a>
<iframe id="ifrmAction" name="ifrmAction" width="0" height="0"></iframe> 

<script>
function uploadFile()
{
    var fParam = window.document.fParam;
    fParam._cmd.value = "uploadFile";
    fParam.method = "post";
    fParam.target = "_blank";
    fParam.submit();
}
</script>
// file_upload_progress1.jsp 소스 끝



// WCMultipartFormParser.java 소스 시작
package wdl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;
    public class WCMultipartFormParser 
    {
        public String m_sCharset;
        private HttpServletResponse resp;
        private ServletContext m_oApp;
        public Vector m_vElement = null;
        public WCProperties m_rParam = null;
        public WCPage m_oPage = new WCPage();
        public WCMultipartFormParser() 
        {
            refresh();
        }
        public WCMultipartFormParser(WCPage oPage) 
        {
            refresh();
            setPage(oPage);
        }
        public void init()
        {
            WCPage oPage = getPage();
            if (oPage == null)
                return;
            HttpServletRequest oRequest = (javax.servlet.http.HttpServletRequest)oPage.getRequest();
            parseContent(oRequest);
        }
        public void init(WCPage oPage)
        {
            setPage(oPage);
            init();
        }
        public int m_nContentLength = 0;
        public byte[] m_btBuf = null;
        public int m_nBufIdx = 0;
        public int m_nBoundaryLen = 0;
        public byte m_btBoundary[] = null;
        public int m_nBufReadSize = 0;
        public int m_nBufAllocSize = 1024*64;
        public int m_nCurrentBuffer = 0; 
        public int m_nBufferCount = 0;
        public int m_nAccumRead = 0;
        public InputStream m_oInputStream = null;
        public int m_nAccumBufIdx = 0;
        public String getEnvValue(String sProp)
        {
            WCEnv env = WCEnv.getInstance();
            if (env != null)
            {
                WCProperties rcd = env.getProperties();
                if (rcd != null)
                {
                    String sVal = rcd.getStrValue(sProp);
                    return sVal;
                }
            }
            return "";
        }
        public void refresh()
        {
            m_vElement = new Vector();
            m_rParam = new WCProperties();
            String sSrcCharset = getEnvValue("charset"); 
            if (WCString.isEmpty(sSrcCharset))
            {
                sSrcCharset = "KSC5601"; 
            }
            m_sCharset = sSrcCharset;
            m_nContentLength = 0;
            m_btBuf = null;
            m_nBufIdx = 0;
            m_nBoundaryLen = 0;
            m_btBoundary = null;
            m_nBufReadSize = 0;
            m_nBufAllocSize = 1024*64;
            m_nCurrentBuffer = 0; 
            m_nAccumRead = 0;
            m_oInputStream = null;
            m_nAccumBufIdx = 0;
            m_nBufferCount = 0;
            m_nPrevAccumBufIdx = 0;
        }
        public byte[] setByte(byte btBuf[],int nIdx,byte btChar)
        {
            {
                int nSize = 0;
                if (btBuf != null)
                    nSize = btBuf.length;
                if (nIdx >= nSize)
                {
                    int nMax = nIdx+32;
                    byte btNew[] = new byte[nMax];
                    for (int i=0;i<nMax;i++)
                    {
                        btNew[i] = 0;
                    }
                    for (int i=0;i<nSize;i++)
                    {
                        btNew[i] = btBuf[i];
                    }
                    btNew[nIdx] = btChar;
                    btBuf = btNew;
                }
                else
                {
                    btBuf[nIdx] = btChar;
                }
                return btBuf;
            }
        }
        public byte[] m_btDebugBuf = null;
        public byte[] getDebugBuf()
        {
            return m_btDebugBuf;
        }
        public byte[] append(byte btBuf[],byte btAppend[],int nLen)
        {
            try
            {
                if (btAppend == null)
                    return null;
                if (btBuf == null)
                {
                    btBuf = new byte[nLen];
                }
                int nSize = btBuf.length;
                int nNewSize = nSize+nLen;
                byte btNew[] = new byte[nNewSize];
                for (int i=0;i<nNewSize;i++)
                {
                    btNew[i] = 0;
                }
                for (int i=0;i<nSize;i++)
                {
                    btNew[i] = btBuf[i];
                }
                for (int i=0;i<nLen;i++)
                {
                    btNew[i+nSize] = btAppend[i];
                }
                btBuf = btNew;
                return btBuf;
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.append "+ex.toString());
            }
            return null;
        }
        public byte[] copyBytes(byte btSrc[],int nStartIdx,int nEndIdx)
        {
            try
            {
                int nLen = nEndIdx-nStartIdx;
                if (nLen <= 0)
                    return null;
                int nAlloc = nLen;
                byte btNew[] = new byte[nAlloc];
                for (int i=0;i<nAlloc;i++)
                {
                    btNew[i] = 0;
                }
                for (int i=0;i<nLen;i++)
                {
                    btNew[i] = btSrc[i+nStartIdx];
                }
                return btNew;
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.copyBytes "+ex.toString());
            }
            return null;
        }
        public void parseContent(HttpServletRequest oRequest) 
        {
            try
            {
                Vector vDataHeader = parseContentEx(oRequest);
            }
            catch(Exception crfe)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.parseContent "+crfe.toString());
                crfe.printStackTrace();
            }
        }
       
        public void setResponse(HttpServletResponse resp) 
        {
            this.resp = resp;
        }
        public void setContext(ServletContext oApp) 
        {
            this.m_oApp = oApp;
        }
        public boolean findBoundary()
        {
            try
            {
                m_btBoundary = null;
                m_nBoundaryLen = 0;
                int nLen = 0;
                m_btBoundary = setByte(m_btBoundary,nLen,(byte)13); 
                nLen ++;
                m_btBoundary = setByte(m_btBoundary,nLen,(byte)10); 
                nLen ++;
                boolean bBoundaryFound = false;
                while (isEof() != true)
                {
                    byte btByte = getByte();
                    if (btByte == 13)
                    {
                        bBoundaryFound = true;
                        m_nBoundaryLen = nLen;
                        getByte();
                        break;
                    }
                    m_btBoundary = setByte(m_btBoundary,nLen,btByte);
                    nLen ++;
                }
                if (bBoundaryFound == true)
                {
                    m_btBoundary = copyBytes(m_btBoundary,0,nLen);
                    return true;
                }
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.findBoundary "+ex.toString());
            }
            return false;
        }
        public String findHeader()
        {
            try
            {
                int nLen = 0;
                byte btHeader[] = null;
                boolean bFound = false;
                byte btByte = 0;
                byte btByte2 = 0;
                while (isEof() != true)
                {
                    btByte = getByte();
                    btByte2 = getByte(); 
                    btByte2 = getByte(); 
                    putBackByte();
                    putBackByte();
                    if (btByte == 13 && btByte2 == 13) 
                    {
                        getByte();
                        getByte();
                        getByte(); 
                        bFound = true;
                        break;
                    }
                    btHeader = setByte(btHeader,nLen,btByte);
                    nLen ++;
                }
                btHeader = copyBytes(btHeader,0,nLen);
                String sDataHeader = new String(btHeader,m_sCharset); 
                return sDataHeader;    
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.findHeader "+ex.toString());
            }
            return null;
        }
        public boolean isBoundary()
        {
            try
            {
                int boundaryKeyPosition = 0;
                boundaryKeyPosition = 0;
                boolean binaryEndFound = false;
                binaryEndFound = false;
                byte btByte = (byte)0;
                int nLen = 0;
                while (isEof() != true)
                {
                    btByte = getByte();
                    nLen ++;
                    if (btByte == m_btBoundary[boundaryKeyPosition])
                    {
                        if (boundaryKeyPosition == m_nBoundaryLen-1 )
                        {
                            binaryEndFound = true;
                            getByte(); 
                            getByte(); 
                            break;
                        }
                        boundaryKeyPosition++;
                    }
                    else
                    {
                        for (int i=0;i<nLen;i++)
                        {
                            putBackByte();
                        }
                        break;
                    }
                }
                return binaryEndFound;
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.isBoundary "+ex.toString());
            }
            return false;
        }
        public void putBackByte()
        {
            m_nBufIdx --;
            m_nAccumBufIdx --;
            if (m_nBufIdx < 0)
            {
                m_nCurrentBuffer --;
                if (m_nCurrentBuffer < 0)
                {
                }
                m_nBufIdx = (m_nBufAllocSize/2) - 1;
            }
        }
        public boolean m_bDebug = false;
        public void setDebug(boolean bDebug)
        {
            m_bDebug = bDebug;
        }
        public boolean isDebug()
        {
            return m_bDebug;
        }
        public boolean isEof()
        {
            if (m_nAccumBufIdx < m_nContentLength)
            {
                return false;
            }
            return true;
        }
        public byte getByte() throws Exception
        {
            byte btData = getByteEx();
            setProgress(m_nAccumBufIdx);
            return btData;
        }
        public byte getByteEx() throws Exception
        {
            try
            {
                if (m_oInputStream == null)
                {
                    m_oInputStream = m_oPage.getRequest().getInputStream();
                }
                if (m_btBuf == null)
                {
                    m_btBuf = new byte[m_nBufAllocSize+32];
                    if (m_btBuf == null)
                    {
                        return (byte)0;
                    }
                    for (int i=0;i<m_nBufAllocSize+32;i++)
                    {
                        m_btBuf[i] = (byte)0;
                    }
                }
                if (m_nBufIdx >= m_nBufReadSize && m_nAccumRead < m_nContentLength && m_nBufferCount == m_nCurrentBuffer)
                {
                    if (m_nBufReadSize == m_nBufAllocSize/2)
                    {
                        m_nBufReadSize = 0;
                        m_nCurrentBuffer ++;
                        m_nBufferCount ++;
                    }
                    int nMaxRead = m_nBufAllocSize/2 - m_nBufReadSize; 
                    if (nMaxRead > m_nContentLength-m_nAccumRead)
                    {
                        nMaxRead = m_nContentLength-m_nAccumRead;
                    }
                    int nRead = m_oInputStream.read(m_btBuf
                        ,(m_nCurrentBuffer%2)*(m_nBufAllocSize/2) + m_nBufReadSize
                        ,nMaxRead);
                    if (this.isDebug())
                    {
                        m_btDebugBuf = this.append(m_btDebugBuf,m_btBuf,nRead);
                    }
                    m_nBufReadSize += nRead;
                    m_nAccumRead += nRead;
                    if (m_nBufReadSize >= m_nBufAllocSize/2)
                    {
                    }
                    m_nBufIdx = m_nBufIdx % (m_nBufAllocSize/2);
                }
                byte btByte = m_btBuf[(m_nCurrentBuffer%2)*(m_nBufAllocSize/2) + m_nBufIdx];
                m_nBufIdx ++;
                if (m_nBufIdx == m_nBufAllocSize/2 && m_nCurrentBuffer < m_nBufferCount)
                {
                    m_nCurrentBuffer ++;
                    m_nBufIdx = 0;
                }
                m_nAccumBufIdx ++;
                return btByte;
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.getByteEx "+ex.toString());
                setProgress(m_nContentLength);
                Exception oEx = new Exception("exception at getByte");
                throw oEx;
            }
        }
        public int procContent()
        {
            try
            {
                if (m_oCurElement.isFile())
                {
                    try
                    {
                        FileOutputStream oFileStream = m_oCurElement.createTempFile();
                        if (oFileStream == null)
                        {
                            return -1;
                        }
                        int nBufSize = 1024*4;
                        byte[] btBuf = new byte[nBufSize];
                        int nLen = 0;
                        byte btByte = 0;
                        while (isEof() != true)
                        {
                            btByte = getByte();
                            if (btByte == (byte)13) 
                            {
                                putBackByte();
                                if (isBoundary() == true)
                                {
                                    break;
                                }
                                btByte = getByte(); 
                            }
                            btBuf[nLen] = btByte;
                            nLen ++;
                            if (nLen >= nBufSize)
                            {
                                if (oFileStream != null)
                                {
                                    oFileStream.write(btBuf,0,nBufSize);
                                }
                                nLen = 0;
                            }
                        }
                        if (nLen > 0)
                        {
                            if (oFileStream != null)
                            {
                                oFileStream.write(btBuf,0,nLen);
                            }
                        }
                        m_oCurElement.closeTempFile();
                    }
                    catch (Exception ex)
                    {
                        WCLog.getInstance().printLog("exception at WCMultipartFormParser.procContent "+ex.toString());
                        m_oCurElement.closeTempFile();
                        m_oCurElement.deleteTempFile();
                        return -1;
                    }
                }
                else
                {
                    byte btContent[] = null;
                    int nLen = 0;
                    byte btByte = 0;
                    while (isEof() != true)
                    {
                        if (isBoundary() == true)
                            break;
                        btByte = getByte();
                        btContent = setByte(btContent,nLen,btByte);
                        nLen ++;
                    }
                    String sValue = null;
                    if (nLen > 0)
                    {
                        btContent = copyBytes(btContent,0,nLen);
                        sValue = new String(btContent,m_sCharset);
                    }
                    else
                    {
                        sValue = "";
                    }
                    String sProp = m_oCurElement.getFieldName();
                    if (btContent != null)
                    {
                    }
                    else
                    {
                    }
                    if (m_rParam == null)
                    {
                        m_rParam = new WCProperties();
                    }
                    m_rParam.addValue(sProp,sValue);
                    m_oCurElement.setValue(sValue);
                }
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.procContent "+ex.toString());
                return -1;
            }
            return 0;
        }
        public WCMultipartFormElement m_oCurElement = null;
        public Vector parseContentEx(HttpServletRequest oRequest) 
        {
            int nLen = oRequest.getContentLength();
            setContentLength(nLen);
            m_nBufIdx = 0;
            m_btBoundary = null;
            m_nBoundaryLen = 0;
            int nState = 0; 
            try
            {
                m_nBufReadSize = 0;
                int nRead = 0;
                m_oInputStream = oRequest.getInputStream();
                while (isEof() != true)
                {
                    if (nState == 0)
                    {
                        findBoundary();
                        nState = 100;
                    }
                    else if (nState == 100)
                    {
                        String sHeader = findHeader();
                        if (sHeader != null)
                        {
                            nState = 200;
                            m_oCurElement = new WCMultipartFormElement(this);
                            m_oCurElement.setHeader(sHeader);
                            if (m_vElement == null)
                                m_vElement = new Vector();
                            m_vElement.addElement(m_oCurElement);
                        }
                        nState = 200;
                    }
                    else if (nState == 200)
                    {
                        int nRet = procContent();
                        if (nRet < 0)
                        {
                        }
                        nState = 100;
                    }
                }
            }
            catch(IOException ioe)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.parseContentEx "+ioe.toString());
                ioe.printStackTrace();
            }
            setProgress(m_nAccumBufIdx);
            return m_vElement;
        }
        public Vector getElements()
        {
            return m_vElement;
        }
        public String getFileName()
        {
            Vector vElement = getElements();
            int nCount = WCVector.size(vElement);
            for (int i=0;i<nCount;i++)
            {
                WCMultipartFormElement oElmt = (WCMultipartFormElement)WCVector.getObjAt(vElement,i);
                if (oElmt == null)
                    continue;
                if (oElmt.isFile())
                {
                    return oElmt.getName();
                }
            }
            return null;
        }
        public void deleteTempFile()
        {
            Vector vElement = getElements();
            int nCount = WCVector.size(vElement);
            for (int i=0;i<nCount;i++)
            {
                WCMultipartFormElement oElmt = (WCMultipartFormElement)WCVector.getObjAt(vElement,i);
                if (oElmt == null)
                    continue;
                if (oElmt.isFile())
                {
                    oElmt.deleteTempFile();
                }
            }
        }
        public String getPathName()
        {
            Vector vElement = getElements();
            int nCount = WCVector.size(vElement);
            for (int i=0;i<nCount;i++)
            {
                WCMultipartFormElement oElmt = (WCMultipartFormElement)WCVector.getObjAt(vElement,i);
                if (oElmt == null)
                    continue;
                if (oElmt.isFile())
                {
                    return oElmt.getPathName();
                }
            }
            return null;
        }
        
        public int getFileCount()
        {
            try
            {
                int nRet = 0;
                Vector vElement = getElements();
                int nCount = WCVector.size(vElement);
                for (int i=0;i<nCount;i++)
                {
                    WCMultipartFormElement oElmt = (WCMultipartFormElement)WCVector.getObjAt(vElement,i);
                    if (oElmt == null)
                        continue;
                    if (oElmt.isFile())
                    {
                        nRet ++;
                    }
                }
                return nRet;
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.getFileCount "+ex.toString());
            }
            return 0;
        }
        public void setCharset(String sCharset)
        {
            m_sCharset = sCharset;
        }        
        public String getCharset()
        {
            return m_sCharset;
        }
        public WCProperties getParam()
        {
            if (m_rParam == null)
                m_rParam = new WCProperties();
            return m_rParam;
        }
        public WCPage getPage()
        {
            return m_oPage;
        }
        public void setPage(WCPage oPage)
        {
            m_oPage = oPage;
        }
        public int getContentLength()
        {
            return m_nContentLength;
        }
        public int getRead()
        {
            return m_nAccumBufIdx;
        }
        public void setContentLength(int nLen)
        {
            m_nContentLength = nLen;
            if (m_oPage != null)
            {
                String sLen = new String(""+m_nContentLength);
                HttpSession oSession = m_oPage.getSession();
                if (oSession != null)
                {
                    oSession.putValue("wdl.WCMultipartFormParser.contentLength",sLen);
                }
            }
        }
        public int m_nPrevAccumBufIdx = 0;
        public void setProgress(int nParam)
        {
            int nRead = nParam;  
            m_nAccumBufIdx = nRead;
            if (m_nAccumBufIdx - m_nPrevAccumBufIdx < 1024 && (m_nAccumBufIdx < m_nContentLength))
            {
                return;
            }
            m_nPrevAccumBufIdx = m_nAccumBufIdx;
            if (m_oPage != null)
            {
                String sLen = new String(""+m_nAccumBufIdx);
                HttpSession oSession = m_oPage.getSession();
                if (oSession != null)
                {
                    oSession.putValue("wdl.WCMultipartFormParser.read",sLen);
                }
            }
        }        
        public void saveFile(String sDir)
        {
            try
            {
                Vector vElement = this.getElements();
                int nCount = WCVector.size(vElement);
                for (int i=0;i<nCount;i++)
                {
                    WCMultipartFormElement oElmt = (WCMultipartFormElement)WCVector.getObjAt(vElement,i);
                    if (oElmt == null)
                    {
                        continue;
                    }
                    if (!oElmt.isFile())
                    {
                        continue;
                    }
                    String sTempFileName = oElmt.getCloneFileName();
                    if (WCString.isEmpty(sTempFileName))
                    {
                        continue;
                    }
                    String sUserDirectoryFile = WCString.buildFilePath(sDir,sTempFileName,"/");
                    oElmt.saveFile(sUserDirectoryFile);
                }
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormParser.saveFile "+ex.toString());
            }
        }        
    }
// WCMultipartFormParser.java 소스 끝

// WCMultipartFormElement.java 소스 시작
package wdl;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;
    public class WCMultipartFormElement 
    {
        private boolean m_bFile = false;
        private String fieldName = null;
        private String fullPathName = null;
        private String m_sFileName = null;
        private String fileExtension = null;
        private String pathName = null;
        private String contentType = null;
        private String contentDisposition = null;
        private String mimeType = null;
        private String mimeSubType = null;
        private String m_sValue = null;
        public WCMultipartFormParser m_oParser;
        public WCMultipartFormElement(WCMultipartFormParser oParser) 
        {
            setMultipartFormParser(oParser);
            m_sValue = null;
            m_rUserData = new WCProperties();
            m_oFileOutputStream = null;
        }
        public void setMultipartFormParser(WCMultipartFormParser oParser)
        {
            m_oParser = oParser;
        }
        public WCMultipartFormParser getMultipartFormParser()
        {
            return m_oParser;
        }
        public FileOutputStream createTempFile()
        {
            try
            {        
                String sSourceFileName = getFileName();
                if (WCString.isEmpty(sSourceFileName))
                {
                    return null;
                }
                java.io.File oFile = null;
                m_sTempFileName = getTempFile(sSourceFileName);
                oFile = new java.io.File(m_sTempFileName);
                m_oFileOutputStream = new FileOutputStream(oFile);
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormElement.createTempFile "+ex.toString());
            }
            return m_oFileOutputStream;
        }
        public void closeTempFile()
        {
            try
            {
                if (m_oFileOutputStream != null)
                {
                    m_oFileOutputStream.close();
                }
                m_oFileOutputStream = null;
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormElement.closeTempFile "+ex.toString());
            }
        }
        public FileOutputStream getTempFileOutputStream()
        {
            FileOutputStream oRet = null;
            oRet = m_oFileOutputStream;
            return oRet;
        }    
        public void setHeader(String headerString) 
        {
            try
            {
                if (headerString == null)
                    return;
                this.m_bFile = headerString.indexOf("filename=\"") > 0;
                int startPosition = headerString.indexOf("name=\"") + "name=\"".length();
                int endPosition = headerString.indexOf("\"", startPosition);
                if( (startPosition > 0) && (endPosition > 0) )
                {
                    this.fieldName = headerString.substring(startPosition, endPosition);
                }
                if (this.isFile())
                {
                    startPosition = headerString.indexOf("filename=\"") + "filename=\"".length();
                    endPosition = headerString.indexOf("\"", startPosition);
                    if( (startPosition > 0) && (endPosition > 0) )
                    {
                        this.fullPathName = headerString.substring(startPosition, endPosition);
                    }
                    startPosition = headerString.indexOf("Content-Type: ") + "Content-Type: ".length();
                    if( startPosition > 0 )
                    {
                        this.contentType = headerString.substring(startPosition);
                    }
                    startPosition = headerString.indexOf("Content-Disposition: ") + "Content-Disposition: ".length();
                    endPosition = headerString.indexOf(";", startPosition);
                    this.contentDisposition = headerString.substring(startPosition, endPosition);
                    if ((startPosition = this.fullPathName.lastIndexOf(47)) > 0)
                    {
                        this.m_sFileName = this.fullPathName.substring(startPosition + 1);
                    }
                    else if((startPosition = this.fullPathName.lastIndexOf(92)) > 0)
                    {
                        this.m_sFileName = this.fullPathName.substring(startPosition + 1);
                    }
                    else 
                    {
                        this.m_sFileName = this.fullPathName;
                    }
                    if((startPosition = this.m_sFileName.lastIndexOf(46)) > 0 )
                    {
                    this.fileExtension = this.m_sFileName.substring(startPosition+1);
                    }
                    else
                    {
                    this.fileExtension = "";
                    }
                    if((startPosition = this.contentType.indexOf("/")) > 0)
                    {
                        this.mimeType = this.contentType.substring(0,startPosition);
                        this.mimeSubType = this.contentType.substring(startPosition+1);
                    }
                    else
                    {
                        this.mimeType = this.contentType;
                        this.mimeSubType = this.contentType;
                    }
                }
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormElement.WCMultipartFormElement "+ex.toString());
            }
        }
        public boolean isFile() 
        {
            return this.m_bFile;
        }
        public boolean isValidFile()
        {
            if (this.m_bFile == true && !WCString.isEmpty(getName()))
            {
                return true;
            }
            return false;
        }
        public String getFieldName() 
        {
            return this.fieldName;
        }
        public String getFullPathName() 
        {
            return this.fullPathName;
        }
        public String getFileName() 
        {
            return this.m_sFileName;
        }
        public String getName()
        {
            return getFileName();
        }
        public String getPathName()
        {
            return this.pathName;
        }
        public String getFileExtension() 
        {
            return this.fileExtension;
        }
        public String getContentType() 
        {
            return this.contentType;
        }
        public String getContentDisposition() 
        {
            return this.contentDisposition;
        }
        public String getMimeType() 
        {
            return this.mimeType;
        }
        public String getMimeSubType() 
        {
            return this.mimeSubType;
        }
        public void setValue(String sValue)
        {
            m_sValue = sValue;
        }
        public String getValue()
        {
            return m_sValue;
        }
        private int size = 0;
        private byte [] contents;
        public WCProperties m_rUserData = new WCProperties();
       
        public String m_sTempDirectory = "";
        public void setTempDirectory(String sVal)
        {
            m_sTempDirectory = sVal;
        }
        public String getTempDirectory()
        {
            if (WCString.isEmpty(m_sTempDirectory))
            {
                m_sTempDirectory = WCString.nullCheck(getEnvValue("tempdir"),getEnvValue("wdl.tempdir"));
                if (WCString.isEmpty(m_sTempDirectory))
                {
                    String sPath = getHome();
                    m_sTempDirectory = WCString.buildFilePath(sPath,"wdl/tmp","/");
                }
            }
            return m_sTempDirectory;
        }
        public String getHome()
        {
            String sHome = WCString.trim(getEnvValue("wdl.home"));
            if (WCString.isEmpty(sHome))
            {
                sHome = WCString.left(WCEnv.getInstance().getEnvFile(),"/WEB-INF");
            }
            return sHome;
        }
        public String getTempName()
        {
            try
            {
                java.util.Date dat = new java.util.Date();
                java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat ("yyyy");
                String sYear = formatter.format(dat);
                formatter = new java.text.SimpleDateFormat("MM");
                String sMonth = formatter.format(dat);
                formatter = new java.text.SimpleDateFormat("dd");
                String sDate = formatter.format(dat);
                formatter = new java.text.SimpleDateFormat("HH");
                String sHour = formatter.format(dat);
                formatter = new java.text.SimpleDateFormat("mm");
                String sMin = formatter.format(dat);
                formatter = new java.text.SimpleDateFormat("ss");
                String sSec = formatter.format(dat);            
                int nRand0 = (int)(Math.random()*10000);
                int nRand1 = (int)(Math.random()*10000);
                int nRand2 = (int)(Math.random()*10000);
                String sName = sYear+sMonth+sDate+sHour+sMin+sSec+"_"+nRand0+"_"+nRand1+"_"+nRand2;
                return sName;
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormElement.getTempName "+ex.toString());
            }
            return "";
        }
        public String getTempFile(String sSourceFileName)
        {
            try
            {
                String sExt = WCString.nullCheck(WCString.getFileExt(sSourceFileName),"");
                String sName = getTempName();
                if (!WCString.isEmpty(sExt))
                {
                    sName += "."+sExt;
                }
                String sDir = getTempDirectory();
                WCSystem oSys = WCSystem.getInstance();
                oSys.CreateDir(sDir);            
                String sRet = WCString.buildFilePath(sDir,sName,"/");
                return sRet;
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormElement.getTempFile "+ex.toString());
            }
            return null;
        }
        public String getEnvValue(String sProp)
        {
            WCEnv env = WCEnv.getInstance();
            if (env != null)
            {
                WCProperties rcd = env.getProperties();
                if (rcd != null)
                {
                    String sVal = rcd.getStrValue(sProp);
                    return sVal;
                }
            }
            return "";
        }
        public FileOutputStream m_oFileOutputStream = null;
        public String m_sTempFileName = null;
       
        public String getTempFileName()
        {
            return m_sTempFileName;
        }
        public int getSize() 
        {
            return this.size;
        }
           
        public void setSize(int size) 
        {
            this.size = size;
        }
           
        public byte [] getContents() 
        {
            return this.contents;
        }
           
        public byte getContentByte(int index) 
        {
            return this.contents[index];
        }
        public void setContents(byte[] contents) 
        {
            this.contents = contents;
        }
           
        public void setContentByte(int index, byte content) 
        {
            this.contents[index] = content;
        }
        public String m_sSaveFileName = null;
        public String getSaveFileName()
        {
            return m_sSaveFileName;
        }
        public void setSaveFileName(String sFileName)
        {
            m_sSaveFileName = sFileName;
        }
        public int saveFile(String sPathFile)
        {
            try
            {
                if (sPathFile == null)
                    return -1;
                String sDir = WCString.getPath(sPathFile);
                WCSystem oSys = WCSystem.getInstance();
                oSys.CreateDir(sDir);
                String sSaveFileName = sPathFile;
                setSaveFileName(sSaveFileName);
                File oSrcFile = new File(getTempFileName());
                File oDestinationFile = new File(sSaveFileName);
                FileInputStream oFIS = null;
                FileOutputStream oFOS = null;
                try
                {
                    oFIS = new FileInputStream(oSrcFile);
                    oFOS = new FileOutputStream(oDestinationFile);
                    byte[] oBuffer = new byte[1024 * 4];
                    int nRead = 0;
                    while ((nRead = oFIS.read(oBuffer)) != -1) 
                    {
                        oFOS.write(oBuffer, 0, nRead);
                    }
                    oFIS.close();
                    oFOS.close();
                    oFIS = null;
                    oFOS = null;
                    oSrcFile.delete();
                }
                catch (Exception e) 
                {
                    WCLog.getInstance().printLog("exception at WCMultipartFormElement.saveFile "+e.toString());
                    if (oFIS != null)
                    {
                        oFIS.close();
                    }
                    if (oFOS != null)
                    {
                        oFOS.close();
                    }
                    e.printStackTrace(); 
                }
            }
            catch(IOException ioe)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormElement.saveFile "+ioe.toString());
                ioe.printStackTrace();
            }
            return 0;
        }
        public WCProperties getUserData()
        {
            return m_rUserData;
        }
        public void setUserData(String sProp,String sValue)
        {
            if (m_rUserData == null)
                m_rUserData = new WCProperties();
            m_rUserData.setValue(sProp,sValue);
        }
        public void setUserData(String sProp,int nValue)
        {
            if (m_rUserData == null)
                m_rUserData = new WCProperties();
            m_rUserData.setValue(sProp,nValue);
        }
        public void deleteTempFile()
        {
            try
            {
                File oFile = new File(m_sTempFileName);
                boolean bSucc = oFile.delete(); 
            }
            catch (Exception ex)
            {
                WCLog.getInstance().printLog("exception at WCMultipartFormElement.deleteTempFile "+ex.toString());
            }
        }
        public String getCloneFileName()
        {
            String sFullPathName = this.getFullPathName();
            if (WCString.isEmpty(sFullPathName))
        {
            return null;
        }
        String sExt = WCString.getFileExt(sFullPathName);
            String sTempName = this.getTempName();
            String sTempFileName = sTempName+"."+sExt;
            return sTempFileName;
        }
        public long m_nFileSize = -1;
        public long getFileSize()
        {
            if (m_nFileSize > (long)0)
                return m_nFileSize;
            String sFileName = getSaveFileName();
            try
            {
                File oFile = new File(sFileName);
                if (oFile != null)
                {
                    m_nFileSize = oFile.length();
                    return m_nFileSize;
                }
            }
            catch (Exception ex)
            {
            }
            sFileName = m_sTempFileName;
            try
            {
                File oFile = new File(sFileName);
                if (oFile != null)
                {
                    m_nFileSize = oFile.length();
                    return m_nFileSize;
                }
            }
            catch (Exception ex)
            {
            }
            return 0;
        }
    }
// WCMultipartFormElement.java 소스 끝

첨부파일 : file_upload_progress1.zip

file_upload_progress1.jsp
WCMultipartFormParser.java
WCMultipartFormElement.java

출처 : 고급 웹 UI 개발 라이브러리 Web Development Library 소스공개 : http://www.webdevlib.net
첨부파일 :  
multipart_form_parser2.zip   [7 KB]   다운로드 횟수 28 회
Posted by 1010