[jsp] include

프로그래밍/Web 2011. 5. 25. 13:06 Posted by galad
http://www.aboutjsp.com/lec/include.jsp

<jsp:include page="aaa.jsp" flush="true" />
=> JSP Action 구문의 include 는 include되는 파일과 include 시키는 파일를 각각 컴파일 한후 두 파일의 실행 결과를 한곳에 합쳐서 출력. 완전히 "별도로" 동작

<%@include file="bbb.jsp" %>
=>
include 지시어 와 Action 구문과의 가장 큰 차이점은 include 지시어는 컴파일 되기전에 파일이 내용이 합쳐진다는 것입니다.  자신의 문서내에 포함하여 하나의 파일로 인식

[java] List 정렬하기

프로그래밍/Java 2011. 4. 6. 16:05 Posted by galad
http://ssami.tistory.com/291

정렬할 대상 List가 갖는 Info 클래스
###java;highlight: [27,28,29]
package com.omp.bp.cms.common.model;

public class CommonFileInfo implements Comparable<CommonFileInfo> {

    private String fileName;    // 파일명
    private String filePath;    // 파일경로
    private String name;        // 화면 표시용 이름

    public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    public String getFilePath() {
        return filePath;
    }
    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int compareTo(CommonFileInfo o) {
        return fileName.compareTo(o.getFileName());
    }
}
compartTo 메소드가 Collections를 이용해 정렬할 때 사용된다.
Info 클래스의 구성원 중 하나만 가지고 비교할 때는 Comparable를 구현하는 방법을 사용하고,
여러 개의 구성원 중 선택해서 정렬하는 방식을 원할 때는 맨 위의 링크를 참고.

정렬하는 메소드
###java
/**
 * 파일 정보를 목록으로 생성. 파일명 역순 정렬.
 * @param files
 * @return
 */
private List<CommonFileInfo> getFileInfos(File[] files) {

    List<CommonFileInfo> list = new ArrayList<CommonFileInfo>();

    for(File f : files) {
        CommonFileInfo info = new CommonFileInfo();
        info.setName(f.getName());
        info.setFileName(f.getName());
        info.setFilePath(f.getAbsolutePath());

        list.add(info);
    }

    Collections.sort(list);        // 정렬
    Collections.reverse(list);    // 역순

    return list;
}

[struts2] <s:select> 사용법 2

프로그래밍/Framework 2011. 3. 22. 17:36 Posted by galad
<s:select name="startYear" list="yearList" listValue="label" listKey="value"></s:select> 년
<s:select name="startMonth" list="monthList" listValue="label" listKey="value"></s:select> 월
~ <s:select name="endYear" list="yearList" listValue="label" listKey="value"></s:select> 년
<s:select name="endMonth" list="monthList" listValue="label" listKey="value"></s:select> 월

Action에서 name으로 받아지는 값이 있으면 select box에서 기본값으로 설정된다.

    private List<LabelInfo> yearList;
    private List<LabelInfo> monthList;
    private String startYear;
    private String startMonth;
    private String endYear;
    private String endMonth;


###java
private List<LabelInfo> yearList;
private List<LabelInfo> monthList;
private String startYear;
private String startMonth;
private String endYear;
private String endMonth;
http://nogun.tistory.com/64

컴을 바꿔서 소스를 옮기고 확인해봤더니 BASE64Decoder 사용한 곳에서 모두 에러 발생.
구글링 결과, 위와 같다는 군...

나도 따라서 간단한게 이클립스 설정을 변경 ㅡ.ㅡ;;
http://nogun.tistory.com/65

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

[java] List 정렬하기  (0) 2011.04.06
[java/펌] Java Character Set의 이해  (0) 2010.11.11
[zip] 압축하기3  (0) 2010.10.11
[zip] 압축하기2  (0) 2010.10.08
[zip] zip 압축하기/압축풀기  (0) 2010.10.08

[oracle] Windows 7 과 oracle, Toad

