참조: http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html

로컬에서 톰캣이 https 를 처리할 수 있게 설정하기

self-signed 인증키 생성
%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA
이 때, 비밀번호는
changeit
으로 하기. 이게 톰캣 디폴트. 변경 시에는 아래 설정에서 변경해줘야 함.
인증키 생성 시 나오는 질문에 적당히 대답하고(국가코드 82(한국)), 마지막 비번은 그냥 엔터. 위의 비번과 동일하게 설정됨.

톰캣의 server.xml에서

<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<!--
<Connector
port="8443" minProcessors="5" maxProcessors="75"
enableLookups="true" disableUploadTimeout="true"
acceptCount="100" debug="0" scheme="https" secure="true";
clientAuth="false" sslProtocol="TLS"/>
-->
주석 제거.

https://localhost:8443
로 테스트.

안될때는 인증키 생성 시 만들어지는 .keystore 파일 위치를 바꿔볼 것(톰캣에서 읽을 수 있는 곳으로).

'프로그래밍 > Server' 카테고리의 다른 글

[Shell Script] Shell Script 문법  (0) 2009.10.14
[Shell Script] PATH추가  (0) 2009.10.14
[unix] vi명령어  (0) 2009.04.16
[Tomcat] 톰캣, JSP 등등 버전 에러 시  (0) 2009.04.07
[Tomcat] Quoting in attributes  (0) 2009.04.07
출처: http://afterdan.kr/40

다른 건 스스로 조사해보지 않아서 잘 모르겠으나,
한비야 씨가 자기과시욕이 많다는 건 알겠다.
책을 둘째치고 최근에 방송한 무릎팍도사에서의 행동거지가 딱이었다...

첨부터 끝까지 나는 뭐해서 뭐해서 뭐해서 뭐했다... 더만.

월드비전이 800억 넘게 돈모아서 정작 구호에는 18억 쓴다는게 사실일까?
사실이면 대박인데...
대국민사기극에 한비야 씨도 동참하는 거잖아...

'프로그래밍 > Library' 카테고리의 다른 글

[eclipse] 이클립스 + Mantis  (0) 2009.10.27
[Utils] Paros 사용법  (0) 2009.09.06
[Subclipse] ignore  (0) 2009.04.02
[firebug] 파이어버그 가이드  (0) 2009.03.20
[MD5] MD5 암호화  (0) 2009.03.13

[Oracle] Toad 단축키

프로그래밍/DB 2009. 8. 22. 20:11 Posted by galad
출처: http://it.kimgisa.net/30

TOAD를 사용하면서 편리하게 이용할 수 있는 단축키를 정리한 것입니다.

 

테이블 정보 상세보기

F4 : Table, View, Proc, Funct, Package DESC(테이블명 위에 커서를 두고 F4)

 

자동완성

Ctrl+. : Table Completion (매칭되는 테이블목록 출력)

Ctrl+T : Columns Dropdown (해당테이블의 컬럼목록 표시)

 

SQL문 실행

F5 : SQL Editor내의 모든 SQL문 실행

Ctrl+Enter : 현재 커서의 SQL문 실행

F9 : SQL문 실행 후 Grid에 출력

 

히스토리(과거 수행SQL문 조회)

F8 : 과거에 실행한SQL HISTORY 목록

Alt+Up : History UP

Alt+Down : History DOWN

 

텍스트 대/소문자 변환

CTRL+L : 텍스트를 소문자로

CTRL+U : 텍스트를 대문자로

 

주석처리

Ctrl+B : 주석처리

Ctrl+Shift+B : 주석해제

 

편집 창 전환(이동)

F6 : SQL Editor와 결과창간의 이동

F2 : SQL Editor창 전체화면 전환

Shift+F2 : Grid Output창 전체화면 전환

 

기타 단축키

F7 : 화면을 모두 CLEAR

Ctrl+Shift+F : 쿼리문을 보기좋게 정렬

Ctrl+F9 : SQL Validate (SQL문을 수행하지 않음)


'프로그래밍 > DB' 카테고리의 다른 글

[Toad] tab 간격 조정하기  (0) 2010.02.02
[ORACLE] 특수문자 입력  (0) 2009.10.21
[oracle10g] 페이징 시 rownum 사용하기  (0) 2009.04.06
[Oracle] [펌] sqlplus 사용법  (0) 2009.03.24
[펌] MSSQL 함수모음  (0) 2009.01.14
출처: http://hyeonseok.com/pmwiki/index.php/Markup/Frame/

인터넷 익스플로러에서 프레임 안에 표준 DTD 문서를 사용할 때 생기는 스크롤바 제거

<!--[if ie]>
<style type="text/css">
html {
overflow: scroll;
overflow-x: auto;
}
</style>
<![endif]-->

[ajax] 소스

프로그래밍/Web 2009. 8. 19. 01:01 Posted by galad
/**
 * BP설명 이미지, BP브랜드 이미지를 삭제한다.(ajax)
 */
function deleteBpFile(fileType) {
    var mbrNo = document.getElementById("mbrNo").value;

    // 이미지 삭제 링크 숨기기
    if(fileType == "BP_DESC") {
        document.getElementById("deleteBpDesc").style.display = "none";
        //document.getElementById("linkBpDesc").style.display = "none";
    }
    else {
        document.getElementById("deleteBpBrand").style.display = "none";
    }

    var parameter = "mbrNo=" + mbrNo + "&fileType=" + fileType;
    //alert(parameter);

    var req = newXMLHttpRequest();
    req.onreadystatechange=getReadyStateXmlHandler(req, fileDeleted);
    req.open("POST", "${pageContext.request.contextPath}/manage/deleteBpFile.omp", true); // 비동기처리여부
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send(parameter);
}

/**
 * ajax 응답(xml)을 받아서 처리
 */
