태원 Wedding Day

지난 25일 태원군도 드디어 장가를 갔습니다.
지금쯤이면 달콤한 신혼의 밤을 보내고 있겠군..

오랜 시간동안 만나왔던 두 사람이니 만큼 행복하게 잘 살아야해..

















2007/03/27 20:48 2007/03/27 20:48
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

It's me...

2007/03/26 19:12

서비 낙서장 , ,



사진 찍는건 좋아하지만 찍히는건 무지 싫어해서 제 모습의 사진이 거의 없는편인데..
사내 출사후 재민군으로부터 받은 제 모습입니다.

한마디로 무책임한 포스팅...인거죠.. ㅎ~
2007/03/26 19:12 2007/03/26 19:12
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. 하하, 셀프샷인줄 알았더니.. 카메라로 가리신건가 보네요^^;;;

  2. ^^;; 예... 그 런것입니다.. ㅎㅎ

Yahoo Buzz Game 에서 자바 IDE 부문에서 넷빈즈가 1위네요..

야후 리서치에 재미있는 조사 결과가 있어서 포스팅 합니다.
불과 일이년전만 해도 자바 개발툴계에 '넷빈즈'라 그러면
'응, 그런 툴도 있지' 수준이었는데 어느새 이클립스 등 여타의 툴과 같은(혹은 이상의)
관심을 받고 있네요.
백번 양보해서 아래 조사결과가 무척 부정확 하다고 해도 여타의 IDE를 따돌리고
이클립스와 어깨를 견줄 IDE로 성장했다는 사실은 변함 없어 보입니다.
넷빈즈 유저로 기쁜일이군요..


        NETBEANS (16.72)
        ECLIPSE (11.58)
        EMACS (9.99)
        JBUILDER (9.62)
        JDEVELOPER (6.66)
        IDEA (5.31)
        WEBLOGIC (4.63)


원문은
http://buzz.research.yahoo.com/bk/market/market.html?_mid=55312

을 보시면 됩니다.
2007/03/26 15:24 2007/03/26 15:24
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. Blog Icon
    궁금이

    혹시 시중에 넷빈즈 관련 서적이 있나여??

  2. 원서로 두권정도 출간된 적이 있는데요..
    그게 다 넷빈즈 3.x대 서적이라 지금은 거의 도움이 안될겁니다.
    지금 나와있는 서적은 저도 본적이 없구요..
    지금은 netbeans.org에서 정보를 얻으시는게 가장 빠른길인듯 합니다.

회사 동료 아들 돌

지난 주말 재헌이의 돌 잔치가 있었습니다.

공교롭게도 '찰나'출사날과 겹치긴 했지만 돌행사가 저녁시간에 잡혀 있었기 때문에
출사 후 행사에 함께 할 수 있었습니다.
재헌이 녀석 절 몇번 봐서인지 이젠 낯을 안가리는게 어찌나 귀여운지..
준호야 애 잘 키우고 재헌이 앞날에도 항상 행복한 일만 가득하길 바란다.









언제나 행복한 가정 되길 바랍니다.
2007/03/25 01:19 2007/03/25 01:19
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

간만에 동기 모임

지금쯤 태원이 자식 정신 없겠구나..
얘들아 내일 식장에서 보자..










2007/03/24 17:01 2007/03/24 17:01
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

Gallery 2.2 (Double Double) Released!

이전 포스팅에서도 잠깐 언급했던 설치형 갤러리인 Gallery2
3월17일자로 근 일여년만에 2.1.2에서  2.2로 업버전을 릴리즈 했다.

사이트에서 소개하고 있는 Gallery2의 새로운 기능은

New Features of Gallery 2.2 Include
:

  1. Downloadable Plugins.
    • This feature allows you to download and install Modules and Themes directly via the Site Admin interface. You can select from different sets of plugins (officially released plugins, experimental plugins under development and plugins provided by the Gallery community). This makes it very easy to stay up to date with the latest changes.
  2. Added support for themes to display dynamic albums.
    • New Keyword Album module makes use of this feature to show albums based on a search of item keywords.
    • New Dynamic Albums module shows albums of newest, most viewed or even random items.
    • Ratings module has a new view to display highly rated items from across the Gallery.
  3. Watermarking changes
    • Edit Album now has a Watermark tab where watermarks may be added or removed from an entire album, optionally including subalbums too.
    • Edit Watermark now has an option to replace a watermark image and apply the new image everywhere the old was one used.
    • New option to always use a single watermark and give users no watermarking options. Only Site Admins can change/remove existing watermarks.
    • New option to turn off the ability for users to upload their own watermark images.
  4. New themes: Carbon and Ajaxian
  5. New WebDAV module to mount Gallery as network device on your computer. This allows you to easily manage your Gallery with any WebDAV client like Windows Explorer.
  6. New module to send Ecards.
  7. New Digibug module for prints from digibug.com.
  8. Added support for Flash Video and Windows ASF video.
  9. Photo auto-rotation based on camera sensors or on settings from other applications.

...and many more!

란다..

와우~ 바로 업그레이드를 단행했다..
2.1.2버전까지 지원되지 않아 많은 갤러리2 유저가 원했던 일괄 워터마크 적용
기능이 가장 마음에 든다.
업그레이드를 단행 하면서 테마도 럭셔리한 PGtheme로 교체하고..
몇가지 손을 더 봐야 하지만... 좀 느긋이 진행 해야겠다..