프로그래밍/DB 2011. 3. 9. 13:34 Posted by galad
64bit 윈도우즈 7에 오라클 10g 64bit를 설치하고 Toad 9.5를 깔았더니 토드가 오라클을 인식 못 해...
구글링 결과 토드가 64bit 오라클을 못 찾는다고... 레지스트리 변경해서 인식하게 해주는 방법도 있으나 여러모로 불안정해보여서
그냥 32bit 오라클을 설치...
http://likebnb.tistory.com/79

추가적으로 윈도우즈7에 오라클 10g 설치 시 지원하지 않는 운영체제?라는 메시지와 함께 오라클 설치가 불가능.
오라클 설치용 설정파일 수정 필요
http://guisin.net/69

설치 대상 시스템에 윈도우즈7을 추가하는 것

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

[Tool] 토드 폰트 변경하기  (0) 2010.11.19
[oracle] SELECT 를 사용한 UPDATE 3  (0) 2010.09.14
[oracle] select 문을 이용한 update 2  (0) 2010.08.16
[SQLite] Command Line Shell For SQLite  (0) 2010.05.24
[SQLite] Quick Start  (1) 2010.05.24
http://maven.apache.org/guides/mini/guide-configuring-maven.html

계정\.m2\setting.xml 내에 <localRepository> 엘리먼트를 추가/수정하면 된다.

[jQuery] form validation

프로그래밍/Web 2011. 3. 2. 15:24 Posted by galad
http://bassistance.de/jquery-plugins/jquery-plugin-validation/

간단하게 쓰기. class만 맞춰주면 OK.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!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>

<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/cms/make_new_image.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/cms/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/cms/jquery/jquery.validate.js"></script>

<script type="text/javascript">
$(document).ready(function(){
    $("#mainForm").validate();
});
</script>
</head>
<body>
<form action="" id="mainForm">
컨텐트 종류 <s:select name="contentType" list="contentTypeList" listValue="label" listKey="key"></s:select>
<br>
원본 메타 필드명 <s:textfield name="srcMeta" cssClass="required"></s:textfield>
<br>
대상 메타 필드명 <s:textfield name="destMeta" cssClass="required"></s:textfield>
<br>
리사이즈 크기 : 가로 <s:textfield name="width" cssClass="required number"></s:textfield> 세로 <s:textfield name="height" cssClass="required number"></s:textfield>
<br>
<s:submit></s:submit>
</form>
</body>
</html>


경고문구 css 설정하기
label.error {
    /* remove the next line when you have trouble in IE6 with labels in list */
    color: red;
    font-style: italic
}

그밖의 여러가지 사용법 - 나만의 유효성검사룰 설정하기, ajax 등은 예제 참고.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="org.apache.commons.lang.StringUtils"%>
<%@ page import="com.omp.commons.utils.SessionUtil" %>
<%@ page import="com.omp.bp.cms.member.MemberConstants"%>
<%@ page import="com.omp.bp.cms.member.model.LoginUserInfo" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!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>

<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/css/cms/make_new_image.css">
<script type="text/javascript" src="${pageContext.request.contextPath}/js/cms/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/cms/jquery/jquery.validate.js"></script>

<script type="text/javascript">
var m_browser;
var m_version;

function detectBrowser() {
    if($.browser.msie) {
        m_browser = "msie";
    }
    else if($.browser.safari) {
        m_browser = "safari";
    }
    else if($.browser.opera) {
        m_browser = "opera";
    }
    else if($.browser.mozilla) {
        m_browser = "mozilla";
    }

    m_version = $.browser.version;
    //alert(m_browser + " " + m_version);
}

$(document).ready(function(){
    detectBrowser(); // browser/version check

    // 폼 유효성 검사
    $("#mainForm").validate({
        submitHandler: function(form) {
            // do other stuff for a valid form
            disableSubmit();
            form.submit();
        }
    });

    /*$("#submitBtn").click(function(){ // 유효성 검사 통과했을 때만 실행하도록 수정
        disableSubmit();
    });*/

    parentResize(); // admin poc 화면 크기 조절용
});

function disableSubmit() {
    $("#submitBtn").hide();
    $("#submitLbl").show();
}