function fileDeleted(xml) {
    var bodyTag = xml.getElementsByTagName("body")[0];
    var typeTag = bodyTag.getElementsByTagName("type")[0];
    //alert(typeTag);
    var type = typeTag.firstChild.nodeValue;
    //alert(type);
    var resultTag = bodyTag.getElementsByTagName("result")[0];
    var result = resultTag.firstChild.nodeValue;

    if(result == "Y") {
        // 파일 링크 지우기
        if(type == "BP_DESC") {
            document.getElementById("linkBpDesc").style.display = "none";
        }
        else {
            document.getElementById("linkBpBrand").style.display = "none";
        }
    }
    else {
        // 파일 삭제 링크 다시 보여주기
        if(type == "BP_DESC") {
            document.getElementById("deleteBpDesc").style.display = "";
        }
        else {
            document.getElementById("deleteBpBrand").style.display = "";
        }
    }
}


// ajax call
<span id="linkBpDesc"><strong><s:a href="%{url}"><s:property value="%{umBpInfo.bpDescImgName}"/></s:a></strong></span>
<span id="deleteBpDesc"><a href="#" onclick="deleteBpFile('BP_DESC'); return false;">이미지 삭제</a></span>

Action & Service
// Action
// BP회원 관련 파일 - BP설명이미지, BP브랜드이미지 파일 삭제
    public String deleteBpFile() {
        log.debug("<< ManageAction.deleteBpFile... >>");
       
        HttpServletRequest request = this.getRequest();
       
        String mbrNo = request.getParameter("mbrNo");
        String fileType = request.getParameter("fileType");
       
        log.debug("mbrNo = " + mbrNo);
        log.debug("fileType = " + fileType);
       
        String xml = this.manageService.deleteBpFile(mbrNo, fileType);
        setInputStream(new ByteArrayInputStream(xml.getBytes()));
       
        return SUCCESS;
    }

// 설정파일
<!-- 파일 삭제 -->
        <action name="deleteBpFile" class="com.omp.bp.cms.manage.action.ManageAction" method="deleteBpFile">
            <result type="stream">
                <param name="inputName">inputStream</param>
                <param name="contentType">text/xml</param>
                <param name="bufferSize">4096</param>
            </result>
        </action>

// Service
// BP추가 파일 삭제 후, 결과를 XML형식으로 반환
    @SuppressWarnings("unchecked")
    public String deleteBpFile(String mbrNo, String fileType) throws ServiceException {
        log.debug("<ManageServiceImpl> deleteBpFile...");
       
        StringBuffer xml = null;
        UserMemberBpInfo umbi = null;
       
        try {
            // DB에서 파일 경로를 얻음
            umbi = this.manageDAO.getMemberBpinfo(mbrNo);
            if(umbi == null) {
                throw new ServiceException("BP추가 파일 삭제 중 BP회원 정보 읽기 실패", "getMemberBpinfo FAIL");
            }
           
            // 파일경로 변경 - 앞에 /data 붙이기
            umbi = DataUtil.makeFilePathFromDB(umbi);
           
            // fileType에 따라 파일 삭제
            if(StringUtils.equalsIgnoreCase(fileType, "BP_DESC")) {
                File f = new File(umbi.getBpDescImgPath());
                if(f.exists() && f.isFile()) {
                    if(!f.delete()) {
                        throw new ServiceException("BP추가 파일 삭제 중 설명 파일 삭제 실패", "delete FAIL");
                    }
                    else {
                        log.debug("BP 설명 물리 파일 삭제");
                       
                        // DB 갱신 - 파일 경로 삭제
                        Map map = new HashMap();
                        map.put("mbrNo", mbrNo);
                        map.put("fileType", fileType);
                        if(!this.manageDAO.deleteBpFile(map)) {
                            throw new ServiceException("BP추가 파일 삭제 중 DB 갱신 실패", "update db FAIL");
                        }
                       
                        log.debug("BP 설명 파일 경로 삭제");
                    }
                }
            }
            else if(StringUtils.equalsIgnoreCase(fileType, "BP_BRAND")) {
                File f = new File(umbi.getBpTbnailImgPath());
                if(f.exists() && f.isFile()) {
                    if(!f.delete()) {
                        throw new ServiceException("BP추가 파일 삭제 중 브랜드 파일 삭제 실패", "delete FAIL");
                    }
                    else {
                        log.debug("BP 브랜드 물리 파일 삭제");
                       
                        // DB 갱신 - 파일 경로 삭제
                        Map map = new HashMap();
                        map.put("mbrNo", mbrNo);
                        map.put("fileType", fileType);
                        if(!this.manageDAO.deleteBpFile(map)) {
                            throw new ServiceException("BP추가 파일 삭제 중 DB 갱신 실패", "update db FAIL");
                        }
                       
                        log.debug("BP 브랜드 파일 경로 삭제");
                       
                    }
                }
            }
           
            // 삭제 결과를 XML로 작성
            xml = makeXmlForDeleteBpFileResult(fileType, true);
        }
        catch(Exception e) {
            log.debug("BP추가 파일 삭제 실패", e);
            xml = makeXmlForDeleteBpFileResult(fileType, false);
        }
       
        return xml.toString();
    }
   
    private StringBuffer makeXmlForDeleteBpFileResult(String fileType, boolean isSucceeded) {
        StringBuffer xml = new StringBuffer();
       
        xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        xml.append("<body>");
            xml.append("<type>");
            xml.append(fileType);
            xml.append("</type>");
            xml.append("<result>");
            xml.append(isSucceeded ? "Y" : "N");
            xml.append("</result>");
        xml.append("</body>");
       
        log.debug("DELETE BP FILE - XML");
        log.debug(xml.toString());
       
        return xml;
    }

의외로 간단하기도 하지만 스크립트쪽 처리가 복잡할 듯.
gmail, google docs 같은 건 정말 어떻게 만든 건지 신기할 뿐..
여태까지는 무조건 value="" 에 값을 넣어서 설정해왔는데
알고 보니 name="XXX" 변수명이 Action에서 사용되고 있으면 자동설정된다.

<s:select name="parentCategoryId" list="parentCategoryList" listKey="key" listValue="value" headerKey="" headerValue="선택" onchange="setCategoryListComboByParentCategory();"></s:select>

이 jsp를 결과로 하는 액션클래스에서 parentCategoryId를 멤버변수로 get/set 함수를 갖고 있으면, 액션클래스에서 parentCategoryId에 설정한 값이 위의 태그의 기본값으로 설정된다.

