달력

6

« 2025/6 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
.. .. ..

오라클에서 테이블 스페이스를 생성하면 생성시 준 옵션 (파일 사이즈, 경로 등)을 가지고

데이터 파일을 만든다.

 

이후 테이블을 생성할때 테이블 스페이스를 잡아주면 그 파일명에 테이블이 생기게 된다.

 

만약 유져를 생성할때 디폴트 테이블 스페이스를 잡아주면 그 유져가 테이블을 생성할때 따로

테이블 스페이스를 잡아주지 않더라도 디폴트 테이블 스페이스 영역으로 테이블이 생성된다.

 

만약 유저 생성시 디폴트 테이블 스페이스를 잡아주지 않았다면 오라클의 기본인

시스템 테이블 스페이스에 생성이 되게 된다. 뭐 이에 대한 문제점은.. 레퍼런스를 보던가 하면 되겠지만

 

안좋겠지 라는 생각으로 결말지음..

내게 필요한건 개념이었으니..

 

 

도움되었다면 댓글을 남겨주세요~! 아님 도움말을 더 숑숑 달던가요 ㅎㅎ

.
:
Posted by .07274.
2012. 5. 21. 15:38

JSTL 의 eq , empty , ne 명령 I.lib()/I.lib(JSTL)2012. 5. 21. 15:38

.. .. ..

값이 같은가? 에 대한 비교로 보통 "== ", "!=" 을 많이 사용한다

이는 jstl에서도 마찬가지면 숫자와 문자 구분은 따움표로 구만해서 사용하는데 이대신 eq, ne를 사용하는것과

list, map 같은 객체가 값이 있느냐 없느냐의 구분하는 용도로 empty 를 사용 할 수 있다.

사용법은 아래와 같다

=============================================== Sample =============================================

Ex) eq (==)

1. <c:if test="${ null eq test_column }"> // null

2. <c:if test="${ 0 eq test_column }"> // 숫자

3. <c:if test="${ '0' eq test_column }"> // 문자

Ex) empty

= <c:if test="${ empty test_columnMap }"> // list, map 객체 등

= <c:if test="${ !empty test_columnMap }"> // 비어 있지 않은 경우

Ex) ne (!=)

1. <c:if test="${ null ne test_column }"> // null

2. <c:if test="${ 0 ne test_column }"> // 숫자

3. <c:if test="${ '0' ne test_column }"> // 문자

.
:
Posted by .07274.
.. .. ..

# vi /etc/inet/services

기본 포트 21을 이름 바꾸고 ( 수정)
원하는 포트로 설정 (추가)

ftp2 21/tcp    <= 수정
ftp 11002/tcp  <= 추가




네트웍 데몬 재시작

/etc/init.d/inetsvc stop

/etc/init.d/inetsvc start

.
:
Posted by .07274.
.. .. ..

솔라리스에서 문자를 지울때 백스페이스(Backspace)를 사용하면 ^H 같은 문자열이 생성이 되어 불편헀다.

