저의 전공들입니다. 배워도 배워도 끝도 없는 세상. 언제쯤 마무리 지을런지..

오픈 소스, Maven, Hibernate, Spring ,Stripes , Spring, Spring Security, Java,Css,Web 2.0,iBatis,EJB,J2EE,Dojo Toolkit, Prototype.js, Script.aculo.us, jQuery, Trac, Eclipse

 

이젠 저 혼자 아는 것도 외로워서리, Java 개발자라면 Java 개발자다운 세상을 만들어 가보고 싶네요.

궁금한게 있으시다면 질문 언제나 환영입니다. 비록 포스팅은 많이 하지 않지만..;;


Spring

이제 거의 모든 프로젝트에 스프링을 필수 입니다. 물론 스프링 프레임웍이 최고라고 단정할 수 없겠습니다만, 세계적으로 이만한 기반을 쌓아놓았다는 것 자체가 힘입니다.

스프링은 그저 Dependency Injection(Inversion of Control), AOP(Aspect Oriental Programming) 밖에 없습니다. 이2개로 다 해결하죠. 

또한 이놈을 씀으로서 자연스럽게 소스를 구조화시키죠. 스파게티로부터 일단 한단계는 벗어나는겁니다.

묻지 마시고, 일단 이건 시작하십시오.

 

Maven

정말 이놈을 만난 순간 이런 세상에 내가 태어났다는게 참으로 감사했죠. 이놈이 나오기전에 내가 있엇으면 참 얼마나 뻘짓들을 하면서 살았을련지.

Ant 를 대체하며, 태스크 중심이 아닌 프로젝트 빌드에 초점을 맞춘 툴입니다.

전세계의 97% 오픈소스가 Maven 으로 기반으로 되어있다고 합니다.

우리 회사는 오픈 소스 아니니깐 상관없어?

무슨 그런 말씀을..ㅡㅡ;;; Maven 을 도입하고 조금 더 게을러져봅시다. 

Hibernate

오랜 시간동안 하이버네이트를 다뤄왔습니다. 국내에서는 별로 쓰이지도 않음에도 불구하고, 그 매력에 빠져 헤어나오지를 못하네요..^^

이제 하이버네이트에 대한 부담감이 없지만, 초창기에는 국내 커뮤니티가 참으로 작아 힘들었더랬죠.

이젠 제가 여러분에 도움을 드릴 수 있지 않을까 합니다.

 

 

Stripes

스트라이프를 써보셨나요? 들어본 적도 없으시죠?

스트럿츠, 스프링 웹MVC 모두 저리가라입니다. 프레임워크에 학을 때시나요?

현재는 스트라이프가 답일 거라 생각합니다. 이또한 국내 커뮤니티가 전무하군요..

워낙 쉬워서 사실 국내문서화가 얼마나 필요할까 싶기도 합니다만..^^

스트러츠를 갈아버리는 그 날까지 제가 일조를 했으면 하는군요


Prototype.js, jQuery, Dojo Toolkit, Ajax

사실 Ajax 라는 것은 무척쉽습니다. 한줄이면 끝나는 말인걸요.

비동기적으로 서버에 메시지 보내서 받아오는 것

이미 알고 계신가요ㅎㅎ 그저 자바스크립트가 싫을 뿐인거죠? 

이러한 자바스크립트 라이브러리를 사용해 보십시오. 자바 스크립트도 나름 재밌구나라는 생각도 듭니다.

지긋한 스크립트 지옥으로부터 탈출하는 습관을 만들어 줄겁니다.



이 글은 스프링노트에서 작성되었습니다.

실제로 ajax 클라이언트 호출은 사용자가 작성해야한다.

스트라이프가 해주는 일은 ajax 호출에 대하여 적절히 데이타를 넘겨줄 수 있을 뿐이다.

 

Ajax 호출 및 스트라이프로 응답하기