2007/03/23 14:30 2007/03/23 14:30
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. 저도 최근에 2.2로 업그레이드를 단행했습니다.

    gallery2 짱이죠...^^

    저 같은 경우엔 gallery를 쓰는 이유가.
    .사진을 쉽게 온라인으로 올릴 수 있다는 점
    .사진을 일정 크기로 자동 변환해준다는 점.
    .사진의 링크 주소를 쉽게 만들어 준다는 점.
    (이건 안 쓰시는것 같던데.. URL Rewrite 한번 사용해 보세요. 주소를 http://photo.nanbean.net/1616-1/300.jpg 이런식으로 만들어줍니다.)
    입니다.

    정말 잘만든 프로그램 같습니다.
    조금 느리다는게 조금 걸리는데..
    온라인으로 사진을 관리하는데는 이만한 프로그램이 없는것 같습니다.^^

  2. kldp쪽 보니 Gallery2에대한 얘기가 심심찮게 올라오더라구요..
    저역시 Rewrite 모듈을 활성화 할까 만까로 약간 고민 중이랍니다. ^^

와~~ 붙였다...

내 계정에는 블로그와 이미지 갤러리가 설치되어 있다..

블로그는 보시는 바와같이 태터툴스 1.1이고 갤러리http://gallery.menalto.com/ 에서
Open Source로 배포하고있는 Gallery2를 이용하고 있다.

국내는 워낙 제로보드의 갤러리가 많이 퍼져있다보니 다른 갤러리를 사용하고 있는걸
보기가 힘들다..

내가 이 Gallery2를 알게 된것도 꽤 오래전에 wordpress 로 블로그를 개설 했을 때로,
wordpress와 연동 할 만한 갤러리 솔루션을 찾다가 알게된게 계기가 되어 지금까지
사용하고 있다. 국내에서는 거의 사용자가 없을지도 모른다는 유니크한 점도 마음에 들고
사진을 웹에 게시하기위한 목적으로 만들어진 만큼 편리하고 재미있는 기능이 많아서
매력적인 프로그램이다.

태터로 블로그를 연지 얼마 되지 않은 상태에서 이 블로그 메인화면에 Gallery2와 연동하여
갤러리에 올린 사진을 랜덤으로 뿌려 줄 수 없을지 고민하다 어제 아이디어가 떠올랐고
오늘 코드를 짜고 적용 해 보니 생각  만큼 잘 작동하고 있다. ^^

솔직히 자바로 밥벌어먹고 살고 있긴하지만 내게 php는 왠지 외계어 같기도 하고
가까이하기엔 좀 먼 당신과 같은 존재 였지만.. '궁하면 통'하고 '목마른 놈이 우물 판다' 하지
않았던가.. 태터사이트의 플러그인 개발참고문서와 다른 플러그인의 동작방식을 뜯어보고
설렁설렁 만들었는데 잘 작동 해 주고 있어서 기분이 좋다 ^^
2007/03/22 22:59 2007/03/22 22:59
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. php.. 외계어.. 공감합니다 ㅎㅎ

  2. 오호~ 멋진데요?^^

    초면에 무리한 부탁인것 같기도 하지만,
    저도 혹시 소스 좀 얻을 수 있을까요?

    혹시 가능하다면 nanbean앳nanbean점net으로 보내주시면 감사히 쓰겠습니다..^^

  3. 일단 플러그인으로 제작은 했는데..
    제 환경에 맞춰 만들다보니
    옵션으로 설정을 할 수 있는 부분이 없습니다.
    몇가지 옵션을 적용 해서 태터 플러그인으로 공개 하겠습니다.

봄이 찾아드는 길목에서

지난 주말 회사 동료들과 함께 삼청동으로 나들이를 나갔더랬습니다.
좀더 날이 풀리고 꽃이 피기시작하면 더 예쁘게 물들지 않을까 하는 생각을
했더랬습니다.



아주 약간 쌀쌀하긴 했지만 봄은 우리 코앞에 있었습니다.





책읽는 사람의 얼굴은 다르다고 합니다.. 독서로 춘곤증을 날려 볼까요..





세린양과 첫 대면인데.. 뭔가 불만이 있는듯 하군요..
담엔 아저씨 한테도 미소를 보여 줄 수 있겠지?





그분의 뒷모습입니다..





앗! 도촬 중 딱 걸렸습니다. 무방비상태로 당해도 미모는 여전 하시군요.. ^^







직장 상사와 그분 이십니다.. 봄날의 연인. 아름답지 않으세요?





이번 나들이를 함께한 사우입니다.



2007/03/22 10:03 2007/03/22 10:03
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. 직장동료들과의 출사라.. 부럽네요^^;;;
    그분이라고 해서 '그녀'인줄 알았는데.. 직장상사분의 '그녀'신가 보네요 ㅎㅎ

  2. 예.. 사내 사진 동호회가 있어서 한달에 한번 출사를 나갑니다.(늘 모여 놀기만 하지만요..^^)
    저도 얼른 저의 '그분'을 찾아야 겠습니다.

  3. JRVg3n subpages-and-index-page_06.07.12;3;8

Web Services (JAX-WS) in Java EE 5

Java API for XML Web Services (JAX-WS) 2.0, JSR 224, is an important part of the Java EE 5 platform. A follow-on release of Java API for XML-based RPC 1.1(JAX-RPC), JAX-WS simplifies the task of developing web services using Java technology. It addresses some of the issues in JAX-RPC 1.1 by providing support for multiple protocols such as SOAP 1.1, SOAP 1.2, XML, and by providing a facility for supporting additional protocols along with HTTP. JAX-WS uses JAXB 2.0 for data binding and supports customizations to control generated service endpoint interfaces. With its support for annotations, JAX-WS simplifies web service development and reduces the size of runtime JAR files.

This document takes you through the basics of using the IDE to develop a JAX-WS web service and to consume it in three different clients—either a Java class in a Java SE application, or a servlet or JSP page in a web application. The three clients that you create in this document are separate applications, all consuming the same web service.

Expected duration: 25 minutes

Software Needed for the Tutorial

Before you begin, you need to install the following software on your computer:

  • NetBeans IDE 5.5 (download).
  • Java Standard Development Kit (JDK) version 5.0 or version 6.0 (download).
  • Sun Java System Application Server 9.0 (if not bundled with your NetBeans IDE installation, download and install it separately).

Tutorial Exercises

Installing and Configuring the Tutorial Environment

If you have not registered an instance of the Sun Java System Application Server 9.0, you must do so before you can begin developing Java EE 5 applications:

  1. Choose Tools > Server Manager from the main window.
  2. Click Add Server. Select Sun Java System Application Server and give a name to the instance. Then click Next.
  3. Specify the server information, the location of the local instance of the application server, and the domain to which you want to deploy.
  4. Click Finish.

Note: If you want to deploy to the Tomcat Web Server, you can do so, except that, since it only has a web container, you should create a web application, not an EJB module, in the next section. JAX-WS web services, unlike JSR-109 web services, can deploy successfully to the Tomcat web container.

Creating a Web Service

The goal of this exercise is to create a project appropriate to the deployment container that you decide to use. Once you have a project, you will create a web service in it.

Choosing a Container

You can either deploy your web service in a web container or in an EJB container. This depends on implementation choices. For example, if you plan to deploy to the Tomcat Web Server, which only has a web container, you should choose to create a web application, and not an EJB module.

  1. Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Web category or EJB Module from the Enterprise category.
  2. Name the project CalculatorWSApplication.
  3. Depending on the deployment server that you want to use, do the following:
    • For the Sun Java System Application Server, set the J2EE Version to Java EE 5.
    • For the Tomcat Web Server, unselect the Set Source Level to 1.4 checkbox.
  4. Click Finish.

Creating a Web Service from a Java Class

  1. Right-click the CalculatorWSApplication node and choose New > Web Service.
  2. Name the web service CalculatorWS, type org.me.calculator in Package, and click Finish.

    The Projects window displays the new web service. For example, for web applications the Projects window now looks as follows:

    Projects window displaying the web service

    The IDE automatically creates the deployment descriptors required for the server, if any. For the Sun Java System Application Server, no deployment descriptor is needed. For web services deployed to the Tomcat Web Server, sun-jaxws.xml and a WSServlet item in web.xml are added.

Summary

In this exercise, you created a NetBeans project and set up the web service.

Coding the Web Service

The goal of this exercise is to do something meaningful with the files and code that the IDE has generated for you. You will add an operation that will add two numbers received from a client.

Adding Business Logic to the Web Service

  1. Expand the Web Services node and double-click the CalculatorWS node. The web service opens in the Source Editor. Note that an operation exists in the code already. It is commented out. Here, we create a new operation from scratch. Another way of creating the operation would be to remove the lines that comment out the code.
  2. Right-click within the body of the class, either above or below the code that is commented out, and choose Web Service > Add Operation.
  3. In the upper part of the Add Operation dialog box, type add in Name and choose int from the Return Type drop-down list.
  4. In the lower part of the Add Operation dialog box, click Add and create a parameter of type int named i. Click OK.
  5. Click Add again and create a parameter of type int called j.
  6. Click OK at the bottom of the Add Operation dialog box. Notice that a skeleton for the add method has been added to the Source Editor:
        
    1. @WebMethod
    2.     public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
    3.         // TODO implement operation
    4.         return 0;
    5.     }

  7. Change the add method to the following (changes are in bold):
       
    1. @WebMethod
    2.     public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
    3.         int k = i + j;
    4.         return k;
    5.     }


Summary

In this exercise, you added code to the web service.

Deploying and Testing the Web Service

When you deploy a web service to a web container, the IDE lets you test the web service to see if it functions as you expect. The Tester application, provided by the Sun Java System Application Server, is integrated into the IDE for this purpose. For the Tomcat Web Server, there is a similar tool. However, while the Sun Java System Application Server's Tester page lets you enter values and test them, the Tomcat Web Server does not. In the latter case, you can only see that the web service is deployed, you cannot test the values. No facility for testing whether an EJB module is deployed successfully is currently available.