<s:select name="contentInfo.categoryId" list="categoryList" listKey="value" listValue="label" headerKey="" headerValue="선택" onchange="setExtMetaByCategoryId();"></s:select>

마찬가지. 단 contentInfo 클래스의 categoryId 멤버변수값


!!! IE 6.0밖에 안되는 듯?!!!!
아마도 FF문제와 같이 locally loaded image에 대해서는 IE6.0밖에 안되는 듯

내가 사용하는 버젼

문제: callback 함수에는 인자 넘기기가 불가능한가?
전역변수로 해결하였으나 다른 방법은 없는가??

참고: http://www.coderanch.com/t/121417/HTML-JavaScript/Passing-Parameter-Into-Callback-Function

jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>

<script type="text/javascript" src="image_util.js"></script>

<script type="text/javascript">
function fileCheck(formObj) {
    if(formObj.fileName.value == "") {
        alert("이미지를 선택해주세요.");
        return false;
    }
    if(formObj.checkUploadImgOkYn.value != "Y") {
        alert("업로드 할 수 없는 이미지 파일입니다.");
        return false;
    }

    return true;
}
</script>
</head>
<body>
<form name="F" onsubmit="return fileCheck(this);">
<input type="file" name="fileName" onChange="checkUploadImg(this.value, 'checkUploadImgOkYn', 'jpg' ,1600, 1200, 500)" >
<input type="hidden" name="checkUploadImgOkYn" id="checkUploadImgOkYn" value="N">
<br>
<input type="submit">
</form>
</body>
</html>

js
// 이미지 파일 관련 javascript

/**
 * 파일 확장자를 반환
 * @param filePath 파일 path
 * @return 확장자
 */
function getFileExtension(filePath)
{
    var lastIndex = -1;
    lastIndex = filePath.lastIndexOf('.');
    var extension = "";

    if ( lastIndex != -1 )
    {
        //extension = filePath.substring( lastIndex+1, filePath.len );
        extension = filePath.substring( lastIndex+1);
    } else {
        extension = "";
    }
   
    return extension;
}


// 이미지.onload시의 callback 함수에 파라미터를 넘기기 위한 전역변수
var g_objId = "";            // 이미지 체크 후, 그 결과를 설정할 input태그의 id. ex) <input type="hidden" name="checkUploadImgOkYn" id="checkUploadImgOkYn" value="N">
var g_widthLimit = 0;    // 이미지 최대 가로길이
var g_heightLimit = 0;    // 이미지 최대 세로길이
var g_fileSizeLimit = 0;    // 이미지 최대 파일크기

/**
 * 이미지 업로드 태그에서 부를 함수. ex) &lt;input type="file" name="fileName" onChange="checkUploadImg(this.value, 'checkUploadImgOkYn', 'jpg' ,1600, 1200, 500)" >
 * @param imgSrc 이미지 파일
 * @param objId 이미지 체크 후 결과를 설정할 input태그의 id
 * @param fileExt_limit 이미지 파일 확장자 제한
 * @param width_limit 이미지 최대 가로길이
 * @param height_limit 이미지 최대 세로길이
 * @param fileSize_limit 이미지 최대 파일크기
 * @return 없음. 체크에 성공하면 objId에 Y를 설정. 실패하면 N을 설정함.
 */
function checkUploadImg(imgSrc, objId, fileExt_limit, width_limit, height_limit, fileSize_limit)
{
    var widthLimit = 0;
    var heightLimit = 0;
    var fileSizeLimit = 0;
    var fileExtLimit = "";
   
    if(typeof width_limit != "undefined") { // 제약조건이 있으면
        widthLimit = width_limit;
    }
    if(typeof height_limit != "undefined") { // 제약조건이 있으면
        heightLimit = height_limit;
    }
    if(typeof fileSize_limit != "undefined") { // 제약조건이 있으면
        fileSizeLimit = fileSize_limit;
    }
    if(typeof fileExt_limit != "undefined") { // 제약조건이 있으면
        fileExtLimit = fileExt_limit;
    }
    else { // 이미지 파일만 업로드해야 하므로 조건이 없으면 기본설정
        fileExtLimit = "jpg,gif,png";
    }

    // global 변수에 저장. callback함수에 인자 넘기기 불가하기 때문
    g_objId = objId;
    g_widthLimit = widthLimit;
    g_heightLimit = heightLimit;
    g_fileSizeLimit = fileSizeLimit;
   
    // IE 체크
    if(navigator.userAgent.toLowerCase().indexOf("msie") == -1) { // IE가 아니면
        var msg = "파일 확장자 : " + fileExtLimit;
        msg = (widthLimit != 0) ? msg + " , 이미지 가로 길이 : " + widthLimit : msg;
        msg = (heightLimit != 0) ? msg + " , 이미지 가로 길이 : " + heightLimit : msg;
        msg = (fileSizeLimit != 0) ? msg + " , 이미지 가로 길이 : " + fileSizeLimit : msg;
       
        alert("인터넷 익스플로러가 아닌 경우에는 업로드할 그림을 확인할 수 없습니다.\n다음의 조건에 맞는 파일을 업로드해 주세요.\n" + msg);
        document.getElementById(g_objId).value = "Y";
        return;
    }
   
    if(typeof imgSrc == "undefined" || imgSrc == "") {
        alert("선택된 파일이 없습니다.");
    }

    var ext = getFileExtension(imgSrc);
    //alert(ext);

    if (ext == "") {
        alert('올바른 파일을 입력하세요');
        return;
    }
    else if(fileExtLimit != "" && ext.toLowerCase().indexOf(fileExtLimit.toLowerCase()) == -1) { // 제약조건이 없으면 체크 안 함
        alert(fileExtLimit + " 형식의 파일만 가능합니다.");
        return;
    }
   
    LoadImg(imgSrc);
}

/**
 * 이미지를 로드
 * @param imgSrc 이미지 파일 path
 * @return
 */
function LoadImg(imgSrc)
{
    var imgInfo = new Image();
    imgInfo.onload = img_Loaded;
    imgInfo.onerror = function() {
        // always called
        alert("이미지 파일의 로드에 실패했습니다.");
        document.getElementById(g_objId).value = "N";
    };
    imgInfo.src = imgSrc;
}