쉘상에
서 stty erase `tput kbs’ 를 입력하면 백스페이스키를 사용할수 있게 된다.

# stty erase `tput kbs`

쉘상에서 바로 되는 것도
좋지만 SSH 로그인시 자동으로 백스페이스를 사용해주기 위하여 profile 에 한줄 추가 해준다.

# echo ‘stty erase `tput kbs`’ >> /etc/profile
#
cat /etc/profile | grep stty
stty erase `tput kbs`

 

.
:
Posted by .07274.
2012. 3. 22. 16:25

dwr 사용방법 I.lib()/I.lib(Java)2012. 3. 22. 16:25

.. .. ..

[펌] : http://innoc99.blog.me/140046778698

Eclipse에서 Web Project 생성.

Project Name : DWR-Test

dwr.jar 파일을 Project내의 WEB-INF/lib에 넣어준다.

(첨부파일에서는 -leepcs 부분을 지운후에..)

web.xml에 아래 내용 추가.

<servlet>
<servlet-name>dwr-invoker</servlet-name>
<!-- If you are using DWR 1.x then servlet-class line shoud contain the following -->
<!-- uk.ltd.getahead.dwr.DWRServlet -->

<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>

</servlet-mapping>

중간 파란색 부분은 dwr 버전이 1.x라면 uk.ltd로 시작하는것을 servlet-class로 적어주어야만 한다. 무조건.

dwr.xml 만들기.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
<allow>
<create creator="new" javascript="HelloTest" >
<param name="class" value="dwr.test.SimpleText"/>
<include method="hello"/>
</create>
</allow>
</dwr>

creator에 new라는 것은 객체를 만들어서 사용한다는 것이고.. HelloTest는 jsp나 html에서 객체의 이름으로 사용할 것을 적는당.

param의 class란 java파일이므로 class라 한 것이고... value의 dwr.test.SimpleText는 java파일의 경로를 적은 것.

hello란 것은 SimpleText Class의 메소드로 hello가 있다는 것을 정의해준 것.(그냥 쓸거 정의하면 됨..)

SimpleText.java 만들기

src 아래에 패키지 만들기를 통해 dwr.test를 만든 후 test 아래에 SimpleText class를 만든다.

package dwr.test;

public class SimpleText {

public String hello(String value){
return "Hello ~ "+value;
}

}

hello는 dwr.xml에서 정의한 것(자신이 쓸 메소드)과 일치시켜주면 된다.

이제 톰캣에 Project를 올리고 서버를 실행시킨후에

http://localhost:{your_port}/{your_app}/dwr/

위 주소로 들어가게 되면 dwr.xml에 정의했던 Class 목록이 나오게 된다.

위와 똑같이 했다면 이런 화면....

그리고 HelloTest를 눌러보면은.. 아래와 같이 나오게 된다..

위 그림에서 보면 script 구문이 3줄이 있다.

DWR이 알아서 저걸 만들어 준다는 것이다.

그리고 그 아래에는 Test를 할 수 있는 부분이 있다.

WebContent/index.jsp 만들기.

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>
<!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>Insert title here</title>
<script type='text/javascript' src='/DWR-Test/dwr/interface/HelloTest.js'></script>
<script type='text/javascript' src='/DWR-Test/dwr/engine.js'></script>
<script type='text/javascript' src='/DWR-Test/dwr/util.js'></script>
<script type="text/javascript">
function test(){
var value = dwr.util.getValue('demo');
//var value = document.getElementById('demo').value;
HelloTest.hello(value,

function(data) { dwr.util.setValue("here", data); }

);

}
</script>
</head>
<body>
<input type="text" value="" size="20" id='demo'>
<input type="button" value="send" onclick="test()"/>
<br>
<input type="text" id="here" value=""/>
</body>
</html>

send를 클릭하게 되면 JavaScript의 test() function이 호출이 된다.

test에서는 demo에 적혀진 text를 value로 저장해 DWR에서 정의한 객체(HelloTest)의 메소드(hello)를 호출한다.

그런데 hello 메서드를 보게 되면 매개변수가 하나 였는데 script내에서는 2개이다..

why?

이를 callback function이라 하는데, return값이 있다면 return 값을 처리하는 함수이다.

왜 저렇게 쓰냐고 하면... 그냥 간단히 하기 위해서??

왜 복잡한지 궁금하다면..

function test(){

var value = dwr.util.getValue("demo");

HelloTest.hello(value, cb_function);

}

function cb_function(data){

dwr.util.setValue("here", data);

}

이렇게 사용하느니 그냥 줄여서 사용한다 이거다.

위 예제는 정말 간단하게 DWR 설명이 가능한 예제이다..

jsp -> Java로 가는 대부분의 과정을 DWR이 처리해주고 있다..

무분별한 사용은 금지..

데이터가 많을 경우 메모리 급상승 최악에는 서버가 죽어버린다..

아래 링크에서 확인할 수 있다.

http://javaora.tistory.com/109

.
:
Posted by .07274.
.. .. ..

catalina.out 로그에 관해서 알아봤는데(로그를 1일 단위로 파일로 남기고 삭제하기) 여러가지 방법이 있는데
1. 외부 응용 프로그램 서버에 설치 필요.
2. Tomcat 서버의 실행파일 변경
3. Shell 스크립트 짜서 Crontab으로 실행.

1번은 외부 프로그램이라 설치하기 좀 그렇고
2번은 다른 사람들이 알아보기 어려운 곳을 변경하는거라 개인적으로 추천드리지 않습니다.
그래서 3번을 진행

#!/bin/sh

LOG_DIR=/usr/local/web/tomcat5/log
DATE=`/bin/date +%Y-%m-%d`

/bin/nice /bin/cp  $LOG_DIR/catalina.out $LOG_DIR/backup/catalina.out.$DATE
/bin/nice /bin/cat /dev/null > $LOG_DIR/catalina.out

#
# delete out-of-date catalina.log
#

#DELETE_DATE=`/bin/date +%Y-%m-%d --date '20 day ago'`
DELETE_DATE`/bin/date +Y-%m-%d --date '1 month ago'`

echo "$LOG_DIR/backup/catalina.out.$DELETE_DATE"

for file in $LOG_DIR/backup/*
do
        if [[ "$file" < "$LOG_DIR/backup/catalina.$DELETE_DATE.out" ]]
        then
                rm -f $file
        fi
done

# end of file


변경이 좀 필요하지만 저정도면...

ps : 리눅스 OS는 기본적으로 Log 관리해주는 프로그램이 있어서 다들 그것을 쓰는데 유닉스 서버에는 없어서  쉘 스크립트로 진행하게 되는점을 참고해 두시기 바랍니다.

.
:
Posted by .07274.
.. .. ..
[펌] : http://msfury.tistory.com/118

스프링에서 기본적으로 지원하는 CommonsMultipartResolver라는게 있는데

이게 파일 여러개를 지원 안한다...

(뭐하나 제대로 되는게 없긔...)

참고 : http://www.egovframe.org/wiki/doku.php?id=egovframework:rte:fdl:file_upload_%EB%AC%B8%EC%A0%9C

방법을 찾던중

발견한 정부프레임워크 URL

1번링크의 2번 솔루션으로 해결했는데.

영어가 참 중요하다고 느낀게...

2번솔루션 대로 하면 여러파일의 업로드가 되는 대신 내가 원한대로

public class FileForm {
private CommonsMultipartFile file;
private MultipartFile[] fileArr;

public CommonsMultipartFile getFile() {
return file;
}

public void setFile(CommonsMultipartFile file) {
this.file = file;
}

public MultipartFile[] getFileArr() {
return fileArr;
}

public void setFileArr(MultipartFile[] fileArr) {
this.fileArr = fileArr;
}
}

요놈 안에 쏙 안들어 간다...

문제1.

 Map multipartFiles = new HashMap();
...
return new MultipartParsingResult(multipartFiles, multipartParameters);
MultipartParsingResult의 생성자 명세가 바뀐건지 아님 저 소스가 착각을 했던지...

첫번째 인자의 class가 HashMap이 아닌

MultiValueMap<String, MultipartFile> multipartFiles = new LinkedMultiValueMap<String, MultipartFile>();

요렇게 바꿔줘야 한다. 그럼 다음 문제가 발생하는데..

문제2.
// multipart file field
                CommonsMultipartFile file = new CommonsMultipartFile(fileItem);
                if (multipartFiles.put(fileItem.getName(), file) != null) {
                    throw new MultipartException("Multiple files for field name [" + file.getName()
                            + "] found - not supported by MultipartResolver");
                }

MultiValueMap은 키 하나에 여러 Value를 가질수 있게 해주는 Map인데 put이 없다....

set과 add 메소드가 존재하지만 둘다 리턴값이 void라 null비교 구문에서 에러가 난다.

(set은 단일키에 단일 밸류를 입력할수 있게 해주고 add를 쓰게 되면 단일키에 멀티 밸류를 가지게 해준다)

암튼 내가 원하는 대로 처리를 하기 위해 널체크를 따로 했다. 어차피 fileItem.getName()이 널이거나

공백이면 파일 폼은 있었는데 입력을 안해줬다는 얘기니까.

if( fileItem != null && fileItem.getName() != null && !"".equals(fileItem.getName()) ){
multipartFiles.add(fileItem.getFieldName(),file);
}

여기서 중요한게 하나 더 있는데 getName으로 넣은게 아니라 getFieldName을 썼다는것

getName은 파일이름이고 리졸버를 지나간뒤 콘트롤러에서 받을땐 파일 이름이 키가되어 파일을 가져올

수 있다.(이거부터 좀 이상하다...저 소스 의도가 대체 뭔지...음...영어가 딸려서 의도 파악이 잘 안됨;;)

암튼 키를 필드네임으로 바꿔주면

<input type="file" id="fileArr1" name="fileArr" />

로 줬을때 fileArr을 키로 가지고 콘트롤러에 넘겨주게 된다.

그리하면 저 위에 FileForm 클래스에 MultipartFile[] fileArr; 이부분에 배열로 파일을 넣어주게 된다.

그 이후부터는 단일 파일 받았을때처럼 가져와서 처리하고 저장하면 끝~

'I.lib() > I.lib(Spring)' 카테고리의 다른 글

spring transactionManager 설정  (0) 2013.08.06
Spring 2.5 에서 Rest 사용하기 Sample  (1) 2012.09.06
DispatcherServlet 이란?  (3) 2012.03.07
[ViewResolver] ViewResolver  (1) 2012.03.07
Spring 에서 JSON 사용하기  (0) 2012.02.27
.
:
Posted by .07274.
2012. 3. 7. 17:18

DispatcherServlet 이란? I.lib()/I.lib(Spring)2012. 3. 7. 17:18

.. .. ..

[펌] : http://springmvc.egloos.com/504151

이전 장까지 MyBatis와 커넥션풀의 활용, 그리고 트랜잭션에 대해 상세히 알아보았습니다. 개인적으로 이 정도의 환경이라면 소, 중형 서비스 구축에는 문제없을 정도로 환상적인 제작환경이 구축됬다고 할 수 있겠네요. 또 실제로 많은 웹개발자들이 이런 포맷을 사용하고 있구요.

이제 우리가 해야 할 것은 누구나 탐낼만한 좋은 개발환경을 구축했으니 드문드문 처리해야할 애매한 문제들을 하나씩 알아나가보는 과정입니다. 그 중 오늘은 우리가 해결해야할 것은 바로 web.xml에 설정한 DispatcherServlet에 대해 알아가고 발생할 수 있는 문제점을 해결하는 것입니다.

스프링MVC는 DispatcherServlet 등장으로 정말 엄청나게 web.xml의 역할이 축소되었습니다. 예전같으면 서블릿을 URL로 활용하기 위해선 반드시 web.xml에 등록해야 했지만 이젠 DispatcherServlet이 해당 어플리케이션으로 들어오는 요청을 모두 핸들링해주니 말이죠.

물론 아직까지 web.xml의 역할은 중요합니다. <servlet>으로 DispatcherServlet을 등록해줘야 하는데다 이 객체의 URL 적용범위 또한 web.xml에다 설정해야 하구요. 향후 고급서비스를 위해 <filter>나 <listener>를 등록하는 역할 또한 web.xml의 기능으로 남아 있습니다.

대신 앞으로 web.xml에서 가장 주요하고 자주 쓰이는 기능인 <servlet>매핑은 이제 완벽하게 DispatcherServlet으로 넘어갔다고 생각합시다. 우리가 web.xml에 DispatcherServlet의 <url-pattern>을 '/'로 설정함과 동시에 이제 모든 요청은 DispatcherServlet의 영역이 된 셈입니다. 물론 DispatcherServlet을 web.xml에 등록해도 계속 서블릿을 web.xml에 매핑해쓸 수 있긴 합니다만 우리가 이런 옛방식을 버리고 DispatcherServlet을 이용해 웹개발을 한다면 앞으로 서블릿 파일을 만들 필요도 없어짐과 동시에 획기적이고 놀라운 @MVC의 혜택을 얻을 수 있습니다. @MVC에 대해서는 차후 설명하기로 하고 오늘은 DispatcherServlet의 역할에 대해 설명드리겠습니다.

먼저 DispatcherServlet을 이용한다는 것은 스프링에서 제공하는 @MVC를 이용하겠단 뜻입니다. @MVC는 그동안 추상적으로만알아오고 발전했던 MVC(Model, View, Controller) 설계영역을 아예 노골적으로 분할하여 사용자가 무조건 MVC로 어플리케이션을 설계하게끔 유도하는 방식인데요. (스프링이 전략패턴을 Dependency Injection이란 이름하에 유도하는 것과 마찬가지죠.) 이 말인즉 초보건 구루건 모두 @MVC를 이용해 어플리케이션을 개발한다면 99% MVC 설계의 원칙대로 웹어플리케이션이 제작할 수 있게 된다는 뜻입니다.

우리가 @MVC라는 이름 하에 DispatcherServlet 클래스를 web.xml에 등록하는 순간 스프링이 있기 전 힘겹게 배웠던 모델1, 모델2는 이제 완전한 추억거리가 되고 말 것입니다. @MVC는 설계자체를 모델1 방식으로 할 수 없게 만드는 데다 그동안 구현하기는 까다롭지만 활용성이 높다고 배웠던 모델2 방식을 모델1보다 쉽게 만들 수 있도록 환경을 조성해주기 때문입니다. 게다가 정확히 따지자면 @MVC는 모델 2방식의 설계도 아닙니다. 다만 우리가 @MVC로 코드를 작성하는 방식이 모델 2와 비슷해서 모델2 방식이라고 부르는 것 뿐이죠.

그렇다면 @MVC에서 DispatcherServlet가 담당하는 역할이 무엇인지 알아봅시다. 먼저 DispatcherServlet에 대해 간단히 정의해보자면 우리가 각각 분리하여 만든 Model 파트와 Controller파트 View파트를 조합하여 브라우저로 출력해주는 역할을 수행하는 클래스라 할 수 있겠네요.

간단하게 DispatcherServlet이 어떤 식으로 클라이언트의 요청을 처리하고 응답하는지 UML과 비슷한 방식으로 나타내 보았습니다. 아마 DispatcherServlet을 처음 접해본 분이시라면 모델2보다 복잡한 처리과정에 당황하실 수도 있겠네요. 하지만 위의 그림이 아무리 복잡해도 당황하실 필요는 없습니다. 어디까지나 저 처리과정의 대부분은 컨테이너가 대신 작업해주며 사용자가 직접 구현해야 될 분량은 얼마 되지 않으니까요. 먼저 위의 작업흐름을 풀어 자세히 설명하자면 다음과 같습니다.

① 클라이언트가 해당 어플리케이션에 접근하면 접근한 URL 요청을 DispatcherServlet이 가로챕니다. 이렇게 요청을 가로챌 수 있는 이유는 web.xml에 등록된 DispatcherServlet의 <url-pattern>이 '/'와 같이 해당 어플리케이션의 모든 URL로 등록되있기 때문입니다. 만약 특정 URL만 적용하고 싶다면 <url-pattern>의 내용을 바꿔주어 범위를 변경시키주면 됩니다.

② 가로챈 정보를 HandlerMapping에게 보내 해당 요청을 처리할 수 있는 Controller를 찾아냅니다. (스프링은 기본적으로 5가지의 핸들러 매핑을 제공합니다.) 이 부분은 스프링의 디폴트 전략에 의해 BeanNameUrlHandlerMapping과 DefaultAnnotationHandlerMapping이 기본으로 스프링MVC에 탑재되있기 때문에 특별한 경우가 아니라면 따로 설정할 필요가 없습니다.

③ 핸들러매핑이 해당 요청을 처리할 컨트롤러를 찾아냈다면 요청을 컨트롤러에 보내줍니다. 컨트롤러는 사용자가 직접 구현해주는 부분입니다. @MVC는 매우 다양한 코딩방식과 직관적이고 편리한 컨트롤러 작성방법을 제공하므로 이 부분에 대해서는 차후 심층적인 분석하여 자신에게 알맞는 전략을 선정해야 합니다.

④ 컨트롤러를 해당 요청을 처리한 후에 보통 컨트롤러는 요청을 응답받을 View의 이름을 리턴하게 됩니다. (물론 다른 핸들러 매핑 전략을 이용한다면 응답 과정이 다를 수도 있습니다.) 그 때 이 이름을 ViwResolver가 먼저 받아 해당하는 View가 존재하는지 검색합니다.

⑥ 해당 View가 있다면 처리결과를 View에 보낸 후 ⑦ 이 결과를 다시 DispatcherServier에 보낸 후 ⑧ DispatcherServlet은 최종 결과를 클라이언트에 전송합니다.

매우 복잡한 과정으로 처리되긴 하지만 이런 DispatcherServlet 전략에서 사용자가 직접 구현해야할 부분은 컨트롤러와 뷰 밖에 없습니다. 나머지 핸들러 매핑이나 리졸버는 대략적인 흐름만 알고 있다가 나중에 필요할 때 필요한 클래스를 컨텍스트에 등록시키기만 하면 그만입니다.



여기서 하나 문제가 발생했습니다. 디스패처 서블릿이 모든 요청을 컨트롤러에 넘겨주는 방식은 괜찮은데 모든 요청을 처리하다보니 이미지나 HTML 파일을 불러오는 요청마저 전부 컨트롤러로 넘겨버리는 것입니다. 게다가 JSP 안의 자바스크립트나 스타일시트 파일들도 전부 디스패처 서블릿이 요청을 가로채는 바람에 제대로 자원을 불러올 수도 없는 상황입니다. 도대체 어떻게 해야 할까요?


만약 이런 처리를 해주지 않는다면 위와 같은 에러가 로그에 기록될 것입니다. 디스패처 서블릿이 해당 요청을 처리할 컨트롤러를 찾지 못했다는 에러메시지죠. 이 문제를 해결하기 위한 방법이 몇가지 있습니다. 첫번째 방법은 아래와 같이 디스패처 서블릿이 처리할 URL과 자바와 관련없는 리소스들의 영역을 분리시키는 것입니다.

/apps - 클라이언트가 이 URL로 접근하면 앞으로 디스패처 서블릿이 담당
/resources - 이 URL은 디스패처 서블릿이 컨트롤할 수 없는 영역으로 분리

근데 이런 처리방식은 괜찮긴 하지만 상당히 코드가 지저분 해지는데다 form에서 모든 요청을 보낼 때 apps라는 URL을 붙여줘야 하기 때문에 직관적인 설계가 불가능해진다는 점이 있습니다. 두번째로는 진짜 말그대로 모든 요청을 컨트롤러에 등록하는 방법입니다. 허나 이런 방식은 정말 소규모 어플리케이션이 아니라면 절대로 해서는 안될 방법이겠죠.

스프링은 이런 모든 문제에 해결함과 동시에 굉장히 편리한 해결방법을 고안해 냈습니다. 그건은 바로 <mvc:resources />입니다. 만약 이클립스를 통해 저처럼 프로젝트를 Spring Template Project 생성하셨다면 servlet-context.xml에서 다음과 같은 코드를 발견하실 수 있으실 겁니다.

<resources mapping="/resources/-*" location="/resources/" />

이 전략은 다음과 같습니다. 먼저 디스패처 서블릿을 통해 들어온 요청을 처리하는데 만약 디스패처 서블릿이 해당 요청에 대한 컨트롤러가 찾을 수 없다면 2차적으로 위의 설정된 경로를 검색하여 해당 자원을 찾아내게 되는 것이죠. 저같은 경우는 기존의 resources폴더의 Depoloyment Assembly를 변경하여 아래와 같이 설정하는 것으로 문제를 해결했습니다.


만약 이런 비 어플리케이션 자원을 따로 분리하지 않고 어플리케이션 자원과 한데 섞어 작업하신다면 지금부터라도 이렇게 분리해서 작업하시길 권장해 드립니다. 먼저 이런 영역분리는 효율적인 리소스 관리와 확장을 돕기 때문입니다.

현대의 많은 대형 웹서비스들의 비 어플리케이션 자원 URL을 보시면 철저하게 static 성격의 외부 자원들을 분리시켜 사용하고 있습니다. 네이버같은 경우는 http://static.naver.net/란 URL을 통해 이런 자원들을 분리하였으며 페이스북은 http://static.ak.fbcdn.net/과 같은 URL로 분리시켰습니다. 이런 일례를 들어서라도 차후 확장을 위해 비어플리케이션 자원은 반드시 분리해야할 영역이라는 사실을 알려드리고 싶네요.

여기까지 DispatcherServlet에 대한 모든 설명이 끝났습니다. 다음 포스트부터는 슬슬 스프링 시큐리티에 대해 다뤄보려고 하는데 아직 아는 부분이 그렇게 많지 않은데다가 해결되지 않은 의문점이 다소 있어서 바로 포스팅하기는 조금 힘들 것 같네요 ㅠㅠ 문제가 해결되는 즉시 포스팅 하도록 하겠습니다.
.
:
Posted by .07274.
2012. 3. 7. 15:41

[ViewResolver] ViewResolver I.lib()/I.lib(Spring)2012. 3. 7. 15:41

.. .. ..
[펌] : http://linuxp.tistory.com/entry/Spring-Framework%EC%9D%98-ViewResolver

ViewResolver

- 컨트롤러 객체에 의해 반환된 ModelAndView 객체의 View 부분의 논리적 이름에 해당하는 View의 결정을 제공

- JSP, Velocity, FreeMarker, PDF, Microsoft Excel 등 다양한 뷰 지원

- org.springframework.web.servlet.ViewResolver 인터페이스를 구현한 여러가지 ViewResolver 지원


Spring에서 지원하는 View Resolver

1) AbstractCachingViewResolver

- Caching View를 다루는 추상(Abstract) ViewResolver
- 해당 View를 확장(extends)하는 View는 Caching 기능을 제공한다.

2) XmlViewResolver

- Spring의 bean 팩토리처럼 DTD를 가진 XML내 쓰여진 사항을 기초로 동작하는 ViewResolver
- 디폴트 설정 파일은 /WEB-INF/view.xml

3) ResourceBundleViewResolver

- ResourceBundle의 basname 속성에 명시된 bean 정의를 사용하는 ViewResolver
- 다른 ViewResolver와 혼합해서 사용 가능
- 디폴트 설정 파일은 views.properties
- [viewname].class = [viewname].url 형태로 설정

4) UrlBasedViewResolver

- 추가적인 어떤 맵핑 작업을 하지 않고 URL의 상징적인 view 이름을 사용하는 ViewResolver
- 단순 JSP만 사용할 경우 사용이 가능하다.
- 보통 해당 클래스를 확장하여 제공하는 별도의 ViewResolver를 사용한다.

5) InternalResourceViewResolver

- JSP, 서블릿, JstlView, TilesView 같은 View 기능을 제공하는 UrlBasedViewResolver의 편리한 하위 클래스

6) VelocityViewResolver

- Velocity View 기능을 제공하는 UrlBasedViewResolver의 편리한 하위 클래스

7) FreeMarkerViewResolver

- FreeMarker View 기능을 제공하는 UrlBasedViewResolver의 편리한 하위 클래스


ViewResolvers Chaining(혼합 사용)

- 여러개의 ViewResolver가 있을 경우에 혼합해서 사용 가능

- defaultParentView: 상위 ViewResolver의 설정사항을 오버라이드 가능

- order : 여러개의 ViewResolver가 존재할 경우 순서를 결정


UrlBasedViewResolver 사용 예제

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
< /bean>



ResourceBundleViewResolver 사용 예제

<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<!-- view.properties에 기술 -->
<property name="basename" value="views"/>
<!-- views.properties 파일에 정의되지 않을 경우에는 parentView 에 정의된 사항을 따른다 -->
<property name="defaultParentView" value="parentView"/>
< /bean>

bookView.class = org.springframework.web.servlet.view.JstlView
bookView.url = WEB-INF/jsp/book/bookView.jsp

bookEdit.class = org.springframework.web.servlet.view.JstlView
bookEdit.url = WEB-INF/jsp/book/bookEdit.jsp



InternalResourceViewResolver 사용 예제


<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/spring/"/>
<property name="suffix" value=".jsp"/>
< /bean>



XmlViewResolver 사용 예제

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
< /bean>
< bean id="excelViewResolver" class="org.springframework.web.servlet.view.XmlViewResolver">
<property name="order" value="1"/>
<property name="location" value="/WEB-INF/simpleviews.xml"/>
< /bean>

<!-- simpleviews.xml -->
<beans>
<bean name="report" class="org.springframework.example.ReportExcelView"/>
< /beans>
.
:
Posted by .07274.
.. .. ..

[출처] JSON과 JSONP 그리고 CrossDomain Ajax (리눅스) |작성자 비타덴트



JSON 과 JSONP, and CrossDomain Ajax

아마도 웹개발을 하면서 JSON을 모르거나 들어본 적이 없으신 분들 거의 없으실 겁니다.

var trip = {start: "seoul",  end:"pusan"};

trip라는 변수는 전형적인 JSON Object를 가지게 됩니다.
JSON이 빛을 발할 때는 데이터 저장이나, 데이터를 불러오기 할 때
이 형식을 사용할 경우 정의가 명확해지고 다루기가 쉬워진다는 것이죠.

그 옛날에는 XML이라는 할아버지가 계셨으나, 이제는 돌아가시려고 하고,
사람들이 뒷방 늙은이 취급을 해서 인기가 시들시들해졌습니다.
그도 그럴것이 하나의 데이타를 정의하기 위한 부수적인 정의가 너무 많이 들어가는
치명적 단점이 있었죠.

그에 반해 JSON의 형태는 간단합니다.

정의 : 값

의 형태로 그야말로 다이어트 킹의 모습처럼 줄일 것 다 줄인 슬림 형태인 것이죠.

JSON 데이타는 이런식으로 사용 가능합니다.

function showTrip(data){    alert("start:" + data.start + ",  End:" + data.end);}

호출은 다음과 같이 합니다.
showTrip({start : “seoul”, end: “pusan”});

이런식으로 하면 JSON 데이타를 이용할 수 있는데요,
보시기에도 엄청 간편해 보이지 않습니까?

자, 이번에는 동적으로 javascript를 삽입하는 구문을 한번 보겠습니다.

<script type="text/javascript">function showTrip(data){    alert("start:" + data.start + ",  End:" + data.end);}var js_url = “trip.js”;//동적으로 외부 JS를 로딩하는 구문 삽입var script = document.createElement('script');script.setAttribute('src', js_url);document.getElementsByTagName('head')[0].appendChild(script);</script>

이 코드를 보시면,
동적으로


구문이 삽입이 됩니다.
trip.js 파일 안에

showTrip({start : "seoul", end: "pusan"});

이렇게 showTrip이 정의 되어 있다면,
위 구문은 showTrip이 실행 되게 되죠.

JSONP(JSON with Padding)이란 바로 이렇게 trip.js 파일 안쪽의 구문 처럼,
showTrip({start : “seoul”, end: “pusan”})
함수 호출에 둘러싸여있는 JSON 데이터를 말합니다.

따라서 JSONP가 제대로 실행 되기 위해서는 반드시 미리
정의된 함수가(글에선 showTrip) 있어야 가능하겠죠.

자, 그러면 JSON은 알겠고 많이 쓰는데, JSONP는 도데체 언제 쓰이느냐?
이게 질문이죠.

먼저 웹에서는 동일 출처 정책, 한국어로 하면 조금 어려운데 Same Origin Policy, 줄여서
SOP라는게 있습니다.
뭣이냐 하면,

www.greatgrape.co.kr

이라는 사이트가 있다고 합시다.
이 사이트에서

www.daum.com

의 사이트의 내용을 자바스크립트로 동적으로 가지고 오거나
Access하지 못합니다.
이해가 안되신다면 간단한 Jquery 구문으로

$.ajax({    url: "http://www.daum.net,     data: {},    type: "POST",    success: function(html){        $("body").html(html);    }});

위와 같은 Ajax 호출 구문이 greatgrape.co.kr 사이트의
index.html 에 있다고 하면 실행이 될까요 안될까요?

100% 안된다는 말씀입니다.
보안상, 웹 정책상 Same Origin Policy에 걸려서 안됩니다.
이게 풀리면 타사이트의 컨텐츠가 마구마구 도용될 가능성이
있겠죠. 자기의 사이트를 다음 사이트처럼 돌릴 수도~ ㅎㅎㅎ

www.greatgrape.co.krblog.greatgrape.co.kr

섭도메인 형태의 위와 같은 두개의 도메인도 Same Origin Policy에 걸립니다.
Ajax 등으로 데이타 받으려면 안되기는 마찬가지입니다.

여튼 SOP는 이런 겁니다.

근데 다른 사이트의 데이타를 가지고 오고 싶은데
방법이 없냐구요?
있습니다. 그걸 위해 태어난 놈이 바로 JSONP입니다.

Ajax 등으로 호출을 할 경우에
JSONP 형태의 데이타로 리턴을 하고,
리턴된 데이타는 자동으로 실행이 되는 형태죠.
이 Mechanism이 실행되기 위해서는 JSONP 형태의 호출 함수를 제공하는
서버측이나, 요청을 하는 Client 측이나 모두 미리
어떤 함수로 JSON을 감싸서 던져줄 것이다 라는 약속이 되어 있어야 합니다.
그렇게 해야지만, 클라이언트는 서버에서 던지는 JSONP를 받아서 미리 정의되어 있는
함수로 바로 실행을 시키게 되는 것이죠. JQuery에서는 JSONP 호출 구문을
지원합니다.

$.getJSON(url + "&callback=?", function(data){    alert("start:" + data.start + ", end:" + data.end);});

위와 같은 호출 구문을 사용하면 JSONP 데이타를 SOP제한 없이
받으실 수 있습니다. 가령 아래와 같은 주소에서 JSONP 데이타를
넘겨준다고 가정하면,

http://www.greatgrape.co.kr/jsonp/trip?start=seoul&callback=showTrip

호출은

jQuery.getJSON("http://www.greatgrape.co.kr/jsonp/trip?start=seoul&callback=?",function(data) {    alert("start: " + data.start + ", end: " + data.end);});

로 하면 됩니다. 이 때 callback 함수에 함수를 정의하지 않고 물음표로 준 것은
좀더 유연한 JSONP 호출을 만들어 줍니다. 무슨 말이냐 하면,
PHP 단에서 이렇게 짜여져 있다고 합시다.

$jsonData = getDataAsJson($_GET['start']);echo $_GET['callback'] . '(' . $jsonData . ');';// prints: jsonp1232617941775({"start" : "seoul", "end" : "pusan"});

이렇게 JSONP 호출 함수가 자동으로 받은 callback 함수를 그대로 싸서 뿌려주게 되는데요,
$.getJSON에서 ? 물음표로 해주면,
JQuery가 자동으로 인라인 함수의 이름을 받아서 넘겨 줍니다. (여기서는 jsonp1232617941775 )
신경 쓸 필요가 없이 getJSON 안의 인라인 함수가 실행이 되게 되는 것이죠. 참 편하죠~ ^^;
이렇게 JSONP를 사용할 경우 CrossDomain 간의 데이타 전송을 편하게
할 수 있습니다.
그리고 한걸음 더 나아가 자신이 개발한 서버 단의 어플리케이션의 일부 API를
공개하고 싶을 때, JSONP 형태의 요청에 한해서 Open 해줄 수 있습니다.

가령 그레이트그레이프(greatgrape)가 개발한 bikesoop.com 에서
최신 글 리스트를 다른 사이트에서도 요청하면 받을 수 있게 하고싶다… 그러면,

http://www.bikesoop.com/json/getNewestPosts

함수를 만들고, 이 함수에서 아래와 비슷한 형태의 구문을 만들어 주면 됩니다

$postList = array(...);$callbackFunc = $_GET['callback'];$echoStr = json_encode($postList);echo $callbackFunc . "(" . $echoStr . ")";

이처럼 JSONP는 잘 사용하면 SOP에 갇히지 않고 Cross Domain Ajax 를
굉장히 편하게 이용할 수 있습니다.

다만, 데이타를 주고 받을 때 Error Handling이 어렵고,
보안이 필요하거나 인증 정보의 전달에는 약점이 있습니다.
또한 최대 전달 용량이 브라우져마다 제한이 있기 때문에 잘 고려하여
사용하셔야 합니다.

'I.lib() > I.lib(JSTL)' 카테고리의 다른 글

JSTL 의 eq , empty , ne 명령  (2) 2012.05.21
jsp중급_EL,JSTL,커스텀태그  (1) 2010.03.16
JSTL  (0) 2010.02.25
.
:
Posted by .07274.