To test successful deployment to a web container:

  1. Right-click the project node, choose Properties, and click Run. Depending on the deployment server that you want to use, do the following:
    • For the Sun Java System Application Server, type /CalculatorWSService?Tester in the Relative URL field.
    • For the Tomcat Web Server, type /CalculatorWS?Tester in the Relative URL field.

    Note: Since the result of a deployed EJB module is not displayed in a browser, you cannot take the step above if you are working with an EJB module.

  2. Right-click the project node and choose Run Project.

    The IDE starts the application server, builds the application, and opens the tester page in your browser, if you deployed a web application to the Sun Java System Application Server. For the Tomcat Web Server and deployment of EJB modules, the situation is different:

    • If you deployed to the Tomcat Web Server, you will see the following instead, which indicates that you have successfully deployed your web service:

      Web page displayed when web service was successfully deployed to Tomcat server

    • If you deployed an EJB module, successful deployment is indicated by the following messages in the Output window:
          Deployment of application CalculatorWSApplication  completed successfully
          Enable of CalculatorWSApplication in target server   completed successfully
          Enable of application in all targets  completed successfully
          All operations completed successfully
          run-deploy:
          run:
          BUILD SUCCESSFUL
    • If you deployed to the Sun Java System Application Server, type two numbers in the tester page, as shown below:

      Web service tester page when service successfully deployed to Sun Java System Application Server

      The sum of the two numbers is displayed:

      Web page showing result of web service test

Summary

In this exercise, you deployed a web service and tested it.

Consuming the Web Service

Now that we have deployed our web service, we need to create a client to make use of the web service's add method. Here, we create three clients— a Java class in a Java SE application, a servlet, and a JSP page in a web application.

Client 1: Java Class in Java SE Application

  1. Choose File > New Project (Ctrl-Shift-N). Select Java Application from the General category. Name the project CalculatorWS_Client_Application.

    Note: At the time of writing, issue Issue 10 was unresolved; therefore, you must create your web service client in a project folder that does not contain spaces in its path. For example, the path should not be "C:\Documents and Settings\...".

    Click Finish.
  2. Right-click the CalculatorWS_Client_Application node and choose New > Web Service Client.
  3. In Project, click Browse. Browse to the web service that you want to consume. When you have selected the web service, click OK.
  4. Type org.me.calculator.client in Package, and click Finish.

    The Projects window displays the new web service client:

    New web service client in Java SE application displayed in the Projects window

  5. Double-click Main.java so that it opens in the Source Editor. Delete the TODO comment and right-click in that line. Choose Web Service Client Resources > Call Web Service Operation.
  6. Browse to the Add operation and click OK.
  7. Change the line that is underlined in red to the following:
        System.out.println("Sum: " + port.add(3,4));
  8. Right-click the project node and choose Run Project.

    The Output window should now show the following:

        compile:
        run:
        Sum: 7
            BUILD SUCCESSFUL (total time: 1 second)

Client 2: Servlet in Web Application

  1. Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Web category. Name the project CalculatorWSServletClient.

    Note: At the time of writing, issue Issue 10 was unresolved; therefore, you must create your web service client in a project folder that does not contain spaces in its path. For example, the path should not be "C:\Documents and Settings\...".

    Click Finish.

  2. Right-click the CalculatorWSServletClient node and choose New > Web Service Client.
  3. In Project, click Browse. Browse to the web service that you want to consume. When you have selected the web service, click OK.
  4. Type org.me.calculator.client in Package, and click Finish.

    The Projects window displays the new web service client:

    New web service client in servlet displayed in the Projects window

  5. Right-click the project node and choose New > Servlet. Name the servlet ClientServlet and house it in a package called org.me.calculator.client. Click Finish. To make the servlet the entry point to your application, right-click the project node, choose Properties, click Run, and type /ClientServlet in Relative URL. Click OK.
  6. In the Source Editor, remove the line that comments out the body of the processRequest method. This is the line that starts the section that comments out the code:
        /* TODO output your page here

    Next, delete the line that ends the section of commented out code:

        */

    Add some empty lines after this line:

        out.println("<h1>Servlet ClientServlet at " + request.getContextPath () + "</h1>");

    Now, right-click in one of the empty lines that you added. Choose Web Service Client Resources > Call Web Service Operation. The Select Operation to Invoke dialog box appears.

  7. Browse to the add operation and click OK.

    The processRequest method now looks as follows (the added code is in bold below):


    1.     protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    2.     throws ServletException, IOException {
    3.         response.setContentType("text/html;charset=UTF-8");
    4.         PrintWriter out = response.getWriter();
    5.         out.println("<html>");
    6.         out.println("<head>");
    7.         out.println("<title>Servlet ClientServlet</title>");
    8.         out.println("</head>");
    9.         out.println("<body>");
    10.         out.println("<h1>Servlet ClientServlet at " + request.getContextPath () + "</h1>");
    11.  
    12.         try { // Call Web Service Operation
    13.             org.me.calculator.client.CalculatorWSService service = new org.me.calculator.client.CalculatorWSService();
    14.             org.me.calculator.client.CalculatorWS port = service.getCalculatorWSPort();
    15.             // TODO initialize WS operation arguments here
    16.             int arg0 = 0;
    17.             int arg1 = 0;
    18.             // TODO process result here
    19.             int result = port.add(arg0, arg1);
    20.             System.out.println("Result = "+result);
    21.         } catch (Exception ex) {
    22.             // TODO handle custom exceptions here
    23.         }
    24.  
    25.         out.println("</body>");
    26.         out.println("</html>");
    27.         out.close();
    28.     }

    Change the value for arg0 and arg1 to other numbers, such as 3 and 4.

    Change the System.out.println statement to out.println.

    Add a line that prints out an exception, if an exception is thrown.

    The try/catch block should now look as follows (new and changed lines are highlighted):


    1.     try { // Call Web Service Operation
    2.         org.me.calculator.client.CalculatorWSService service = new org.me.calculator.client.CalculatorWSService();
    3.         org.me.calculator.client.CalculatorWSApplication port = service.getCalculatorWSApplicationPort();
    4.         // TODO initialize WS operation arguments here
    5.         int arg0 = 3;
    6.         int arg1 = 4;
    7.         // TODO process result here
    8.         int result = port.add(arg0, arg1);
    9.         out.println("<p>Result: " + result);
    10.     } catch (Exception ex) {
    11.         out.println("<p>Exception: " + ex);
    12.     }

  8. Right-click the project node and choose Run Project.

    The server starts, if it wasn't running already; the application is built and deployed, and the browser opens, displaying the calculation result.

Client 3: JSP Page in Web Application

  1. Choose File > New Project (Ctrl-Shift-N). Select Web Application from the Web category. Name the project CalculatorWSJSPClient.

    Note: At the time of writing, issue Issue 10 was unresolved; therefore, you must create your web service client in a project folder that does not contain spaces in its path. For example, the path should not be "C:\Documents and Settings\...".

    Click Finish.

  2. Right-click the CalculatorWSJSPClient node and choose New > Web Service Client.
  3. In Project, click Browse. Browse to the web service that you want to consume. When you have selected the web service, click OK.
  4. Type org.me.calculator.client in Package, and click Finish.

    The Projects window displays the new web service client.

  5. In the Web Pages folder, double-click index.jsp so that it opens in the Source Editor.
  6. In the Web Service References node, expand the node that represents the web service. The add operation, which you want to invoke from the client, is now exposed.
  7. Drag the add operation to the client's index.jsp page, and drop it below the H1 tags. The code for invoking the service's operation is now generated in the index.jsp page.

    Change the value for arg0 and arg1 to other numbers, such as 3 and 4.

  8. Right-click the project node and choose Run Project.

    The server starts, if it wasn't running already; the application is built and deployed, and the browser opens, displaying the calculation result:

    JSP page showing result 

    @http://www.netbeans.org/kb/55/websvc-jax-ws.html