/**
 * image.onload의 callback 함수. image가 load 되면 불려진다.
 * @return
 */
function img_Loaded()
{
    /*var imgSrc, imgWidth, imgHeight, imgFileSize;
    imgSrc = this.src;
    imgWidth = this.width;
    imgHeight = this.height;
    imgFileSize = this.fileSize;

    alert(imgWidth);*/

    var objId = g_objId;
    var widthLimit = g_widthLimit;
    var heightLimit = g_heightLimit;
    var fileSizeLimit = g_fileSizeLimit;
    //alert(widthLimit);
    //alert(heightLimit);
   
    if (this.src == "" || this.width <= 0 || this.height <= 0)
    {
        alert("이미지 파일의 로드에 실패했습니다.");
        document.getElementById(objId).value = "N";
        return;
    }

    // 제약조건 확인
    if(widthLimit != 0 && this.width > widthLimit) {
        alert("선택한 이미지의 가로 길이가 허용치인 " + widthLimit + " 를 초과했습니다.\n선택한 이미지의 가로 길이는 " + this.width + " 입니다.");
          document.getElementById(objId).value = "N";
        return;
    }
    if(heightLimit != 0 && this.height > heightLimit) {
        alert("선택한 이미지의 세로 길이가 허용치인 " + heightLimit + " 를 초과했습니다.\n선택한 이미지의 세로 길이는 " + this.height + " 입니다.");
          document.getElementById(objId).value = "N";
        return;
    }
    if(fileSizeLimit != 0 && this.fileSize > fileSizeLimit*1024) {
        alert("선택한 이미지 크기가 허용치인 " + fileSizeLimit + "KB 를 초과했습니다.\n선택한 이미지의 크기는 약 " + Math.ceil(this.fileSize/1024) + "KB 입니다.");
          document.getElementById(objId).value = "N";
        return;
    }

    // 제약조건 이내라면
    document.getElementById(objId).value = "Y";

    //이미지 사이즈 저장
    //document.F.imgWidth.value = imgWidth;
    //document.F.imgHeight.value = imgHeight;

    //alert("this.width = " + this.width);
    //alert("this.height = " + this.height);

    //alert(document.getElementById(objId).value);
}


!!! IE 6.0밖에 안되는 듯?!!!!
아마도 아래의 FF문제와 같이 locally loaded image에 대해서는 IE6.0밖에 안되는 듯

일단 firefox에서는 image.onload가 업로드 하려는 파일, 즉 locally loaded image에 대해서는 작동하지 않는다
(참고: http://www.tek-tips.com/viewthread.cfm?qid=1452885&page=5)

대신에 image.src="http://www.tek-tips.com/images/logo.gif" 와 같이 어딘가의 서버상에 올려져 있는 파일에 대해서는 작동한다.

 function LoadImg(value)
{
    var imgInfo = new Image();
    imgInfo.onload = img_Load;
    imgInfo.onerror = function() {
        // always called
        alert('error');
    };
// imgInfo.src = "http://www.tek-tips.com/images/logo.gif"; // 이렇게 하면 firefox에서도 동작함
    imgInfo.src = value;
}

function img_Load()
{
    var imgSrc, imgWidth, imgHeight, imgFileSize;
    var maxFileSize;
    maxFileSize = 5000000;
    imgSrc = this.src;
    imgWidth = this.width;
    imgHeight = this.height;
    imgFileSize = this.fileSize;

    if (imgSrc == "" || imgWidth <= 0 || imgHeight <= 0)
    {
        alert('그림파일을 가져올 수 없습니다.');
        return;
    }

    if (imgFileSize > maxFileSize)
    {
        alert('선택하신 그림 파일은 허용 최대크기인 ' + maxFileSize/1024 + ' KB 를 초과하였습니다.');
        return;
    }

    //이미지 사이즈 저장
    document.F.imgWidth.value = imgWidth;
    document.F.imgHeight.value = imgHeight;

    alert(imgWidth);
    alert(imgHeight);
}

주의할 건 image.onload 이후에 image.src 가 와야한다는 것.
image.src 에서 실제 이미지를 로드하고 나서, onload가 동작하는 원리인 듯.
src가 먼저오면 onload가 되기도 하고 아니기도 하는 듯.

기타 참고 링크
http://dogfeet.tistory.com/20
http://www.juniac.net/183
http://blog.byuli.com/entry/운영체제와-브라우저-체크

[Strust2] <s:radio> 사용법

프로그래밍/Framework 2009. 7. 29. 14:19 Posted by galad
radio에 디폴트로 선택되게 하고 싶을 때

<s:radio name="productInfo.updateTypeCd" list="#{'A':'오름차순', 'D':'내림차순(최근 등록한 콘텐츠가 위로 정렬)'}" value="%{'D'}"></s:radio>

위와 같이 리스트를 강제로 설정하고, 기본값도 문자열로 주고 싶으면 %{'D'} 를 지킬 것. %{}를 사용하지 않으면 Struts2에서 태그를 변환하지 않는 듯.



<s:radio name="productInfo.updateTypeCd" list="#{'A':'오름차순', 'D':'내림차순(최근 등록한 콘텐츠가 위로 정렬)'}" value="D"></s:radio>

이게 될 것 같지만 되지 않는다..
public String getMcodeFromMLB() {
        HttpURLConnection uc = null; // 연결용 커넥션
        URL url = null;
        String sUrl = "http://localhost:8080/MLBServerTest/MLBTest.jsp"; // 연결할 주소
        String result = "";
       
        try {
           
            url = new URL(sUrl);
           
            uc = (HttpURLConnection) url.openConnection();
           
            uc.setDoInput(true);
            uc.setDoOutput(true);
            uc.setUseCaches(false);
            uc.setRequestMethod("POST");
            uc.setConnectTimeout(10000);  // 커넥션 타임아웃
            uc.setAllowUserInteraction(true);
           
            // Http Header Setting
            uc.setRequestProperty("Content-type", "application/x-www-form-urlencoded;charset=euc-kr");
           
            // Http Parameter Sending
            String partner_id = "O00128";    // CP의 파트너ID
            String service_code = "001";    // 각 CP서버에 할당된 코드
            String music_code = "00293876";    // MLB에서 조회된 MUSIC_CODE
            String content_price = "800";     // 컨텐츠 단가
            String content_name = "핑계";     // 컨텐츠가 서비스되는 이름
            String content_num = "1";     // 패키지에 포함한 컨텐츠의 갯수. 단일상품일 경우 1, 복합상품일 경우 2이상
            String pid = "3102306023";     // PID
            String sub_code = "12700000012";     // CP서버가 자체적으로 관리하는 Code(SCID등). 12자리 이하
            String carrier_code = "00";     // ASP에 서비스하는 캐리어를 구분하기 위한 구분코드
           
            StringBuffer sb = new StringBuffer();
            sb.append(MLBConstants.MCODE_REQUEST_PARTNER_ID).append("=").append(partner_id).append("&");
            sb.append(MLBConstants.MCODE_REQUEST_SERVICE_CODE).append("=").append(service_code).append("&");
            sb.append(MLBConstants.MCODE_REQUEST_MUSIC_CODE).append("=").append(music_code).append("&");
            sb.append(MLBConstants.MCODE_REQUEST_CONTENT_PRICE).append("=").append(content_price).append("&");
            sb.append(MLBConstants.MCODE_REQUEST_CONTENT_NAME).append("=").append(content_name).append("&");
            sb.append(MLBConstants.MCODE_REQUEST_CONTENT_NUM).append("=").append(content_num).append("&");
            sb.append(MLBConstants.MCODE_REQUEST_PID).append("=").append(pid).append("&");
            sb.append(MLBConstants.MCODE_REQUEST_SUB_CODE).append("=").append(sub_code).append("&");
            sb.append(MLBConstants.MCODE_REQUEST_CARRIER_CODE).append("=").append(carrier_code);
           
            PrintWriter pw = new PrintWriter(new OutputStreamWriter(uc.getOutputStream(), "euc-kr"));
            pw.write(sb.toString());
            pw.flush();
           
           
            int resCode = 0; // RMS 와의 연결 응답값
            resCode = uc.getResponseCode();
           
            StringBuffer resp = new StringBuffer();
            if(resCode < 400){  // 연결이 성공적일때
               
                String line;
                BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream(), "euc-kr"));
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                    resp.append(line);
                }
               
                pw.close();
                br.close();
               
                // html 파싱
                result = getResultCode(resp.toString());
                result = (result.equals("OK")) ? result : "MLB연동 중 에러 발생 : " + getResultCode(resp.toString());
            }
            else{
                result = "MLB연동 중 에러 발생 : " + resCode + " 에러입니다.";
            }
           
        } catch (IOException e) {
            e.printStackTrace();
        }
        catch(Exception e) {
            e.printStackTrace();
        }
       
        return result;
    }

