ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파일업로드 게시판 만들기(1)
    카테고리 없음 2011. 7. 8. 23:37
    최근에 폰에서 파일전송에 대한 문의가 많이 들어 오고 있어서 이해 대해서 차근차근 설명하도록 하겠다.

    한분 한분 소스를 보내드리기 보단 이 방법이 낳을것 같아서 급하게 코드를 정리하고 강좌를 올린다.

    일단 안드로이드에서 사용할 cd2m 서드 파티션 서버 구축을 위해 jsp 로 웹 서버를 구축 하도록 하겠다.

    기본적으로 입력값은 null이 어도 상관없게 유효성 체크를 최소화 하여 간단하게 작성하도록 하겠다.

    기본적으로 사용한 환경을 보면 조금 복잡하게 구성이 되어있다. 서블릿 하나로 간단하게 만들 수도 있겠지만.

    struts2 를 이용해서 만들었기 때문에 익숙하지 않은 분들께서는 그냥 돌리면 될 정도로 쉽게 설명을 하도록 하겠다.

    사용한 환경은 이렇다 oracle10g, jsp, ibatis, tomcat 6.0, struts2 이다.


    간단한 입력 폼이다.

    <%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8"%>
    <%
     String contextPath = 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>* 프 로 필 등 록 *</title>
    </head>
    <script type="text/javascript">
     function imgPreview(img) {
      var imgObj = document.getElementById('previewImg');
      if (img.value.match(/\.(gif|jpg|jpeg|png)$/i)) {
       imgObj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"
         + img.value + "',sizingMethod=scale)";
      } else {
       img.outerHTML = img.outerHTML;
       imgObj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='',sizingMethod=scale)";
       alert('이미지파일만 올릴수 있습니다.');
      }
     } //-->
    </script>
    <body>
    <form action="profileJoin.action" name="joinForm" method="post"
     enctype="multipart/form-data">
    <table border="1">
     <tr>
      <td colspan="2 ">
      <div id="previewImg" style="width: 300px; height: 300px;"></div>
      </td>
     </tr>
     <tr>
      <td>이미지</td>
      <td><input type="file" name="doc" onchange="imgPreview(this);">
      <input type="hidden" name="prof_img" id="prof_img" /></td>
     </tr>
     <tr>
      <td>아이디</td>
      <td><input type="text" name="prof_id" size="30"/></td>
     </tr>
     <tr>
      <td>패스워드</td>
      <td><input type="text" name="prof_password" size="30" /></td>
     </tr>
     <tr>
      <td><input type="hidden" name="prof_device" size="30" /></td>
     </tr>
     <!-- </tr>-->
     <tr>
      <td>인사말</td>
      <td><input type="text" name="prof_hiword" size="30" /></td>
     </tr>
     <tr>
      <td colspan="2" align="right"><input type="submit" value="등록" /></td>
     </tr>
    </table>
    </form>
    </body>
    </html>
     



    이미지 파일 형식만을 입력받도록 Javascript에서 막았다.
    JSP 파일 기본적인 폼모양으로 간단하게 작성하고 이미지 파일을 전송하기 위한 struts2 설정은
    <action name="profileJoin" class="kr.co.nooto.action.ProfileJoinAction">
       <interceptor-ref name="prepare"></interceptor-ref>
       <interceptor-ref name="modelDriven"></interceptor-ref>
       <interceptor-ref name="fileUpload"></interceptor-ref>
       <interceptor-ref name="params"></interceptor-ref>
       <result name="success" type="redirect">/showPromem.action</result>
       <result name="fail">/profile/AccountFail.jsp</result>
      </action>

    빨갛게 줄그은 부분이 파일 업로드의 핵심이며 ,

    서버상에서 섬네일로 이미지 사이즈를 줄여서 폰에서 읽어 들일때 약간이라도 용량을 적게 하기 위해 처리 하였다.

    파일처리를 하는 서블릿 파일은 이렇다.
    package kr.co.nooto.action;
    
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.awt.image.renderable.ParameterBlock;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.Reader;
    
    import javax.imageio.ImageIO;
    import javax.media.jai.JAI;
    import javax.media.jai.RenderedOp;
    
    import org.apache.commons.io.FileUtils;
    
    import kr.co.nooto.dto.ProfileDTO;
    import com.ibatis.common.resources.Resources;
    import com.ibatis.sqlmap.client.SqlMapClient;
    import com.ibatis.sqlmap.client.SqlMapClientBuilder;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    import com.opensymphony.xwork2.Preparable;
    
    public class ProfileJoinAction extends ActionSupport 
    implements Preparable,	ModelDriven
    {
    	private final String UPLOAD_DIR = "C:\\developerset\\server\\workspace\\FileUpload\\WebContent\\proimg\\";
    	
    	/**
         * fileUpload 인터셉터가 임시 디렉터리에 저장한 파일 객체
         */
    	File doc;
    	/**
         * 컨텐트 타입
         */
    	String docContentType;
    	/**
         * 원본 파일 이름
         */
    	String docFileName;
    	/**
         * 도메인 오브젝트
         */
    	ProfileDTO dto;
    	/**
         * 보관된 파일
         */
    	File savedFile;
    	
    	int duplication;
    	
    	int thumbW = 100; // 너비 120 픽셀인 썸네일을 만들기 위한 설정
    	int thumbH;
    	
    	String result , account;
    	@Override
    	public String execute() throws Exception {
    		System.out.println("액션실행");
    		// fileUpload 인터셉터가 임시 디렉터리에 저장한 파일을 보관할 디렉터리로 복사한다.
    		// 임시 디렉터리의 파일은 액션이 끝난 후에 fileUpload 인터셉터가 삭제한다.
    		System.out.println(doc);
    		try
    		{
    		if (doc != null && doc.exists()) {
    			savedFile = new File(UPLOAD_DIR + docFileName.replaceAll(" ", ""));
    			if(docFileName.equals(savedFile))
    			{
    			}
    			FileUtils.copyFile(doc, savedFile);
    //			File savedFile = new File(UPLOAD_DIR + docFileName);
    //			FileUtils.copyFile(doc, savedFile);
    			
    			//ParameterBlock 클래스의 인스턴스 pb 생성
    			ParameterBlock pb = new ParameterBlock(); //
    			pb.add(UPLOAD_DIR+docFileName.replaceAll(" ", ""));
    			
    			//변환할 이미지를 담고 불러온다.
    			RenderedOp rOp = JAI.create("fileload",pb);
    			
    			//불러온 이미지를 BufferedImage 클래스에 담는다
    			BufferedImage bi = rOp.getAsBufferedImage();
    			
    			int imgW = bi.getWidth();
    			int imgH = bi.getHeight();
    			//비율에 맞는 너비 120, 높이 X의 이미지를 만들기 위해 X값 추출
    			thumbH = (int)(imgH * thumbW / imgW);
    			
    			//thumb란 이미지 버퍼를 생성하고 버퍼의 사이즈를 100 * 100으로 설정한다.
    			BufferedImage thumb = new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB);
    			
    			//thumb의 이미지 버퍼에 원본 이미지를 정해진 사이즈인 100 * 100에 맞춰 그린다
    			Graphics2D g = thumb.createGraphics();
    			g.drawImage(bi, 0, 0, thumbW, thumbH, null);
    			
    			//출력할 위치와 파일 이름을 설정하고 썸네일 이미지를 생성한다
    			File file = new File(UPLOAD_DIR+docFileName.replaceAll(" ", ""));
    			ImageIO.write(thumb,"png",file);
    			
    		}
    		Reader reader = Resources
    		.getResourceAsReader("kr/co/nooto/ibatis/SqlMapConfig.xml");
    		SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
    		
    		duplication = (Integer)sqlMap.queryForObject("idduplication", dto.getProf_phone());
    			if(duplication > 0)
    			{
    				result = "D";
    				return "fail";
    			}
    			else
    			{
    				
    				result = "T";
    			}
    		System.out.println("duplication" + duplication);
    		
    		sqlMap.startTransaction();
    		
    		dto.setProf_img(docFileName.replaceAll(" ", ""));
    		System.out.println("이미지 이름 :" + dto.getProf_img());
    		
    		//이미지이름을 못찾아?
    		sqlMap.insert("Projoin", dto);
    		sqlMap.commitTransaction();
    		reader.close();
    		}
    		catch (FileNotFoundException fe) {
    			System.out.println(fe.getMessage());
    			account = "F";
    			return "fail";
    		}
    		catch (Exception e)
    		{
    			System.out.println("에러" + e.getMessage());
    			account = "F";
    			return "fail";
    		}
    		// TODO : 비즈니스 로직
    		account = "S";
    		return SUCCESS;
    	}
    
    	// setter methods
    
    	public void setDoc(File doc) {
    		this.doc = doc;
    	}
    
    	public void setDocContentType(String docContentType) {
    		this.docContentType = docContentType;
    	}
    
    	public void setDocFileName(String docFileName) {
    		this.docFileName = docFileName;
    	}
    
    	// getter methods
    
    
    	public File getDoc() {
    		return doc;
    	}
    
    	public ProfileDTO getDto()
    	{
    		return dto;
    	}
    
    	public File getSavedFile() {
    		return savedFile;
    	}
    
    	/**
         * Preparable의 메서드
         */
    	public void prepare() throws Exception {
    		dto = new ProfileDTO();
    	}
    
    	/**
         * ModelDriven의 메서드
         */
    	public Object getModel() {
    		return dto;
    	}
    
    	public int getDuplication()
    	{
    		return duplication;
    	}
    
    	public void setDuplication(int duplication)
    	{
    		this.duplication = duplication;
    	}
    
    	public String getResult()
    	{
    		return result;
    	}
    
    	public void setResult(String result)
    	{
    		this.result = result;
    	}
    
    	public String getAccount()
    	{
    		return account;
    	}
    
    	public void setAccount(String account)
    	{
    		this.account = account;
    	}
    
    }
    
    

    이부분의 구현에 대해서는 더 자세한 설명이 필요하다. 일단은 안드로이드 설명을 하기 위해 급하게 작성하는 부분이니 천천히 더 설명 하도록 하겠다.

    댓글

COPYRIGHT 2010 EpoNg. ALL RIGHTS RESERVED.