2007/03/21 15:36 2007/03/21 15:36
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

Creating a Simple SOA Project with NetBeans Enterprise Pack

Contents

Overview

You will be creating a simple SOA project. You will add a WSDL file to your BPEL Module project. You use the Partner view to add the messages, partner link type, port type, and operation. Then you will create a composite application project and use the CASA editor to modify the project configuration. This tutorial also illustrates a basic scenario of how a File Binding Component can be used in a composite application.

Software Needed for this Tutorial

Before you begin, you must install the following software on your computer:

  • NetBeans IDE 5.5.1 Beta with NetBeans Enterprise Pack 5.5.1 Beta

 

Configuring the Tutorial Environment

Before you can deploy your application, the Sun Java System Application Server and JBI runtime must be configured correctly and running.

To configure the tutorial environment:

  1. Click the Runtime tab to open the Runtime window.
  2. In the Runtime window, expand the Servers node.
  3. If the Servers node already contains a Sun Java System Application Server 9 node, then go to step 5.
  4. If the Servers node does not contain a Sun Java System Application Server 9 node, then do the following to add an application server:
    1. Right-click the Servers node and choose Add Server from the pop-up menu.
      The Add Server Instance dialog box opens.
    2. In the Choose Server page, from the Server drop-down list, select Sun Java System Application Server.
    3. (Optional) In the Name field, accept the default value or type the name you want to use to identify the server in the IDE.
    4. Click Next.
      The Platform Location Folder page opens.
    5. In the Platform Location field, use the Browse button to navigate to and select the Application Server installation location.
      If you accepted the default values during the installation, the location is C:\Sun\Appserver .
    6. Select the Register Local Default Domain radio button.
    7. Click Next.
    8. Supply the user name and password for the domain's administrator.
      If you accepted the default values during the installation, the user name is admin and the password is adminadmin .
    9. Click Finish.
  5. In the Runtime window, right-click the Sun Java System Application Server 9 node and choose Start.
    If the Start option is not available, the server is already running and you can skip the next step.
  6. Wait until the following message appears in the Output window:
    Application server startup complete.
    When the server is running, the IDE displays a green arrow badge on the Sun Java System Application Server 9 node.

Creating the Project

In this section, you create a BPEL Module project called HelloSample .

To create the HelloSample project:

  1. From the IDE's main menu, choose File > New Project.
    The New Project wizard opens.
  2. In the Categories list, select the Service Oriented Architecture node.
  3. In the Projects list, select the BPEL Module node.
  4. Click Next.
  5. In the Project Name field, type HelloSample .
  6. (Optional) In the Project Location field, use the Browse button to navigate to and select a different folder where the IDE will store the project files.
  7. Click Finish.
    The Projects window now contains a project node for a BPEL Module project called HelloSample .

Creating the WSDL Document

In this section, you add a WSDL file to your BPEL Module project and then use Partner view to configure the components of the WSDL Document.

To create HelloSample.wsdl :

  1. In the Projects window, expand the HelloSample project node, then right-click the Process Files node and choose New > WSDL Document.
    The New WSDL Document wizard opens.
  2. In the File Name field, type HelloSample .
  3. Click Finish.
  4. The IDE does the following:
    • Creates HelloSample.wsdl node under the Process Files.
    • Opens the HelloSample.wsdl in the source editor.
      The Source Editor contains 3 tabs for the WSDL file, Source, WSDL, and Partner, with the WSDL view opened.
    • Opens the Properties window. If the Properties window is not visible, choose Window > Properties.
  5. In the WSDL view, click the Partner button to open the Partner view of the WSDL editor.
    The IDE opens the WSDL Palette. If the Palette window is not visible, choose Window > Palette from the main menu.
    You can create the SequenceDiagram in this view.

To add Messages :

  1. In the Palette of the Partner view select the Message icon.
  2. Drag your selection to the WSDL Partner View design area, below the Messages.
    The IDE adds a Message and the name of the new Message is ( Messages1 ).
  3. Click the down arrow to expand the new message. If the arrow is up, the message is already expanded.
    The design area now shows Part Name and Part element or Type columns.
  4. In the Message Part Name column, double-click the default value (part1) to make the field editable.
  5. Type inputType and press Enter. If the Message1 is collapsed, click the down arrow to expand the new message
  6. In the Part Element Or Type column, make sure the default type is xsd:string
    If the type is not string then click the ellipsis button and select BuiltIn Schema Types > Built-in Types > String
  7. Repeat step 1-6 and for the Message Part Name, enter resultType.

To add PartnerLinkType :

  1. In the Palette of the Partner view select the PartnerLinkType icon.
  2. Drag your selection to the WSDL Partner View design area, below the PartnerLinkTypes(0).
    The IDE adds a PartnerLink and is ready to create new Roles and Port Types. Roles and PortTypes are drawn as dotted vertical lines( Lifeline) with the External names showing at the top.
  3. For Port Types double click the green rectangle under the role1 node.
  4. Click Enter. The new portType1 is assigned.
  5. In the Palette of the Partner view select the Request-Response icon.
  6. Drag your selection to the WSDL Partner View design area, below the portType1.
    The new Operation, operation1 is added.
  7. Under operation1, double click the upper message arrow where it says <No Message Selected> and select tns:message1.
  8. Repeat step 7and 8 for the lower message arrow and select tns:message2.

Creating the BPEL Process

To create HelloSample.bpel :

  1. In the Projects window, expand the HelloSample project node, then right-click the Process Files node and choose New > BPEL Process.
    The New BPEL Process wizard opens.
  2. In the File Name field, type HelloSample.
  3. Click Finish.
    The Sample.bpel is created

To add a partner link:

  1. In the Web Service section of the Palette, select the Partner Link icon and drag your selection to the design area.
    The Create New Partnerlink1Property Editor opens.
  2. Accept the defaults and click OK.

To add a Receive activity:

  1. In the Web Service section of the Palette, select the Receive icon and drag your selection to the design area between the Process Start activity and the Process End activity.
    The IDE provides you with visual clues to show you where you can drop the selection.
    This action places a Receive activity called Receive1 in the Design view.
  2. Double-click the Receive1 activity.
    The Receive1 [Receive] - Property Editor opens.
  3. From the Partner Link drop-down list, select PartnerLink1.
    The IDE fills in the Operation field.
  4. Create a new input variable by doing the following:
    1. Click the Create button next to the Input Variable field.
      The New Input Variable dialog box opens.
    2. Change the value in the Name field to inputVar .
    3. Click OK.
  5. Click OK to close the Receive1 [Receive] - Property Editor.
    The Receive activity is now labeled start in the Design view.

To add a Reply activity:

  1. In the Web Service section of the Palette, select the Reply icon and drag your selection to the design area between the Receive1 activity and the Process End activity.
    The IDE provides you with visual clues to show you where you can drop the selection.
    This action places a Reply activity called Reply1 in the Design view.
  2. Double-click the Reply1 activity.
    The Reply1 [Reply] - Property Editor opens.
  3. From the Partner Link drop-down list, select PartnerLink1.
    The IDE fills in the Operation field.
  4. Create a new output variable by doing the following:
    1. Make sure the Normal Response radio button is selected.
    2. Click the Create button next to the Output Variable field.
      The New Output Variable dialog box opens.
    3. Change the value in the Name field to outputVar .
    4. Click OK.
  5. Click OK to close the Reply1 [Reply] - Property Editor.
    The Reply activity is now labeled end in the Design view.