넘기고 받을 때 euc-kr로 변환하는 것도 주목.

'프로그래밍 > Java' 카테고리의 다른 글

[java] thorws .....  (0) 2009.12.11
[java] 소스 분석  (0) 2009.09.06
[HttpURLConnection] HttpURLConnection 에서 GET / POST 방식 사용상의 주의  (0) 2009.02.19
CLASSPATH  (0) 2009.01.06
HttpURLConnection 사용례  (0) 2009.01.06
참고: http://x1210.tistory.com/385
http://htmlcleaner.sourceforge.net/index.php

public String getResultCode(String resp) throws IOException {
        // create an instance of HtmlCleaner
        HtmlCleaner cleaner = new HtmlCleaner();

        // take default cleaner properties
        CleanerProperties props = cleaner.getProperties();
         
//        // customize cleaner's behaviour with property setters
//        props.setXXX(...);
       
        // Clean HTML taken from simple string, file, URL, input stream,
        // input source or reader. Result is root node of created
        // tree-like structure. Single cleaner instance may be safely used
        // multiple times.
        TagNode node = cleaner.clean(resp);

        // optionally find parts of the DOM or modify some nodes
//        TagNode[] myNodes = node.getElementsByName(MLBConstants.MCODE_RESULT_NAME, true);
        TagNode[] myNodes = node.getElementsByName("input", true);
//        // and/or
//        Object[] myNodes = node.evaluateXPath(xPathExpression);
//        // and/or
//        aNode.removeFromTree();
//        // and/or
//        aNode.addAttribute(attName, attValue);
//        // and/or
//        aNode.removeAttribute(attName, attValue);
//        // and/or
//        cleaner.setInnerHtml(aNode, htmlContent);
         
//        // serialize a node to a file, output stream, DOM, JDom...
//        new XXXSerializer(props).writeXmlXXX(aNode, ...);
//        myJDom = new JDomSerializer(props, true).createJDom(aNode);
//        myDom = new DomSerializer(props, true).createDOM(aNode);
       
        String resultCode = "";
       
        for(int i = 0; i < myNodes.length; i++) {
           
            System.out.println("name = " + myNodes[i].getAttributeByName("name"));
           
            if(myNodes[i].getAttributeByName("name").equals("result")) {
                resultCode = myNodes[i].getAttributeByName(MLBConstants.MCODE_RESULT_ATTRIBUTE);
                System.out.println(">>> value of result = " + resultCode);
            }
        }
       
        return MLBConstants.getMcodeRequestResultMessage(resultCode);
    }


html
                            <td nowrap style="width:225px;margin-bottom:1px;">
                                <s:select name="approvalStage" list="stageCodeList" listKey="key" listValue="value" headerKey="" headerValue="--선택(현재 상태)--" onchange="selectStageCode(this);"></s:select>
                            </td>
                            <td nowrap style="width:85px;margin-bottom:1px;" id="dpStageTd">
                                <div id="dpStage" style="display: none;"><img src="../images/button/btn_next.gif" align="middle"> 상용상태</div>
                            </td>
                            <td nowrap style="width:225px;margin-bottom:1px;">
                                <div id="dpStageSelect" style="display: none;"><s:select name="dpStageSelect" list="dpStageCodeList" listKey="key" listValue="value" headerKey="" headerValue="전체"></s:select></div>
                            </td>
                            <td align="right" nowrap style="margin-bottom:1px;">
                                <img id="searchButton" src="../images/button/btn_search.gif" align="middle" onClick="javascript:searchContent();" style="cursor:hand;">
                            </td>