우선 완전한 jsp 페이지를 보자.

<%@page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes.tld"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
  <head>
      <title>My First Ajax Stripe</title>
      <script type="text/javascript"
              src="${pageContext.request.contextPath}/ajax/prototype.js"></script>
      <script type="text/javascript" xml:space="preserve">
          /*
           * Function that uses Prototype to invoke an action of a form. Slurps the values
           * from the form using prototype's 'Form.serialize()' method, and then submits
           * them to the server using prototype's 'Ajax.Updater' which transmits the request
           * and then renders the response text into the named container.
           *
           * NOTE: Requires Prototype version 1.6 or above.
           *
           * @param form reference to the form object being submitted
           * @param event the name of the event to be triggered, or null
           * @param container the name of the HTML container to insert the result into
           */
          function invoke(form, event, container) {
              if (!form.onsubmit) { form.onsubmit = function() { return false } };
              var params = Form.serialize(form, {submit:event});
              new Ajax.Updater(container, form.action, {method:'post', parameters:params});
          }
      </script>
  </head>
  <body>
    <h1>Stripes Ajax Calculator</h1>

    <p>Hi, I'm the Stripes Calculator. I can only do addition. Maybe, some day, a nice programmer
    will come along and teach me how to do other things?</p>

    <stripes:form action="/examples/ajax/Calculator.action">
        <table>
            <tr>
                <td>Number 1:</td>
                <td><stripes:text name="numberOne"/></td>
            </tr>
            <tr>
                <td>Number 2:</td>
                <td><stripes:text name="numberTwo"/></td>
            </tr>
            <tr>
                <td colspan="2">
                    <stripes:submit name="add" value="Add"
                        onclick="invoke(this.form, this.name, 'result');"/>
                    <stripes:submit name="divide" value="Divide"
                        onclick="invoke(this.form, this.name, 'result');"/>
                </td>
            </tr>
            <tr>
                <td>Result:</td>
                <td id="result"></td>
            </tr>
        </table>
    </stripes:form>
  </body>
</html>

이 예제는 숫자 2개를 입력받은 후 ajax 호출로 더한결과와 나눈 결과를 받아서 result 안에 출력하는 소스다. 여기선 프로토타입을 사용했지만, jQuery 를 써도 당연히 무방하다.
중요한 부분은 다음 구문이다.

var params = Form.serialize(form, {submit:event});

액션빈 클래스에 받아들일 메서드명을 submit 파라미터로 집어넣고 있다.
다음은 액션빈 클래스를 보자.

 

public class CalculatorActionBean implements ActionBean, ValidationErrorHandler {
    private ActionBeanContext context;
    @Validate(required=true) private double numberOne;
    @Validate(required=true) private double numberTwo;

    public ActionBeanContext getContext() { return context; }
    public void setContext(ActionBeanContext context) { this.context = context; }

    @DefaultHandler public Resolution add() {
        String result = String.valueOf(numberOne + numberTwo);
        return new StreamingResolution("text", new StringReader(result));
    }

    public Resolution divide() {
        String result = String.valueOf(numberOne / numberTwo);
        return new StreamingResolution("text", new StringReader(result));
    }

    // Standard getter and setter methods
    public double getNumberOne() { return numberOne; }
    public void setNumberOne(double numberOne) { this.numberOne = numberOne; }

    public double getNumberTwo() { return numberTwo; }
    public void setNumberTwo(double numberTwo) { this.numberTwo = numberTwo; }
}


add 메서드와 devide 메서드를 구현한걸 확인할 수 있다. ajax 통신이라고 조금 다르게 사용한것은 Resolution 을 StreamingResolution 을 반환한다는것 뿐이다.
StreamingResolution 을 3개의 생성자를 가지며, 첫 인자는 contentType 을 받아들이는것에 주의한다.

다음은 주로 사용하는 Resolution 에 대한 Java doc 이다.