To add an Assign activity:

  1. In the Basic Activities section of the Palette, select the Assign icon and drag your selection to the design area between the Receive1 activity and the Reply1 activity.
    This action places an Assign activity called Assign1 in the Design view.
  2. Select the Assign1 activity.
  3. If the BPEL Mapper window is not visible, choose Window > BPEL Mapper from the main menu.
  4. In the left pane of the BPEL Mapper, under Variables, expand the inputVar node.
    inputType appears under inputVar .
  5. In the right pane of the BPEL Mapper, under Variables, expand the outputVar node.
    resultType appears under outputVar .
  6. Drag inputType from the left pane of the BPEL Mapper to the resultType node in the right pane of the BPEL Mapper.
    This assignment copies the input statement into the output.
  7. To save your changes, in the Projects window, select the SynchronousSample project node, and from the IDE's main menu, choose File > Save All.

Creating the Composite Application

Before you deploy the BPEL Module project, you must add the JBI module to the deployment project. Deploying the project makes the service assembly available to the application server, thus allowing its service units to be run.

To create the Composite Application project:

  1. From the IDE's main menu, choose File > New Project.
    The New Project wizard opens.
  2. In the Categories list, select the Service Oriented Architecture node.
  3. In the Projects list, select the Composite Application node.
  4. Click Next.
  5. In the Project Name field, type SampleCompositeApp .
  6. Click Finish.
    The Projects window now contains a project node for a Composite Application project called SampleCompositeApp .

Using the CASA Editor

To use the CASA editor to modify the project configuration:

  1. Right click on the SampleCompositeApp project and select Edit Project.
  2. Click on the HelloSample node and drag-n-drop it onto the JBI module area.



  3. Click the build button on CASA toolbar to build the bpel project.

To create the WSDL endpoint:

  1. Click on the "file" palette item on the WSDL Bindings category in the Palette panel.
  2. Drag-n-drop it to the WSDL Ports area in the CASA editor.
  3. A new "casasport1" WSDL endpoint is added.

To createa new connection:

  1. Click on the consume endpoint of the new port.
  2. Drag it to the erole1_myRole to create a new connection.

To Check auto-generated WSDL endpoint properties

  1. In the Navigator panel, expand the WSDL Ports node.
  2. Expand casaPort1 > casaBinding1 > operation1 > input1.
  3. Select file:message.
  4. In the Properties window, assign use='literal" , pollingIntervl=5000 and fileName=input.txt.
  5. Click on WSDL Ports area in the CASA editor to open the Navigator panel again.
  6. In the Navigator panel, expand WSDL Ports > casaPort1 > casaBinding1 > operation1 > output1.
  7. Select file:message.
  8. In the Properties window, assign fileName=output.txt.
  9. Click on WSDL Ports area in the CASA editor to open the Navigator panel.
  10. In the Navigator panel, expand the WSDL Ports node.
  11. Expand casaPort1 ->casaPort1 to select the file:address node.
  12. In the Properties window, in the fileDirectory, replace C:/Temp with the string c:/temp.
  13. Click Ok.



Deploying and Testing the SampleCompositeApp

To deploy the Composite Application:

  1. Right-click the SampleCompositeApp project node and choose Deploy Project.
    If a message similar to the following message appears in the Output window, then the deployment has succeeded:
    BUILD SUCCESSFUL (total time: 11 seconds)

To test the SampleCompositeApp:

  1. Create the input.txt file in c:/temp folder and edit the file to content 'Hello World!!'.
  2. input.txt will be renamed to input.txt_processed.
  3. output.txt will be created in the same folder with the same content 'Hello World!!'.


@http://blogs.sun.com/barkodar/resource/HelloSample.html

2007/03/21 15:16 2007/03/21 15:16
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

Tomcat/JSP와 한글 문제...

◎ Tomcat 4.x
단순히 JSP 혹은 서블릿의 최 상단에 request.setCharacterEncoding("euc-kr");을 하면 된다.
GET과 POST 방식에 상관없이 인코딩을 해준다.


◎ Tomcat 5.x
POST 방식은 request.setCharacterEncoding("euc-kr");로 계속 하면된다.
하지만 GET 방식은 server.xml의 설정 부분을 바꿔줘야만 한다.

Server.xml 보기



위에서 URIEncoding="euc-kr" 부분이다.그리고 아래의 port="8009" 부분은 mod_jk를 이용해서 Apache와 Tomcat 5.x 를 연동할 때 URIEncoding="euc-kr"을 지정할 필요가 있다.