script
    function selectStageCode(obj) {
        var STAGE_CODE_RELEASED = "<%=WorkflowCodeDef.STAGE_CODE_RELEASED%>";
       
        //alert(obj.value);
        if(obj.value == STAGE_CODE_RELEASED) { // 상용이면
            document.getElementById("dpStageTd").setAttribute("className", "subject");
            document.getElementById("dpStage").style.display="";
            document.getElementById("dpStageSelect").style.display="";
        }
        else {
            document.getElementById("dpStageTd").setAttribute("className", "");
            document.getElementById("dpStage").style.display="none";
            document.getElementById("dpStageSelect").style.display="none";
        }
    }



[jQuery] jQuery 예제 01

프로그래밍/Web 2009. 7. 17. 16:49 Posted by galad
출처: http://www.jiny.kr/jiny/417
위의 출처의 예제를 직접 해보면서 작성한 소스를 붙여넣고, 몇몇 사항들은 삭제/추가하였음...
문제있으면 알려주시길...

http://hanjiq.egloos.com/2108204
http://orangenius.tistory.com/5
http://jqueryui.com/home


size( ) 
Returns: Number
size( ), 실행후 숫자를 반환

The number of elements in the jQuery object.
매치되어진 원소들의 갯수를 반환한다.
<!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=EUC-KR">
<title>01</title>

<style>
body { cursor:pointer; }
div { width:50px; height:30px; margin:5px; float:left; background:blue; }
span { color:red; }
</style>
 
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $(document.body).click(function() {
        $(document.body).append($("<div>"));
        var n = $("div").size();
        //var n = $("div").length; // size()와 같다
        $("span").text("There are " + n + " divs. Click to add more.");
    }).click(); // 한 번 강제로 클릭 - 아래의 body에는 div가 3개인데 실행되면서 4개로 화면에 표시된다.
});
</script>

</head>
<body>

<span></span>
<div></div>
<div></div>
<div></div>

</body>
</html>
/JQueryTest01/WebContent/Example01/01.html

get( ) 
Returns: Array<Element>
get( ), 실행후 원소 배열 반환

Access all matched DOM elements.
매치되는 모든 문서 원소들을 배열로 반환한다
<!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=EUC-KR">
<title>02</title>

<style>
span { color:red; }
</style>
 
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    disp($("div").get().reverse()); // get으로 array를 얻어서, reverse로 순서뒤집기
});

function disp(divs) {
    var a = [];
    for(var i = 0; i < divs.length; i++) {
        a.push(divs[i].innerHTML);
    }

    $("span").text(a.join(" "));
}
</script>

</head>
<body>

Reversed - <span></span>
<div>One</div>
<div>Two</div>
<div>2.5</div>
<div>Three</div>

</body>
</html>
/JQueryTest01/WebContent/Example01/02.html

get( index ) 
Returns: Element
get( 인덱스 ), 실행후 매치 되는 원소를 반환

Access a single matched DOM element at a specified index in the matched set.
매치되는 원소들 중 주어진 인덱스에 해당하는 하나의 원소만 반환한다.

<!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=EUC-KR">
<title>02</title>

<style>
span { color:red; }
div { background:yellow; }
</style>
 
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $("*", document.body).click(function (e) {
        e.stopPropagation(); // 이벤트 정지
        var domEl = $(this).get(0); // 클릭한 객체를 받음
        $("span:first").text("Clicked on - " + domEl.tagName); // 태그명 표시
    });
});
</script>

</head>
<body>

<span> </span>
<p>In this paragraph is an <span>important</span> section</p>
<div><input type="text" /></div>

</body>
</html>

event.stopPropagation

https://developer.mozilla.org/en/DOM:event.stopPropagation
jQuery함수가 아니라 DOM 객체 함수임.

Prevents further propagation of the current event.
현재 이벤트가 더 진행하는 것을 방지
<html>
<head>
<title>Event Propagation</title>

<style type="text/css">
 #t-daddy { border: 1px solid red }
 #c1 { background-color: pink; }
</style>

<script type="text/javascript">

function stopEvent(ev) {
  c2 = document.getElementById("c2");
  c2.innerHTML = "hello";

  // this ought to keep t-daddy from getting the click.
  ev.stopPropagation();
  alert("event propagation halted.");
}

function load() {
  elem = document.getElementById("tbl1");
  elem.addEventListener("click", stopEvent, false);
}
</script>
</head>

<body onload="load();">

<table id="t-daddy" onclick="alert('hi');">
 <tr id="tbl1">
  <td id="c1">one</td>
 </tr>
 <tr>
  <td id="c2">two</td>
 </tr>
</table>

</body>
</html>
/JQueryTest01/WebContent/Example01/03.html

출처: http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery

Using the tablesorter plugin
http://tablesorter.com/docs/
$("#myTable").tablesorter();
---------------------------------------------
<table id="myTable">
<thead>
<tr>
    <th>Last Name</th>
    <th>First Name</th>
    <th>Email</th>
    <th>Due</th>
    <th>Web Site</th>
</tr>
</thead>
<tbody>
<tr>
    <td>Smith</td>
    <td>John</td>
    <td>jsmith@gmail.com</td>
    <td>$50.00</td>
    <td>http://www.jsmith.com</td>
</tr>
<tr>
    <td>Bach</td>
    <td>Frank</td>
    <td>fbach@yahoo.com</td>
    <td>$50.00</td>
    <td>http://www.frank.com</td>
</tr>
<tr>
    <td>Doe</td>
    <td>Jason</td>
    <td>jdoe@hotmail.com</td>
    <td>$100.00</td>
    <td>http://www.jdoe.com</td>
</tr>
<tr>
    <td>Conway</td>
    <td>Tim</td>
    <td>tconway@earthlink.net</td>
    <td>$50.00</td>
    <td>http://www.timconway.com</td>
