2014년 7월 22일 화요일

javascript Closure


	(function(){
		var j=0;
		for(var i=0;i<10;i++){
			++j;
			(function(){
				var idx = j;
				$("",{
							text:idx,
							style:"padding:2px;",
							click:function(){
									alert(idx);
								}					
				}).appendTo($("#closureTest"));			
			})();
		}		
	})();




javascript 의 모든 함수는 Closure 이다. 

최소한 내가 이해하고 있는 Closure 란 함수가 호출될 당시에 접근 할 수 있는 코드블럭이다.

위의 코드를 약간 수정해 보면


        (function(){
		var j=0;
		for(var i=0;i<10;i++){
			++j;
			
				var idx = j;
				$("",{
							text:idx,
							style:"padding:2px;",
							click:function(){
									alert(idx);
								}					
				}).appendTo($("#closureTest"));			
			
		}		
	})();


익명 함수를 제거해보았다.

언뜻 보면 의도대로 동작할 거 같지만 

click 이벤트가 발생되서 함수가 호출될 시점과 선언된 시점의 idx 값이 다르게 된다.

즉, 함수가 사용하는 변수는 내부적으로 계속 참조하고 있다는 말이 된다.

이는 전역변수를 생각해보면 이해가 될것이다.

그래서 익명함수를 사용하여 스코프를 분리하고 참조블럭을 변경시켜주는 작업을 통해 해결 할 수 있다.

2014년 6월 10일 화요일

jQuery.proxy


function Obj(){
	
	this.init = function(text){
		this.text = text;	
		
		var span = $("",{
						text:this.text,
						click:$.proxy(this, 'clickHandler')
					});
		
		$("#proxyTest").append(span);
	};
	
	this.clickHandler = function(){
		alert(this.text);
	};
}


$(function(){
	
	var Obj_1 = new Obj();
	Obj_1.init("프록시테스트1");
	
	var Obj_2 = new Obj();
	Obj_2.init("프록시테스트2");
});

id가 proxyTest 인 엘리먼트를 두고 위와 같은 코드를 작성할시 
프록시테스트1프록시테스트2 라고 화면에 나타난다.

위 코드의 목적은 프록시 설명을 위한거인데 프록시는 대리자, 대리인의 뜻을 가지고있다. 
뭐 뜻이 중요한건 아니고 아무튼 $.proxy 의 역할을 설명하자면
this 를 이용해 현재 context 의 'clickHandler' 속성을 확장한다는 뜻이다.

무슨 뜻이냐하면
만약에 
function Obj(){
	
	this.init = function(text){
		this.text = text;	
		
		var span = $("",{
						text:this.text,
						click:this.clickHandler
					});
		
		$("#proxyTest").append(span);
	};
	
	this.clickHandler = function(){
		alert(this.text);
	};
}
위와 같이 작성할때 아무런 문제가 없어보인다. 하지만 실제로 클릭을 해보면
아무런 반응이 없거나 스크립트 오류가 날 것이다. 그 이유는 이벤트 발생시에 
this에 해당하는 객체가 재정의되기 때문이다.
실제로 this를 찍어보면 jQuery234234234 이런 값이 있는 것을 확인 할 수 있다.
그래서 $.proxy 메소드를 이용하여 원래의 this를 이용해서 확장시켜주는 것이다.

요약:span의 click 이벤트핸들러가 실행되는 시점의 컨텍스트 즉, 실행주체가 변경되기 때문에
this 키워드가 가리키는 객체가 달라지는 것이다.

2014년 3월 31일 월요일

Spring 인코딩 문제

POST 방식으로 한글을 날리는 경우 아래 설정으로 인해 깨지지 않지만 GET 방식으로 한글을 날리는 경우 깨지므로 script 에서 따로 인코딩을 해주던가 POST 방식으로 변경한다.
 
  encodingFilter
  
   org.springframework.web.filter.CharacterEncodingFilter
  
  
   encoding
   utf-8
  
     
 
        HTMLTagFilter
        
            egovframework.rte.ptl.mvc.filter.HTMLTagFilter
        
    
    
  encodingFilter
  *.do
 

2014년 3월 26일 수요일

Spring 파일 업로드

설정 파일 부터

     
        
        
    
    
    

가장 많이 사용 되는 CommonsMultipartResolver 를 사용해본다. jsp 파일 내용은 간단함
/*
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>





Insert title here






	
*/
컨트롤러 내용은 더 간단함
package egovframework.test.fileupload;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class FileUploadController {
	
	@RequestMapping(value="/test/fileUploadView.do")    
    public String fileUploadView(ModelMap model, HttpServletRequest request) throws Exception {
   		
    	return "fileupload/upload";
    }
	
	@RequestMapping(value="/test/fileUpload.do")    
    public String fileUpload(@RequestParam("file") MultipartFile file, ModelMap model, HttpSession session) throws Exception {
		    	
		String uploadPath = session.getServletContext().getRealPath("/upload/");
		//실제 디플로이되는 폴더의 root path를 따온다

		System.out.println("UPLOAD_PATH : "+uploadPath);
		
		FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(uploadPath+"/"+file.getOriginalFilename()));
                //upload 폴더안에 등록하겠다는 말
		
    	return "fileupload/upload";
    }

    @RequestMapping(value="/test/ajaxGetFileUrlList.do")
    @ResponseBody
    public List ajaxGetFileUrlList(ModelMap model) throws Exception {
    	
    	
    	return new ArrayList();
    } 
}