URIEncoding으로 지정할 경우, 만약 웹 어플리케이션이 EUC-KR과 UTF-8을 각 요청 별로 따로 처리할 필요가 있을경우 그에 대응할 수 없다. 대신, useBodyEncodingForURI="true"을 사용하면 Tomcat 4.x와 동일한 방식으로 즉, request.setCharacterEncoding() 값에 따라 GET/POST 방식 모두를 처리할 수도 있다. (참조 : http://tomcat.apache.org/tomcat-5.5-doc/config/http.html)

결론적으로 Tomcat 4.x와 Tomcat 5.x 는 모두 request.setCharacterEncoding()이 필요하다는 사실에는 변함이 없다.
2007/03/20 11:38 2007/03/20 11:38
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

QUEUE와 DELAYED 프로세싱

J2SE 5.0 출시에는 새로운 top-level Queue 인터페이스가 Collections Framework에 추가되어 Map, List, Set 인터페이스와 어우러진다. 일반적으로 queue는 먼저 들어온 것이 먼저 나가는 데이터 스트럭쳐이지만 priority queue같은 몇몇 구현들에서는 queue 뒤에 엘리먼트가 첨부되지 않는다. 이 queue와 FIFO(first in, first out)구조에 관한 얘기는 은행에서의 대기선에 비유할 수 있겠다. 은행직원은 고객이 대기선에 있는지 확인한 후 대기선의 첫번째 손님을 맞이하여 손님이 원하는 거래를 처리한다. 그리고 그 손님은 이제 대기선에서 제외된다.

J2SE 5.0에는 Queue 인터페이스와 함께 몇 가지 새로운 queue 구현이 있다. DelayQueue가 그 중 하나인데, DelayQueue에서 queue 안의 아이템들은 지연시간 동안 처리되지 않는다. 이번 테크팁에서는 새로운 Queue 인터페이스와 DelayQueue 구현에 대해 알아보도록 하자.

첫번째로 Queue 인터페이스를 분석해보자. 이 인터페이스는 Collection을 확장하고 다섯개의 고유 메서드들을 추가한다.

  • E element()
  • boolean offer(E o)
  • E peek()
  • E poll()
  • E remove()

J2SE 5.0이 새롭게 generics를 지원하므로 여기에서의 E는 어느 타입이든지 가능하며, Queue가 생성될 때 정의된 엘리먼트 타입으로 결정된다.

Queue의 엘리먼트를 추가하고 제거하는 데 당연히 Collection 인터페이스 메서드들을 사용할 수도 있지만, 그 메서드들은 동작할 때 부가적인 요구사항을 가지므로, Queue 인터페이스에서는 사용하지 않을 것을 권장하고 있다. 예를 들어 Collection.add 메서드로 queue에 엘리먼트를 추가하는 대신에 offer 메서드로 queue에 엘리먼트를 추가할 수 있다. 이 둘은 무슨 차이가 있을까? add 실행이 오류가 날 수 있다. 그 한 예는 queue에 사이즈 제한이 있을 때이다.(은행 대기선에 비유하자면, 10명만 대기 가능할 경우) Collectionadd 메서드를 사용하면 add는 예외를 던지면서 실패한다. 이와 비교할 때 offer 메서드는 false를 리턴하며 "실패"하게 된다. 따라서 offer 메서드를 사용하면 실제로 예외적인 상황에서만(특히 체크 안 된 런타임 예외가 던져졌을 경우) 예외처리(exception handling)을 사용하게 된다.

Queue의 다른 네가지 메서드는 두개씩 짝지어 설명할 수 있다. remove/poll, element/peek. removepoll 메서드는 둘 다 queue의 첫번째 엘리먼트 즉 "head"를 제거하는 데 사용된다. 빈 Collection 객체에서 호출되었을 때, remove 메서드는 예외를 던지고, poll 메서드는 단순히 null 값을 리턴한다. head 엘리먼트를 제거하는 대신 단지 그 엘리먼트를 살펴볼 수도 있다. 이 때 element와 peek 메서드가 사용된다. 여기서 element 메서드는 빈 queue에서는 예외를 던지고, peek은 null값을 리턴한다. Queue는 일반적으로 태스크를 진행하는 데 사용되므로 빈 queue를 갖는 것이 예외상황일 필요는 없다. 따라서, poll/peek 모델이 사용하기에 보다 적합할 것이다. (앞에서 본 메서드들 중 예외를 안 던지고 null 리턴하는 메서드들)

Queue는 다음과 같은 상황에서 일반적으로 사용된다.

   class Producer implements Runnable {
     private final Queue queue;
     Producer(Queue q) { queue = q; }
     public void run() {
       try {
         while(true) { queue.offer(produce()); }
       } catch (InterruptedException ex) { ... handle ...}
     }
     Object produce() { ... }
   }

   class Consumer implements Runnable {
     private final Queue queue;
     Consumer(Queue q) { queue = q; }
     public void run() {
       try {
         Object o;
         while((o = queue.poll()) != null) { consume(o); }
       } catch (InterruptedException ex) { ... handle ...}
     }
     void consume(Object x) { ... }
   }

Queue가 꽉 차 있거나(생산자의 입장에서) 비어있을 때(소비자의 입장에서) 어떤 일이 일어나는 지 궁금할 것이다. 이 시점에서 새로운 queue 인터페이스 BlockingQueue를 설명하는 것이 좋겠다. Queue를 사용하여 엘리먼트를 무작정 추가하거나(offer사용) 삭제하는(poll 사용) 대신 BlockingQueueput 메서드로 엘리먼트를 추가하고 take메서드로 제거할 수 있다. puttake는 모두 이를 호출한 쓰레드가, 특정 조건 하에서 블로킹되게끔 한다. put은 queue가 꽉 차 있을 경우, take는 queue가 비어있을 경우가 블로킹 조건이다.

BlockingQueue의 일반적인 사용패턴은 다음과 같다.

   class Producer implements Runnable {
     private final BlockingQueue queue;
     Producer(BlockingQueue q) { queue = q; }
     public void run() {
       try {
         while(true) { queue.put(produce()); }
       } catch (InterruptedException ex) { ... handle ...}
     }
       Object produce() { ... }
  }
  
   class Consumer implements Runnable {
     private final BlockingQueue queue;
     Consumer(BlockingQueue q) { queue = q; }
     public void run() {
       try {
         while(true) { consume(queue.take()); }
       } catch (InterruptedException ex) { ... handle ...}
     }
     void consume(Object x) { ... }
   }

각 생성된 생산자가 꽉 찬 queue에 새로운 아이템을 추가하려 하면 put메서드에서 기다리고, take 메서드에서는 꺼내갈 것이 추가될 때까지 기다린다. queue가 비어있다면 while(true) 조건문에는 아무런 변화도 일어나지 않을 것이다.

DelayQueue는 BlockingQueue 인터페이스의 구체적인 구현이다. DelayQueue 에 추가된 아이템들은 반드시 새로운 Delayed 인터페이스를 구현해야하며, 이 Delayed는 한 개의 메서드, long getDelay(TimeUnit unit)를 갖고 있다. DelayQueue는 우선순위 힙 데이터 스트럭쳐에 기반한 시간 기준 스케쥴링 Queue로 동작한다

데모를 위해, 다음의 프로그램 DelayTest는 몇 초안에 실행되는 Delayed 인터페이스를 구현한다. 알아둬야할 것은1) nanosecond는 10억분의 1초, 2) nanosecond 유니트에서 작업을 가능케하는 System의 새로운 메서드, nanoTime 이 있다는 것이다. getDelay 메서드가 nanosecond로 리턴된 횟수를 필요로 하기 때문에 nanosecond에서 작업하는 것이 중요하다.

   import java.util.Random;
   import java.util.concurrent.Delayed;
   import java.util.concurrent.DelayQueue;
   import java.util.concurrent.TimeUnit;

   public class DelayTest {
     public static long BILLION = 1000000000;
     static class SecondsDelayed implements Delayed { 
       long trigger;
       String name;
       SecondsDelayed(String name, long i) { 
         this.name = name;
         trigger = System.nanoTime() + (i * BILLION);
       }
       public int compareTo(Delayed d) {
         long i = trigger;
         long j = ((SecondsDelayed)d).trigger;
         int returnValue;
         if (i < j) {
           returnValue = -1;
         } else if (i > j) {
           returnValue = 1;
         } else {
           returnValue = 0;
         }
         return returnValue;
       }
       public boolean equals(Object other) {
         return ((SecondsDelayed)other).trigger == trigger;
       }
       public long getDelay(TimeUnit unit) {
         long n = trigger - System.nanoTime();
         return unit.convert(n, TimeUnit.NANOSECONDS);
       }
       public long getTriggerTime() {
         return trigger;
       }
       public String getName() {
         return name;
       }
       public String toString() {
         return name + " / " + String.valueOf(trigger);
       }
     }
     public static void main(String args[]) 
             throws InterruptedException {
       Random random = new Random();
       DelayQueue<SecondsDelayed> queue = 
             new DelayQueue<SecondsDelayed>();
       for (int i=0; i < 10; i++) {
         int delay = random.nextInt(10);
         System.out.println("Delaying: " + 
               delay + " for loop " + i);
         queue.add(new SecondsDelayed("loop " + i, delay));
       }
       long last = 0;
       for (int i=0; i < 10; i++) {
         SecondsDelayed delay = (SecondsDelayed)(queue.take());
         String name = delay.getName();
         long tt = delay.getTriggerTime();
         if (i != 0) {
           System.out.println("Delta: " + 
                 (tt - last) / (double)BILLION);
         }
         System.out.println(name + " / Trigger time: " + tt);
         last = tt;
       }
     }
   }

DelayTest 프로그램은 엘리먼트를 실행하기 전 DelayQueue 안에 그 10개의 엘리먼트를 위치시킨다.

다음은 DelayQueue를 한번 구동했을 때의 출력물이다.

   Delaying: 8 for loop 0
   Delaying: 7 for loop 1
   Delaying: 2 for loop 2
   Delaying: 4 for loop 3
   Delaying: 0 for loop 4
   Delaying: 9 for loop 5
   Delaying: 3 for loop 6
   Delaying: 4 for loop 7
   Delaying: 6 for loop 8
   Delaying: 2 for loop 9
   loop 4 / Trigger time: 1883173869520000
   Delta: 1.9995545
   loop 2 / Trigger time: 1883175869074500
   Delta: 0.0012475
   loop 9 / Trigger time: 1883175870322000
   Delta: 0.9995177
   loop 6 / Trigger time: 1883176869839700
   Delta: 0.9995187
   loop 3 / Trigger time: 1883177869358400
   Delta: 6.408E-4
   loop 7 / Trigger time: 1883177869999200
   Delta: 2.0001667
   loop 8 / Trigger time: 1883179870165900
   Delta: 0.9986953
   loop 1 / Trigger time: 1883180868861200
   Delta: 0.9995595
   loop 0 / Trigger time: 1883181868420700
   Delta: 1.001262
   loop 5 / Trigger time: 1883182869682700