</tr>
</tbody>
</table>
<thread> 태그 안에 있는 것을 클릭하면 테이블을 정렬한다. 신기하네...
숫자, 문자 등을 알아서 판별한다고 하는군. 상세한 것은 위의 링크를 참조.

$("#myTable").tablesorter( {sortList: [[0,0], [1,0]]} );
This tells tablesorter to sort on the first and second column in ascending order.
정렬 초기값 설정.

Sort multiple columns simultaneously by holding down the shift key and clicking a second, third or even fourth column header!
하나 선택해서 그걸 기준으로 정렬하고 쉬프트 클릭하고 다른 것 선택하면 계단식으로 정렬됨(기존 정렬을 기준으로 다시 정렬).

속도만 받쳐주면 테이블 정렬은 이걸로 해도 될듯?!
출처: http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery

Using Effects
$(document).ready(function(){
   $("a").toggle(function(){
     $(".stuff").hide('slow');
   },function(){
     $(".stuff").show('fast');
   });
 });
소스 버전이 옛날 것인가... 제대로 동작하질 않는군..

http://docs.jquery.com/Effects/toggle
위의 링크된 문서를 참고할 것

$(document).ready(function() {
    $("#btn1").click(function() {
        $("p").toggle();
        $("#hbtn").toggle();
    });
});

-----------------------------------------

<button id="btn1">Toggle</button>
<p class="tg">Hello</p>
<p class="tg" style="display: none;">Toggle!</p>
<p>AAA</p>
<p style="display: none;">BBB</p>
<button id="hbtn" style="display: none;">hidden button</button>
해보면 toggle()한 display:none이 아닌 것은 안보이게 되고, display:none이었던 것은 보이게된다.

var flip = 0;
$("button").click(function () {
    $("p").toggle( flip++ % 2 == 0 );
});
toggle(XXX)안에 식을 넣는 것도 가능. true면 보이고, false면 숨긴다.

$("button").click(function () {
    $("p").toggle("slow");
});
toggle("slow"). 천천히 사라지고 천천히 나타남.
slow, fast, normal 이 있고, 직접 밀리세컨드로 속도를 지정할 수 있다.

$("button").click(function () {
    $("p").toggle("slow", doCallback);
});

function doCallback() {
    // do something
    this; // DOM element
}
이런 식으로 토글 이펙트가 끝났을 때 실행될 callback 함수도 지정 가능.
여러 개가 토글 되는 경우 각각 실행됨.
사라지는 토글이라고 해서 사라지는 DOM의 callback만 실행되는 것이 아니라, 나타나는 DOM의 callback도 실행된다.
즉 어찌됐든 토글되는 모든 DOM의 callback이 실행됨.

기타 Effects는 아래 링크를 참조.
http://docs.jquery.com/Effects

Animate
// Using multiple unit types within one animation.
$("#go").click(function(){
    $("#block").animate({
        width: "70%",
        opacity: 0.4,
        marginLeft: "0.6in",
        fontSize: "3em",
        borderWidth: "10px"
    }, 1500 );
});
---------------------------------------------------
<button id="go">» Run</button>
<div id="block">Hello!</div>
#block이 초기 모양에서 animate({XXX}, YYY)에 설정된 모양(XXX)으로 변형된다. 이 때, YYY는 변형 시간(클 수록 천천히).

$("#go1").click(function(){
    $("#block1").animate( { width:"90%" }, { queue:false, duration:3000 } )
         .animate( { fontSize:"24px" }, 1500 )
         .animate( { borderRightWidth:"15px" }, 1500
    );
});

$("#go2").click(function(){
    $("#block2").animate( { width:"90%"}, 1000 )
         .animate( { fontSize:"24px" } , 1000 )
         .animate( { borderLeftWidth:"15px" }, 1000
    );
});

$("#go3").click(function(){
    $("#go1").add("#go2").click();
});

$("#go4").click(function(){
    $("div").css({width:"", fontSize:"", borderWidth:""});
});
---------------------------------------------------
<button id="go1">» Animate Block1</button>
<button id="go2">» Animate Block2</button>
<button id="go3">» Animate Both</button>
<button id="go4">» Reset</button>
<div id="block1">Block1</div>
<div id="block2">Block2</div>
$("#ID").animate({AAA},AAA).animate({BBB},BBB).animate({CCC},CCC); AAA, BBB, CCC의 순서대로 애니메이트됨.
queue:false 옵션이 있으면 순서 상관없이 동시에 애니메이트됨.

$("#go1").add("#go2").click(); go1과 go2를 동시에 클릭 이벤트 발생시킴.


animate()
Arguments:
paramsOptions
A set of style attributes that you wish to animate, and to what end.
duration (Optional)String, Number
A string representing one of the three predefined speeds ("slow", "normal", or "fast") or the number of milliseconds to run the animation (e.g. 1000).
easing (Optional)String
The name of the easing effect that you want to use (plugin required). There are two built-in values, "linear" and "swing".
callback (Optional)Function
A function to be executed whenever the animation completes, executes once for each element animated against.

$("p").animate({
      "height": "toggle", "opacity": "toggle"
}, { duration: "slow" });
Animates all paragraphs to toggle both height and opacity, completing the animation within 600 milliseconds.
라는데, height랑 opacity를 토글하는게 무슨 효과인지 모르겠다.

나머진 위의 링크 참조...


'프로그래밍 > Web' 카테고리의 다른 글

[jQuery] jQuery 예제 01  (0) 2009.07.17
[jQuery] Getting Started with jQuery 04  (0) 2009.07.11
[jQuery] Getting Started with jQuery 02  (0) 2009.07.10
[jQuery] Getting Started with jQuery 01  (0) 2009.07.10
[jQuery] How jQuery Works  (0) 2009.07.06
출처: http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery

Using Ajax
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>jQuery Starterkit</title>

<link rel="stylesheet" type="text/css" media="screen" href="css/screen.css" />
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
    // generate markup
    var ratingMarkup = ["Please rate: "];
    for(var i=1; i <= 5; i++) {
        ratingMarkup[ratingMarkup.length] = "<a href='#'>" + i + "</a> ";
    }
    var container = $("#rating");
    // add markup to container
    container.html(ratingMarkup.join(''));
   
    // add click handlers
    container.find("a").click(function(e) {
        e.preventDefault();
        // send requests
        $.post("starterkit/rate.php", {rating: $(this).html()}, function(xml) {
            // format result
            var result = [
                "Thanks for rating, current average: ",
                $("average", xml).text(),
                ", number of votes: ",
                $("count", xml).text()
            ];
            // output result
            $("#rating").html(result.join(''));
        } );
    });
});
</script>