function parentResize() {
<%
    LoginUserInfo loginInfo = (LoginUserInfo)SessionUtil.getMemberSession(request);
    boolean isAdmin = StringUtils.equalsIgnoreCase(loginInfo.getMemberType(), MemberConstants.MEMBER_TYPE_ADMIN);
%>
    //운영자면 adminpoc의 프레임 크기 조절용 스크립트를 실행
    var isAdmin = <%=isAdmin%>;
    if(isAdmin) {
        rsize();
    }
}

function rsize() {
    var iframe = document.getElementById( 'inneriframe' );
    var height = Math.max( 200, document.body.scrollHeight + 500 );
    iframe.src = '<%=loginInfo.getAdminpocResizeUrl()%>?height='+height;
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath}/common/makeNewImage.omp" id="mainForm" method="post">
컨텐트 종류 <s:select name="contentType" list="contentTypeList" listValue="label" listKey="key"></s:select>
<br>
원본 메타 필드명 <s:textfield name="srcMeta" cssClass="required"></s:textfield>
<br>
대상 메타 필드명 <s:textfield name="destMeta" cssClass="required"></s:textfield>
<br>
리사이즈 크기 : 가로 <s:textfield name="width" cssClass="required number"></s:textfield> 세로 <s:textfield name="height" cssClass="required number"></s:textfield>
<br>
<s:submit id="submitBtn" value="이미지 생성 시작"></s:submit><label id="submitLbl" style="display: none;">이미지 생성 처리중...</label>
</form>
</body>
</html>



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

[jsp] include  (0) 2011.05.25
[jsp/servlet] jsp 와 servlet 의 차이  (0) 2010.10.29
[펌] jQuery Fundamentals  (1) 2010.10.07
[html] 웹페이지에서 마우스 툴팁(Tooltip; 말풍선) 태그(Tag)  (0) 2010.05.31
[script] 정규식  (0) 2010.05.20

[struts2] <s:if> 사용법3

프로그래밍/Framework 2011. 1. 3. 14:08 Posted by galad
<s:set var="isTvAppAdmin"><%=isTvAppAdmin%></s:set>

<s:if test="!{isTvAppAdmin}">
<s:if test="{isTvAppAdmin != 'true'}">
<s:if test="{isTvAppAdmin.equals('true')}">
<s:if test='{isTvAppAdmin != "true"}'>
<s:if test='%{#isTvAppAdmin.equals("false")}'>
...
...
</s:if>

isTvAppAdmin에 true를 넣고,
거짓이면 if문 내의 것이 실행되도록 했음.

test = !{...} 에서 {} 안의 것이 참 또는 거짓을 판별하는 조건이 되고, !는 NOT 임.

(수정)
위와 같은 경우, s:set 으로 isTvAppAdmin 에 넣은 값이 문자열 "true" 또는 "false" 라서 s:if 에서 boolean 으로 사용되지 않음.
즉, {문자열} 일 경우에는 무조건 참. 그래서 문자열 비교로 수정하였음.

(수정2)
문자열 비교이므로 equals 사용할 것. ㅡ.ㅡ;;;;

(수정3)
문자열 비교인데 equals 안됨.
수정1에서 안되었던 것은 문자열 비교이므로 ""로 묶어야 하는데 ''으로 묶어서 안되었던 것인 듯.

(수정4)
역시 equals로 해야만 함!.
단, s:set으로 밸류 스택에 넣었기 때문에 #변수명으로 불러와야만 함!
그리고 !{조건} 은 성립하지 않는 듯. 결과값이 생각과 다름.  <s:if test='%!{#isTvAppAdmin.equals("true")}'> 가 안되서 위와 같이 했음.
<s:debug> 태그로 표시된 value stack에 접근하기
<s:property value="#parameters.artist_id"/><br>
<s:property value="#parameters.artist_name"/><br>
<s:property value="#parameters.nationality"/><br>
<s:property value="#parameters.activity_type"/><br>
<s:property value="#parameters.genre"/><br>
<s:property value="#parameters.activity_period"/><br>
<s:property value="#parameters.imgFileName"/><br>
<s:property value="#com.opensymphony.xwork2.ActionContext.parameters.imgFileName"/>

<s:debug> 내용을 보면 Value Stack Contents 와 Stack Context로 나누어져있는데, Stack Context에는 #key 로 접근할 수 있다고 쓰여 있다.