이 출력물은 loop4를 위한 아이템이 time 0, 즉 지연 없이 시작하기로 설정되어있다는 것을 가리키고 있으며,

   Delaying: 0 for loop 4

따라서 첫번째로 다음과 같이 구동한다.

   loop 4 / Trigger time: 1883173869520000

Loop 2에서는 2초간의 지연이 있으며,

   Delaying: 2 for loop 2

따라서 다음과 같이 나타난다.

   loop 2 / Trigger time: 1883175869074500

여기서의 delta는 1.9995545로 약 2초이다.

   Delta: 1.9995545

다른 loop를 위한 비슷한 delta들도 존재한다.

좀 더 실제적인 예를 위해 DelayQueue에서 pull된 것을 단지 출력하는 대신, queue의 아이템들을 Runnable 구현시키고, 그 아이템들의 run 메서드를 호출할 수 있다.

Queue, DelayQueue 와 J2SE 5.0에서 바뀐 다른 Collections Framework에 대한 좀 더 많은 정보를 원한다면 Collection Framework Enhancements를 참조하기 바란다.


@http://kr.sun.com/developers/techtips/c2004_1019.html

2007/03/16 18:01 2007/03/16 18:01
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다

HTTPURLCONNECTION를 사용하여 웹 페이지 액세스하기

이 글은 HttpURLConnection 과 이의 서브클래스인 HttpsURLConnection 을 사용하여 보안 웹 페이지에 액세스하는 방법을 보여준다. 또한 비보안 페이지(non-secure page)에서 보안 페이지(secure one)로의 리다이렉트를 쉽게 할 수 있는 방법도 볼 수 있다. HTTP 와 HTTPS에 관한 정보는 HTTP 1.1 RFC 2616HTTPS RFC 2818를 참고하기 바란다.

첫번째 예로, 주어진 URL에 접속하기 위해 다음 WebPageReader 프로그램의 HttpURLConnection 를 이용해 보자. 그리고 페이지의 내용을 스탠다드 아웃(standard out)에 출력하자.