Constructor Summary
StreamingResolution(String contentType)
Constructor only to be used when subclassing the StreamingResolution (usually using an anonymous inner class.
StreamingResolution(String contentType, InputStream inputStream)
Constructor that builds a StreamingResolution that will stream binary data back to the client and identify the data as being of the specified content type.
StreamingResolution(String contentType, Reader reader)
Constructor that builds a StreamingResolution that will stream character data back to the client and identify the data as being of the specified content type.

StreamingResolution 외에 흥미로운 ajax 관련 Resolution 들이 더 있다.

Constructor Summary
JavaScriptResolution(Object rootObject, Object... objectsToExclude)
Constructs a new JavaScriptResolution that will convert the supplied object to JavaScript.

JavaScriptResolution 은 주어진 인자를 javascript 에서 평가(eval)할 수 있는 형태로 문자열을 만들어 출력한다. 즉 json 형태로 출력한다.

물론 ForwardResolution 을 이용하여 jsp 로 렌더링해도 상관 없다.

Constructor Summary
ForwardResolution(Class<? extends ActionBean> beanType)
Constructs a ForwardResolution that will forward to the URL appropriate for the ActionBean supplied.
ForwardResolution(Class<? extends ActionBean> beanType, String event)
Constructs a ForwardResolution that will forward to the URL appropriate for the ActionBean supplied.
ForwardResolution(String path)
Simple constructor that takes in the path to forward the user to.

이 글은 스프링노트에서 작성되었습니다.

특정 부분에 대해 ajax 로 내용(e.g. HTML 조각)을 받아와 변경하는 방법이다.
prototype.js 를 사용했다. 매우 간단하다.

/**

 * @param container* Ajax 로부터 넘어온 text 결과를 반영할 element

 * @param url* 읽어드릴 url       

 * @param ajax 호출시 넣어줄 option object

 * @author 편현장(slothink)

 */

new Ajax.Updater(container, url, [,options]);


매우 간단하다. 그저 url 읽어와서 container 에 집어넣기만 하면된다.
container 는 dom element 의 id 값을 넣어주도 되고, $() 함수를 이용하여 element 확장한 오브젝트를 넣어줘도 된다.
아래에 예제를 포함했다.

var params = $H();

params.set('code', code);

new Ajax.Updater('detailProperty', '<c:url value="/document/contents.type.tpl" />', {

       method: 'get',

       parameters:params.toQueryString(), // serialize

       });

 



prototype.js 를 이용하여 ajax 기법을 사용하는 방법을 소개해보자 한다.
prototype.js 에선 Ajax.Update 등 여러가지 방법이 있지만, 다 알필요는 없지 않은가?
내가 주로 사용하는 2가지 방법을 설명했다.

참고1. prototpye.js 에선 문서내 id 를 가진 오브젝트를 찾는 $ 유틸리티 함수를 제공한다.
참고2. xml2json 라이브러리는 xml 문서를 json 으로 변환시켜준다. (더 자세히)

1. form 안의 값들을 ajax 에 의해 전송하기
var form = $('categoryForm');
form.action = '<c:url value="/category/update.xml" />';
form.request({
    method: 'post',
    enctype: "application/x-www-form-urlencoded",
    onComplete: function(transport){
        var xml = transport.responseText;
        var json = xml2json.parser(xml);
        if(json.data.result == "true") {
            alert("success"}
        else {
            alert("error");
        }
    }
});


2. 파라미터를 집적 입력하여, 호출하기

var no = $('categoryForm').no.value;
new Ajax.Request('<c:url value="/category/delete.xml" />', {
    parameters: {"no": no},
    requestHeaders: {Accept: 'text/xml'},
    onSuccess: function(transport){
        var xml = transport.responseText;
        var json = xml2json.parser(xml);
        if(json.data.result == "true") {
             alert("삭제하였습니다");
         }else {
             alert("error");
         }
    }
});

+ Recent posts