parameters {activity_type=[Ljava.lang.String;@1f55cae, artist_id=[Ljava.lang.String;@197d09f, artist_name=[Ljava.lang.String;@18e1b, nationality=[Ljava.lang.String;@1f808e6, genre=[Ljava.lang.String;@18b492, activity_period=[Ljava.lang.String;@f1b25e}

파라메터 인터셉터 <interceptor-ref name="params"> 를 설정하면, request의 파라메터 값이 밸류 스택에 저장된다고 한다.
위처럼 들어가는 듯..

근데 input type="file"은 못가져오나?
jsp
<form name="frm "action="${pageContext.request.contextPath}/openapi/artist/add.omp" method="post" enctype="multipart/form-data">
    <input type="text" name="test"><br>
    <input type="file" name="img"><br>
    <input type="submit">
</form>

action
public class ArtistAction extends BaseAction {

    /**
     *
     */
    private static final long serialVersionUID = 384851516132095345L;
    private final static Logger log = Logger.getLogger(ArtistAction.class);

    private File img;            // 업로드할 실제 파일
    private String imgFileName;    // 업로드할 파일명, 규칙 : (파일input태그 name) + FileName

    public String add() {
        HttpServletRequest request = getRequest();

        log.debug(request.getParameter("test"));
        log.debug("FileName = " + imgFileName);
        log.debug("FileSize = " + img.length());

        return SUCCESS;
    }

    public File getImg() {
        return img;
    }

    public void setImg(File img) {
        this.img = img;
    }

    public String getImgFileName() {
        return imgFileName;
    }

    public void setImgFileName(String imgFileName) {
        this.imgFileName = imgFileName;
    }
}

interceptor에 <interceptor-ref name="fileUpload"/> 설정되어 있고, <input type="file" name='img"> 태그의 name만 aciton의 멤버변수명과 일치시켜 주면 간단하게 파일을 받을 수 있다.

꼭 <s:file> 태그를 쓰지 않아도 상관없다.

[strust2] Chain Result

프로그래밍/Framework 2010. 12. 14. 16:50 Posted by galad
다른 package의 Action으로 chain 걸기

    <package name="openapi" extends="bp-common" namespace="/openapi">
        <action name="*/*" class="com.omp.bp.cms.openapi.action.OpenApiAction">
            <result type="chain">
                <param name="namespace">${namespace}</param>
                <param name="actionName">${actionName}</param>
                <param name="method">${actionName}</param>
            </result>
        </action>
    </package>

    <package name="artist" extends="bp-common" namespace="/artist">
        <action name="add" class="com.omp.bp.cms.openapi.artist.action.ArtistAction" method="add">
            <result>/serverIp.jsp</result>
        </action>
    </package>

적절하게 namespace, actionName, method를 넘겨주면 된다.
request 시의 parameter를 모두 다음 Action에서 사용하고 싶을 때 사용.
http://offree.net/3366

chrome://view-http-cache/

크롬이 캐싱한 모든 url 정보가 표시됨. url 복사해서 받거나, 스트리밍 같은 경우엔 넷트랜스포드 같은 프로그램 사용.
FF의 grease monkey에서 Anti-Disabler for Naver 유저스크립트 쓰기


            out = new FileOutputStream(file);
            XMLOutputter serializer = new XMLOutputter();

            // jdom output format
            Format f = Format.getPrettyFormat(); // output 출력 포맷 - pretty format : whitespace beautification with 2-space indents, uses the UTF-8 encoding 등
            serializer.setFormat(f);

            serializer.output(xmlDoc, out);
            out.flush();


http://www.jdom.org/docs/apidocs/index.html

[Tool] 토드 폰트 변경하기

프로그래밍/DB 2010. 11. 19. 17:51 Posted by galad
http://dev.messfilm.com/87

View - Toad Options - Editor - Behavior - Languages - Edit - Highlighting - Customer Font

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

[oracle] Windows 7 과 oracle, Toad  (0) 2011.03.09
[oracle] SELECT 를 사용한 UPDATE 3  (0) 2010.09.14
[oracle] select 문을 이용한 update 2  (0) 2010.08.16
[SQLite] Command Line Shell For SQLite  (0) 2010.05.24
[SQLite] Quick Start  (1) 2010.05.24

[방법론] Agile

프로그래밍/Development 2010. 11. 15. 16:51 Posted by galad
http://www.ciobiz.co.kr/news/articleView.html?idxno=4054
http://kwangshin.pe.kr/blog/2010/11/08/%EC%99%9C-%EC%95%A0%EC%9E%90%EC%9D%BCagile-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%90%98%EA%B8%B0-%ED%9E%98%EB%93%A4%EA%B9%8C/
http://mckdh.net/353 <-- 이거 많이 좋은 듯?
http://blog.openmaru.com/80


기민한 이라는 말뜻처럼 사용자(고객)의 요구에 기민하게 대응하기 위한 개발 방법론인 듯

기본 개념은 이런 듯?


TDD와 마찬가지로 안드로이드 개발하면서 적용해보자~

1. 기본 개념 알아보기
2. 어떻게 적용하는가?
  -> 책 볼 것. 그리고 위의 산골 블로그 님의 글 참고하기

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

[방법론] TDD  (0) 2010.11.15

[방법론] TDD

프로그래밍/Development 2010. 11. 15. 16:41 Posted by galad
http://www.javajigi.net/display/OSS/TDD#TDD-TDD%EB%94%B0%EB%9D%BC%ED%95%B4%EB%B3%B4%EA%B8%B0
http://www.java2go.net/blog/62

TDD...
책도 읽어봤고 무엇인지 어느 정도 알고 있다고는 생각하나 실제로 제대로 실천해 본 적은 없다...
안드로이드 개발하면서 해보자~

1. 안드로이드 개발 시 테스트는 어떤 식으로 하는가?
  -> 안드로이드 프로젝트 생성 시 테스트 프로젝트도 같이 생성가능

2. 테스트 가능한 영역은?
  -> 아무리 그래도 Activity도 없이 테스트가 가능하려나?

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

[방법론] Agile  (0) 2010.11.15
http://kin.naver.com/knowhow/detail.nhn?docId=527939


현재 일하는 업무 상 String의 Code page를 변환해야 하는 작업이 많다.

 

하지만 이에 관한 자료들이 매우 미흡하며 잘못된 지식을 전달하는 블로그나 웹도 많이 보아왔다.

(처음에 그것이 잘못된 것인지도 몰랐지만)

 

그리고 믿고 사용했지만 여전히 깨져버리는 한글을 보며 고민하기도 했다.

 

사실 DB모니터링 툴 개발 업무를 하다보니 Character Set을 직접 변환해야 하는 작업들이 꽤 많았다.

 

Java에선 과연 어떤 형태로 변환작업을 수행할 수 있으면 읽을 수 있을까 고민도 했다.

 

이 글이 조금은 어려울 수도 있지만 천천히 읽어본다면 충분히 이해할 수 있고 명확하게 java의

 

캐릭터 셋에 대해 알 수 있을 것이다.

 

 영문은 대부분의 캐릭터셋이 1바이트기 때문에 변환작업에서 깨질일이 거의 없다고 할 수 있지만

 

한글은 utf-8의 경우 1에서 4바이트까지의 가변형으로 저장되기 때문에 1글자의 바이트 길이가 달라

 

명시적인 변환이 요구된다.

 

여기저기 자료도 많이 찾아봤지만 역시나 테스트 하는 것이 가장 빠르게 이해할 수 있었다.

 

결론 부터 언급하면 String 객체내 바이트 배열이 어떤 캐릭터셋으로 저장될 것이라는 생각이 오해를 불러왔고

 

잘못된 사고를 하게 했다. String이 실제 메모리 상에 어떠한 캐릭터셋의 바이트 배열로 저장되어 있는지

 

사용자들은 고민할 필요도 없이 자바는 잘 되어 있었다.

 

Jdk 1.4를 기준으로 내 머리의 이해를 도와봤다.

 

내 이름 한민호라는 세자를 utf-8로 byte 배열에 저장해보았다.

 

막무가내로 시작했지만 getBytes라는 함수가 어떻게 이용되는지 알 수 있었다.

 

byte [] bytes = new String("한민호").getBytes("utf-8");

 

처음 이 코드를 작성하고 "한민호"라는 객체는 어떤 캐릭터 셋의 바이트 배열로 저장되어 있을까 생각했지만

 

그것을 생각하면서 이미 정상적인 사고를 하기가 어려웠다. 자바에선 String 객체로 생성되었다면 어떠한 종류의

 

캐릭터 셋의 바이트 배열이든 리턴이 가능하기 때문이다.

 

단 한글로 생성했는데 한글을 지원하지 않는 캐릭터셋이라면 리턴한 바이트 배열의 값이 깨지게 된다.

 

 getBytes라는 메소드에 대해 전혀 알지 못했을 땐 String을 생성할 때 지정한 즉 메모리 상에 저장된

 

"한민호"라는 객체의 바이트 배열의 캐릭터 셋을 지정해줘야 되는 줄 알았다.

 

그러나 이 메소드가 내가 상상했던거 보다 훨씬 대단하다는 것을 알게 되었다.

 

 이 메소드는 현재 저장된 String값이 어떠한 캐릭터 셋으로 저장되든 상관없이

 

바이트 배열과 바이트 배열에 맞는 캐릭터 셋으로 생성만 했다면

 

java에서 한글을 지원(영문만 지원하는 캐릭터 셋은 깨지게 된다.) 하는

 

어떠한 캐릭터 셋으로든 변환하여 변환된 바이트 배열로 리턴한다.

 

 여기서 핵심은 정상적인 String 객체의 생성이라는 것이다. 아래서 정상적인 String 객체의 생성에 대해 알아보겠다.

 

 위에서 생성한 바이트 배열을 다시 String 객체로 변환해 보겠다.

 

String name = new String(bytes, "utf-8");

 

이런 식으로 변환이 가능하다. 간혹 String의 두 번째 파라메터로 넣는 캐릭터 셋을 바이트 배열의 캐릭터 셋이 아닌 다른

 

캐릭터셋을 넣어 변환하겠다는 코드를 많이 봤다. 이건 잘못된 것이다. 이 자린 바이트 배열에 저장된 바이트들의 캐릭터 셋을

 

설정하는 곳이다.

 

잘못된 변환의 사용예를 한가지 들어보겠다.

 

잘못된 변환

String convert = new String(message.getBytes("euc-kr"), "utf-8");

 

소스를 보면 message String에 저장된 문자를 getBytes를 이용하여 euc-kr라는 캐릭터셋 바이트 배열로 얻고있다.

 

분명 이것을 작성한 사람은 위 코드에서 new String(스트링배열, "euc-kr")라고 String 개체를 생성했을 것이다.

 

간단히 설명하면 euck-kr라는 캐릭터 셋으로 바이트 배열을 읽어들인 

 

다음 utf-8이라는 새로운 캐릭터셋으로 변환(?)을 시도하겠다는 것이다.

 

이것은 두 번째 파라메터에 대해 잘못된 이해를 하고 있기에 이런 코드가 가능한 것이다.

 

때문에 이렇게 변환을 하게 되면 한글이 저장된 경우 같은 계열(변환가능한)의 캐릭터 셋이 아니라면 100프로 깨지게 된다.

 

이러한 변환은 자바에서 지원을 안하는 사항이다.

 

또 문제는 다시 String 객체로 생성을 한다는 것이다. 이 때 String생성 시 잘못된 캐릭터 셋을 주었기 때문에 깨진

 

바이트 배열로 저장이 되게 된다. 때문에 이러한 경우 getBytes() 메소드를 통해 어떠한 캐릭터 셋으로 읽든

 

읽을 수가 없게 된다.

 

 그렇다면 이제까지의 사항들에 대해 테스트를 통해 명확히 알아보겠다.

 

아래는 테스트에 자주 사용될 byte 배열을 16진수로 보여주는 함수다.

 

public static String BinToHex(byte [] buf) {
  String res = "";
  String token = "";
  for (int ix=0; ix<buf.length; ix++) {
   token = Integer.toHexString(buf[ix]);
//   CommonUtil.println("[" + ix + "] token value : " + token + " len : " + token.length());
   if (token.length() >= 2)
    token = token.substring(token.length()-2);
   else {
    for(int jx=0; jx<2-token.length();jx++)
     token = "0" + token;
   }     
   res += " " + token;
  }
  
  return res.toUpperCase();
 }

 

< 테스트 소스 >

1   String name = new String("한민호");   
2   strs = name.getBytes();   
3   System.out.println("Length : " + strs.length);
4   System.out.println("Hex    : " + BinToHex(strs));
5   System.out.println("Value  : " + new String(strs));
6   System.out.println();   
7   strs = name.getBytes("utf-8");
8   System.out.println("Length : " + strs.length);
9   System.out.println("Hex    : " + BinToHex(strs));
10   System.out.println("Value  : " + new String(strs, "utf-8") );
11   System.out.println();   
12  name = new String(strs, "utf-8");
13   strs = name.getBytes();
14   System.out.println("Length : " + strs.length);
15   System.out.println("Hex    : " + BinToHex(strs));
16   System.out.println("Value  : " + name);   
17   System.out.println();   
18   String convert = new String(name.getBytes("euc-kr"), "utf-8");
19   System.out.println(convert);
20   strs = convert.getBytes();
21   System.out.println("Length : " + strs.length);
22   System.out.println("euc-kr Hex    : " + BinToHex(strs));
23   strs = convert.getBytes("utf-8");
24   System.out.println("Length : " + strs.length);
25   System.out.println("utf-8 Hex    : " + BinToHex(strs)); 
26   System.out.println();
27   System.out.println();

 

테스트 코드를 보며 이 결과들이 어떻게 나올것이라고 예측했는데 그것이 맞아떨어지지 않는다면

 

다시 글을 보면서 이해하면된다.

 

결과는 아래와 같다.

 

< 결과 >

Length : 6
Hex    :  C7 D1 B9 CE C8 A3
Value  : 한민호

Length : 9
Hex    :  ED 95 9C EB AF BC ED 98 B8
Value  : 한민호

Length : 6
Hex    :  C7 D1 B9 CE C8 A3
Value  : 한민호

????
Length : 4
euc-kr Hex    :  3F 3F 3F 3F
Length : 10
utf-8 Hex    :  EF BF BD D1 B9 EF BF BD C8 A3

 

1번 라인을 보면 한민호라는 String객체를 생성하고 있다

 

이 객체를 strs라는 바이트 배열에 getBytes()를 이용해서 받는다. getBytes에 아무 파라메터도 주지 않는다면

 

이것은 디폴트 캐릭터셋으로 바이트 배열이 리턴된다.

 

디폴트 캐릭터셋은 System.getProperty("file.encoding") 메소드를 통해 알수 있다.

 

이것을 utf-8로 저장하는 로직이 7번 라인이다. 단지 getBytes에 utf-8이란 파라메터를 주고 utf-8 캐릭터 셋의

 

바이트 배열을 받아 올 수 있다.

 

그리고 12번 라인은 이 utf-8로 저장된 바이트 배열을 다시 String객체로 파라메터 값으로 "utf-8"을 주고 생성한 것이다.

 

이때 파라메터를 주지 않거나(디폴트 파라메터가 지정됨) 다른 캐릭터셋을 준다면 깨지게 된다.

 

마지막으로 18번 라인은 잘못된 컨버팅 예이다. euc-kr을 utf-8로 변환하겠다는 건데

 

위에서 설명했듯 이러한 변환 때문에 바이트 배열이 깨져서 euc-kr이든 utf-8이든 어떠한 바이트 배열로 읽어오든

 

깨져있는 것을 확인할 수 있다. 이미 깨져서 생성된 String 객체의 바이트 배열은 어떻게든 복구가 불가능 하다.

 

<결론>

 이야기를 종합해보면 String 객체로 생성된 것을 다른 캐릭터 셋의 String 객체로 변환한다는 것은

 

어불성설인 것이다. 이러한 변환은 무지에서 나오는 것이며 String 객체에 이미 깨진 내용은 어떠한 변환이 있더라도

 

정상적인 출력이 불가능하다는 것이다. 캐릭터셋을 포함하여 관리하겠다면 철저하게 바이트 배열을 이용해야 한다.

 

그리고 String에 어떤 캐릭터 셋으로 저장되어 있는지에 대해 논하는 것은 애초부터 잘못된 것이다.

http://nicho.tistory.com/131
http://www.terms.co.kr/servlet.htm

서블릿은 멀티쓰레딩에 의해 사용자 요구를 처리하고 가공해서 이에 대한 결과를 내보내게 된다. CGI가 클라이언트 프로세스로 처리하는데 반해 서블릿은 클라이언트를 쓰레드로 처리한다. 그래서 많은 클라이언트의 요구를 효과적으로 처리할 수 있다. 서블릿 객체는 쓰레드가 여러 개 돌아가면서 처리하기 때문에 서블릿 메소드들은 반드시 멀티쓰레드에 대한 고려를 해야한다.

 JSP와 서블릿은 자바 기반으로 만들어진 웹 프로그래밍 언어이다. 서블릿이 자바 코드에 의존적이라면 JSP는 덜 의존적이라 프로그래밍하기가 더 쉽고 편하다. JSP와 서블릿은 같은 처리 구조를 가진다. 엄밀히 말하면, JSP는 페이지 요청이 있을 시에는 최초에 한 번 자바 코드로 변환된 후 서블릿 클래스로 컴파일된다. 결론적으로 JSP는 실행시 서블릿으로 변환된다. 단 한번만 서블릿으로 변경되며 코드를 수정하기 전까지 재 변환 작업이 일어나지 않기 때문에 수행 속도는 JSP나 서블릿간에 별차이가 없다.
 
 서블릿과 JSP는 상호 연계되어 JSP에서 정적인 부분을 담당하고, 서블릿은 보다 동적인 처리를 위한 부분으로 사용되어 보다 효율적인 웹사이트를 구성할수 있다. JSP는 주로 사용자용 뷰(view)의 구현에 사용되고 서블릿은 사용자의 뷰와 프로그램 로저 사이를 제어해주는 역활을 주로 사용한다.

서블릿은 서버에서 실행되는 작은 프로그램이다. 이 용어는 웹 페이지와 함께 별도의 파일로 보내지는 작은 프로그램인 자바 애플릿의 맥락에서 만들어진 신조어이다. 자바 애플릿들은 사용자를 위해 간단한 계산업무를 수행하거나 사용자의 반응에 기반하여 이미지를 위치시키는 등과 같은 서비스를 위해 대개 클라이언트에서 실행되도록 만들어진다.

그러나, 사용자의 입력에 따라 데이터베이스와 연계되는 프로그램들은 서버에서 실행될 필요가 있다. 보통, 이러한 것들은 CGI를 이용하여 구현된다. 그러나, 서버에서 실행되는 자바 가상머신을 이용하면, 그러한 프로그램들을 자바 언어로 구현할 수 있다. 서버에 있는 자바 서블릿의 장점은 CGI 응용프로그램보다 더 빠르게 실행될 수 있다는 것이다. 서블릿은 각 사용자의 요청마다 별도의 프로세스가 생기는 대신, 단 하나의 데몬 프로세스 내에서 스레드로 호출되는데, 이는 각 요구에 따른 시스템 오버헤드가 적다는 것을 의미한다.


결국,
jsp 나 servlet 이나 결론적으로는 같음.
단, jsp는 서버에서 서블릿으로 변환되어 - 처음 한번만 - 실행됨
jsp 가 view단을 처리하기에 편리함. 서블릿의 경우엔 모두 프로그램적으로 처리해야함(out.println("<html>"); 이런 식으로)

MVC는 각각의 효율성을 봐서 V를 jsp, C를 서블릿에 맡긴 것.

다 배웠던 건데 왜 싹 다 까먹었나 ㅡ.ㅡ;;

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

[jsp] include  (0) 2011.05.25
[jQuery] form validation  (0) 2011.03.02
[펌] jQuery Fundamentals  (1) 2010.10.07
[html] 웹페이지에서 마우스 툴팁(Tooltip; 말풍선) 태그(Tag)  (0) 2010.05.31
[script] 정규식  (0) 2010.05.20