[code] import java.net.URL; import java.net.MalformedURLException; import java.net.URLConnection; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; public class WebPageReader { private static URLConnection connection; private static void connect( String urlString ) { try { URL url = new URL(urlString); connection = url.openConnection(); //for jdk 1.5 or higher connection.setConnectionTimeout(1000); connection.setReadTimeout(3000); //for jdk 1.4 above System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "50000"); } catch (MalformedURLException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void readContents() { BufferedReader in = null; try { in = new BufferedReader( new InputStreamReader( connection.getInputStream())); String inputLine; while ( (inputLine = in.readLine()) != null) { System.out.println(inputLine); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { if (args.length != 1) { System.err.println("usage: java WebPageReader " + "<url>"); System.exit(0); } connect(args[0]); readContents(); } } [/code]

만약 현재의 위치가 방화벽 뒤라면, 다음과 같이 설정된 proxyHost과 proxyPort 변수들이 필요하다.

[code] http.proxyHost=webcache http.proxyPort=8080 https.proxyHost=webcache https.proxyPort=8080 [/code]

커맨드 라인에 -D플래그를 이용해서 값을 직접 입력하거나 프로그램 상에서 System.setProperty()를 호출함으로써 변수를 구할 수있다. WebPageReader 를 컴파일한 후에 이하와 같은 커맨드로 Core Java Technologies Tech Tips 홈 페이지의 내용을 열거해 볼 수 있다.

[code] java WebPageReader http://java.sun.com/developer/JDCTechTips/ [/code]

URLConnection는 추상 클래스이다. URL클래스의 openConnection() 메소드는 지정된 URL을 읽을 수 있도록 적절하고 구체적인 서브클래스를 리턴한다. http나 https URL을 입력하면 이는 HttpURLConnection나 HttpsURLConnection의 서브클래스가 될 것이다. 만약 다음을 openConnection()를 호출하는 라인에 추가하면,

[code] System.out.println(connection.getClass()); [/code]

HttpURLConnection의 숨겨진 구현 클래스의 인스턴스를 리턴하는 커넥션(connection)을 보게 된다. 예를 들면, 다음과 같다.

[code] class sun.net.www.protocol.http.HttpURLConnection [/code]

이와 유사하게 보안 페이지를 읽기 위해 동일한 WebPageReader코드를 사용할 수가 있다.

[code] java WebPageReader https://today.dev.java.net [/code]

후자의 경우, 커넥션은 HttpsURLConnection의 서브클래스인 HttpURLConnection타입이라는 것을 알아야 한다. 보다 명확하게 말하자면 다음과 같은 숨어있는 구현 클래스가 있다는 것을 인식할 수 있어야 한다.

[code] class sun.net.www.protocol.https.HttpsURLConnectionImpl [/code]

일반적으로 브라우저에 URL을 입력할 때, 이동하고자하는 페이지가 보안 페이지인지 아닌지는 알 수가 없다. 다시 말하면, today.dev.java.net 페이지를 보기 위해서는 http://today.dev.java.net를 입력한다. 필요하다면 브라우저가 리다이렉트할 것이고 사용자를 https://today.dev.java.net로 연결하기 위해 적절한 신호변경을 수행한다. WebPageReader프로그램이 요청된 리다이렉션을 수행하는지를 살펴보자.

[code] java WebPageReader http://today.dev.java.net [/code]

원하는 페이지로 리다이렉트되는 대신에 다음과 같은 메시지를 보게 된다.

[code] <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <HTML><HEAD> <TITLE>301 Moved Permanently</TITLE> </HEAD><BODY> <H1>Moved Permanently</H1> The document has moved <A HREF="https://today.dev.java.net/">here</A>.<P> <HR> <ADDRESS> Apache/1.3.26 Server at today.dev.java.net Port 80 </ADDRESS> </BODY></HTML> [/code]

이 정보로부터 무언가를 읽어내는 것은 어렵지만 문제는 리다이렉션에 관한 것이 아니다. URL http://linux.java.net으로 프로그램을 실행하면, 프로그램은 http://community.java.net/linux으로 적절히 이를 리다이렉트하고 사용자는 원하는 컨텐츠를 볼 수가 있다. 어떤 일이 일어나는지를 자세히 살펴보려면 HttpURLConnection를 명시적으로 이용해야 한다. 스탠다드 아웃에 웹 페이지의 컨텐츠를 출력하는 코드를 삭제해서 일을 간단히 해보자. RedirectingReader프로그램이다.

[code] import java.net.URL; import java.net.MalformedURLException; import java.net.HttpURLConnection; import java.io.IOException; public class RedirectingReader { private static HttpURLConnection connection; private static void connect( String urlString ) { try { URL url = new URL(urlString); connection = (HttpURLConnection)url.openConnection(); //for jdk 1.5 or higher connection.setConnectionTimeout(1000); connection.setReadTimeout(3000); //for jdk 1.4 above System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "30000"); System.out.println(connection.getURL()); System.out.println( connection.getResponseCode() + " " + connection.getResponseMessage()); System.out.println(connection.getURL()); } catch (MalformedURLException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { if (args.length != 1) { System.err.println( "usage: java WebPageReader " + "<url>"); System.exit(0); } connect(args[0]); } } [/code]

다음과 같이 리다이렉트하는 URL을 입력하여 RedirectingReader 를 컴파일하고 실행해 보자.

[code] java RedirectingReader http://linux.java.net/ [/code]

다음과 같은 출력값을 보게 될 것이다.

[code] http://linux.java.net/ 200 OK http://community.java.net/linux/ [/code]

첫번째 라인이 재빨리 나타난다. String값으로 URL을 생성하고 HttpURLConnection객체를 실행하자. 그러면 http://linux.java.net를 요청하는 동안에 잠깐의 멈춤이 생긴다. 페이지가 리다이렉트되는 이 시간동안 받게 되는 응답 코드와 메시지는 리다이렉트된 페이지로부터 온 것이다. 이 리다이렉트된 페이지는 출력값의 3번째 라인에 열거된다. URL url = new URL(urlString);아래의 라인을 추가해서 리다이렉션을 허용하지 않았을 때 발생하는 현상을 보자.

[code] HttpURLConnection.setFollowRedirects(false); [/code]

출력값은 다음과 같다.

[code] http://linux.java.net/ 302 Found http://linux.java.net/ [/code]

이는 302 에러가 발생했다는 것을 나타낸다. 곧 리다이렉트되지 않고 URL이 그대로 유지되었다는 것이다. 이를 처리하기 전에, 좀 전에 추가했던 라인을 지우고 리다이렉션이 다시 작동하는지를 확인하기 위해 RedirectingReader 프로그램을 실행시켜보자. RedirectingReader를 다시 한번 실행시키고, http://today.dev.java.net 를 입력하자. 다음과 같은 출력값을 보게 된다.

[code] http://today.dev.java.net 301 Moved Permanently http://today.dev.java.net [/code]

위는 이 프로그램이 "Moved Permanently" 에러를 처리할 수 없어서 리다이렉트 했다는 것을 말한다. 이것이 바로 원했던 디폴트 속성이다. 보안문제 때문에 http 과 https간에는 리다이렉트할 수 없다. 어디로 리다이렉트할 것이냐하는 정보는 이 응답의 헤더 부분에 있다. 이전의 요청에 대한 전체 응답 헤더는 다음과 같다.

[code] HTTP/1.1 301 Moved Permanently Date: Tue, 03 Feb 2004 01:38:43 GMT Server: Apache/1.3.26 (Unix) mod_ssl/2.8.10 OpenSSL/0.9.6b mod_jk/1.2.1 Location: https://today.dev.java.net/ Content-type: text/html; charset=iso-8859-1 [/code]

HttpURLConnection 내의 getResponseCode() 과 getResponseMessage() 메소드가 이 응답의 첫번째 라인에 포함된 정보를 리턴하는 것을 본 적이 있을 것이다. 혹은 getHeaderField() 메소드를 이용해서 헤더 필드의 이름에 스트링값을 넣어주어도 된다. 가령, getHeaderField("Location")는 https://today.dev.java.net/값을 리턴한다.

이 글의 시작부분에서 언급했던 HTTP 1.1 과 HTTPS RFCs에서 요청과 응답 헤더의 포맷에 관해 자세히 살펴 볼 수 있다. 300 레벨 응답에서, "Location:"는 리다이렉션을 위한 위치값을 제공해야만 한다. 301나 302 에러를 발생하는지를 확인하기 위해 다음 사항을 추가하자.

[code] private static boolean mustRedirect(int code){ if (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP) { System.out.println("Received error " + code + ", trying secure redirect"); return true; } else return false; } [/code]

리다이렉트가 자동적으로 처리되지 않는다면 사용자는 301 나 302 응답 코드만을 받게 된다는 것을 기억하자. 지금까지 이것은 리다이렉트가 HttpURLConnection가 아닌 HttpsURLConnection가 필요하다는 것을 의미했다. "Location:" 필드에 제공된 정보를 따르자. 다음과 같이 새로운 정보를 이용해서 url 값과 커넥션을 재설정하자.

[code] url = new URL("https://"+ url.getHost() + url.getFile()); connection = (HttpsURLConnection)url.openConnection(); [/code]

마지막으로, 웹 리더를 받기 위해 위의 모든 사항을 모으고 필요할 때 보안 페이지로 리다이렉트될 수 있도록 하자.

[code] import javax.net.ssl.HttpsURLConnection; import java.net.URL; import java.net.MalformedURLException; import java.net.HttpURLConnection; import java.io.IOException; import java.io.BufferedReader; import java.io.InputStreamReader; public class RedirectingReader { private static HttpURLConnection connection; private static URL url; private static void connect(String urlString) { try { url = new URL(urlString); connection = (HttpURLConnection) url.openConnection(); //for jdk 1.5 or higher connection.setConnectionTimeout(1000); connection.setReadTimeout(3000); //for jdk 1.4 above System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); System.setProperty("sun.net.client.defaultReadTimeout", "50000"); int code = connection.getResponseCode(); if (mustRedirect(code)) secureRedirect( connection.getHeaderField("Location")); readContents(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static boolean mustRedirect(int code) { if (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP) { return true; } else return false; } private static void secureRedirect(String location) throws IOException { System.out.println(location); url = new URL(location); connection = (HttpsURLConnection) url.openConnection(); } private static void readContents() { BufferedReader in = null; try { in = new BufferedReader( new InputStreamReader( connection.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { if (args.length != 1) { System.err.println("usage: java WebPageReader " + "<url>"); System.exit(0); } connect(args[0]); } } [/code]

업데이트된 RedirectingReader 를 컴파일하고 동작이 제대로 이루어지는지 확인하기 위해 몇 개의 다른 입력값을 넣어 실행해보자. 예를 들면 http://today.dev.java.net 와 http://linux.java.net를 넣어보자. 리다이렉트되지 않는 보안페이지와 비보안 페이지를 입력해서 RedirectingReader를 실행해도 동작이 적절하게 이루어져야 한다. 이제 다시 뒤로 돌아가서 최초 WebReader 프로그램에 모든 println() 메소드를 제거하고 readContents()를 추가할 수 있다.


@http://kr.sun.com/developers/techtips/c2004_02_10.html

2007/03/15 12:58 2007/03/15 12:58
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. Blog Icon
    감사합니다.

    좋은 정보 감사합니다. 비공개로 담아갑니다 ^^;

  2. Blog Icon
    비밀방문자

    관리자만 볼 수 있는 댓글입니다.

  3. Blog Icon
    비밀방문자

    관리자만 볼 수 있는 댓글입니다.

행사장에서 만난 꼬마 친구들



















minolta @7, tokina 28-80, potra 160vc
2007/03/11 01:05 2007/03/11 01:05
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다
  1. 역시 포트라다.. 라는 느낌이 듭니다^^

  2. 우담아빠님 또 찾아주셨군요.. ^^
    이번 주말엔 직장 동료 애기 돌 스냅사진을 부탁받았는데..
    이런 부탁을 받으면 한편으론 기쁘면서도 또 한편으론
    부담스러워 집니다.

    카메라를 처음들었을때같은 편한 마음으로 찍는 스냅이라면 좋으련만
    그런 행사장 사진은 저 보단 사진 받을 사람의 마음에 드는 결과물이
    나와줘야 하기 때문에 아직은 제 사진에대한 확신이 없는 저로선
    부담스러워 지는게 어찌보면 당연한 일이겠지요..

역쉬...뒷풀이는 고깃집이..









출사 후 뒷풀이.
허기진 배를 채우러 들어온 나름 이름있는 고깃집.
너무 오랜만에 느껴보는  선술집 분위기...
소주한잔이 생각나는 밤이다.

minolta @7, km 17-35mm, portra 160vc
2007/03/11 00:13 2007/03/11 00:13
Trackback Address:이 글에는 트랙백을 보낼 수 없습니다