</head>
<body>
<h1>jQuery Getting Started Example - rate me</h1>
<p>This example demonstrate basic use of AJAX. Click one of the links below to rate. The
number of rating and the average rating will be returned from the serverside script and displayed.</p>

<div id="rating">Container</div>

</body>
</html>
$("average", xml).text() -> 결과로 받은 xml에서 <average>XXX</average>를 찾아서 text 값을 가져온다.
딱히 구조(부모-자식)는 상관없는 듯.

기타 참고 사항.
ajax 사용 시 주의점

A very common problem encountered when loading content by Ajax is this: When adding event handlers to your document that should also apply to the loaded content, you have to apply these handlers after the content is loaded. To prevent code duplication, you can delegate to a function.
Example:
function addClickHandlers() {
   $("a.remote", this).click(function() {
     $("#target").load(this.href, addClickHandlers);
   });
 }
 $(document).ready(addClickHandlers);

Now addClickHandlers is called once when the DOM is ready and then everytime when a user clicked a link with the class remote and the content has finished loading.

Note the $("a.remote", this) query, this is passed as a context: For the document ready event, this refers to the document, and it therefore searches the entire document for anchors with class remote. When addClickHandlers is used as a callback for load(), this refers to a different element: In the example, the element with id target. This prevents that the click event is applied again and again to the same links, causing a crash eventually.

Another common problem with callbacks are parameters. You have specified your callback but need to pass an extra parameter. The easiest way to achieve this is to wrap the callback inside another function:
// get some data
 var foobar = ...;
 
 // specify handler, it needs data as a paramter
 function handler(data) {
   //...
 }
 
 // add click handler and pass foobar!
 $('a').click(function(){
   handler(foobar);
 });
 
 // if you need the context of the original handler, use apply:
 $('a').click(function(){
   handler.apply(this, [foobar]);
 });


출처: http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery

간단한 부분은 제외.

Using selectors and events

$(document).ready(function() {
   $("#orderedlist").addClass("red");
 });
id가 orderedlist 인 것을 찾아서 red 클래스를 추가

$(document).ready(function() {
   $("#orderedlist > li").addClass("blue");
 });
orderedlist 가 갖는 모든 li 태그에 blue 클래스 추가

$(document).ready(function() {
   $("#orderedlist li:last").hover(function() {
     $(this).addClass("green");
   },function(){
     $(this).removeClass("green");
   });
 });
orderedlist 가 갖는 마지막 li 태그 위에 커서가 오면 green 클래스를 추가하고, 커서가 나가면 green 클래스를 제거

$(document).ready(function() {
   $("#orderedlist").find("li").each(function(i) {
     $(this).append( " BAM! " + i );
   });
 });
orderedlist 의 li 태그들을 찾아서, 각각의 li 태그 내의 값(<li>XXX</li>)에 BAM! 현재 카운트를 붙인다.
each(function(i) {...}) 에서 i 가 루프의 현재 카운트 값. 시작은 0.

$(document).ready(function() {
   // use this to reset a single form
   $("#reset").click(function() {
     $("form")[0].reset();
   });
 });

$(document).ready(function() {
   // use this to reset several forms at once
   $("#reset").click(function() {
     $("form").each(function() {
       this.reset();
     });
   });
 });
폼 리셋하기.
위는 폼이 1개일 때. 밑은 여러 개일 때.

$(document).ready(function() {
   $("li").not(":has(ul)").css("border", "1px solid black");
 });
ul 태그를 갖지 않는 모든 li 태그에 주어진 css 스타일을 적용(border를 1px solid black으로).
원래는 모든 li 태그를 찾고 그 중에서, ul 태그를 갖는 li 태그를 제거.

$(document).ready(function() {
   $("a[name]").css("background", "#eee" );
 });
XPath 형식의 객체 선택.
name 속성을 갖는 a 태그를 선택해서 css 스타일 적용.

[jQuery] How jQuery Works

프로그래밍/Web 2009. 7. 6. 17:38 Posted by galad
출처: http://docs.jquery.com/Tutorials:How_jQuery_Works

window.onload=function() {
    alert("welcome");
}
이건 html내의 모든 것이 로드된 후에 실행되지는 않는다고.(그 이전에 실행될 듯?)

jQuery로는 다음과 같이 처리.
$(document).ready(function() {
    alert("welcome");
});

a 태그 클릭 시, 링크로 이동 전에 메시지 출력.
(a 태그에 click handler를 추가)
$(document).ready(function() {
    //alert("welcome");

    $("a").click(function(event) {
        alert("Thanks for visiting.");
    });
});

a 태그 클릭 후, a 태그의 행동을 막으려면(기본 행동을 막으려면)
$(document).ready(function() {
    //alert("welcome");

    $("a").click(function(event) {
        alert("Thanks for visiting.");
        event.preventDefault();
    });
});

기타 추가 기능
$(document).ready(function() {
    //alert("welcome");

    $("a").click(function(event) {
        alert("Thanks for visiting.");
        event.preventDefault();
        $("a").hide("slow");    // 태그 천천히 숨기기
    });

    $("a").addClass("test");        // 태그에 class 추가
    $("a").removeClass("test");    // 태그에 class 삭제
});
class는 여러 개를 추가할 수 있다.

Callback & Functions
Callback실행 전에 부모가 실행된다. Callback에 인자를 넘길 수 있다....
인자 없는 Callback
$.get('myhtmlpage.html', myCallBack);
myhtmlpage.html 실행 후, myCallBack함수를 실행한다(myCallBack은 함수 포인터).

인자 있는 Callback
$.get('myhtmlpage.html', myCallBack(param1, param2));  // 틀린 방법

$.get('myhtmlpage.html', function(){  // 올바른 방법
    myCallBack(param1, param2);
});