vb 또는 asp에서 다른 웹페이지를 호출하고 싶어질때가 있다.
물론 C#과 같은 언어는 httpRequest 와 같은 객체가 있어 손쉽게 받을수 있지만
vb or asp에서는 WinHttp.WinHttpRequest.5.1 의 객체를 생성하여 사용할수 있다.

GET 방식으로 페이지를 호출할경우

Function getSiteSourceGet( siteURL, params )
 Set httpObj = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
 httpObj.open "GET", siteURL & "?" & params, False
 
 httpObj.Send()
 httpObj.WaitForResponse
 If httpObj.Status = "200" Then
  getSiteSourceGet = httpObj.ResponseText
 Else
  getSiteSourceGet = null
 End If
End Function



 

POST 방식으로 페이지를 호출할 경우

Function getSiteSourcePost( siteURL, params )
 Set httpObj = Server.CreateObject("WinHttp.WinHttpRequest.5.1")
 httpObj.open "POST" , siteURL, False
 httpObj.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
 '포스트 방식시 위의 라인을 추가해 주어야 한다.
 
 httpObj.Send params
 '포스트의 파라미터는 Send 호출시 같이 값을 넘겨 주어야 한다.
 httpObj.WaitForResponse
 If httpObj.Status = "200" Then
  getSiteSourcePost = httpObj.ResponseText
 Else
  getSiteSourcePost = null
 End If
End Function



POST를 이용할시 약간 수정행 주어야 할것이 있는데 Content-Type을 위와 같이 변경해주어야 하며 파라미터를 GET방식과는 다르게 Send 시 값을 넘겨주어야 파라미터값들이 전달되다.

위와 같이 함수를 만들어 사용하면 될것이다.

추가된글 파라미터를 넘길때 GET 방식이던 POST 방식이던 URLEncode 를 해주어야 한다. 그것때문에 한참 헤맸다. 그리고 VB Script로 호출시에는 Server 객체를 사용할수 없음으로 URLEncode 함수를 직접 만들어 사용해야 했다. URLEncode 함수는 쉽게 구할수 있다.

비교 3번째네요. 제가 저번 프로젝트때 가장 기초적인 것임에도 불고 하고 제일 혼란해 했던.... 저혼자서 끙끙 앓다가 결국 물어봐서 해결본 것이에요. 그래서 물어보기 전까지 혼자서 생쑈를 했죠. ^^ 일단 코드를 보자구요.

C#코드
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;>
class HttpClientGet
{
    static void Main(string[] args)
    {
        HttpWebRequest wReq =
            (HttpWebRequest)WebRequest.Create(@"http://hahakbs.dothost.co.kr/reqTest.php?input=123256");
        wReq.UserAgent = ".NET Framwork Example Client";
        HttpWebResponse wResp = (HttpWebResponse)wReq.GetResponse();
        Stream respStream = wResp.GetResponseStream();
        StreamReader reader = new StreamReader(respStream, Encoding.Default);
        while (reader.Peek() >= 0)
        {
            String str = reader.ReadLine();
            Console.WriteLine(str);
            if (str.Equals("Y"))
                Console.WriteLine("Get Y");
            else
                Console.WriteLine("Get else");
        }
    }
}



 

결과
N
Get else



 

자바코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class HttpRequest {
 public static void main(String[] args)
  throws MalformedURLException, IOException {
  HttpURLConnection connection =
   (HttpURLConnection) new URL("http://hahakbs.dothost.co.kr/reqTest.php?input=123456").openConnection();
 
  BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  String line;
  while ((line = in.readLine()) != null){
   System.out.println(line);
   
   if(line.equals("Y")) {
    System.out.println("Get Y");
   } else {
    System.out.println("Get else");
   }
  }
 }
}


 

결과
Y
Get Y



위의 예제는 간단하다. 미리 만들어 놓은 사이트에 input에 값을 Request한다. 그리고 그 것에 대한 값을 Stream 형태롤 받아서 그 값을 출력한다. input의 값은 123456 일 경우는 Y라는 문자열을 그 외의 경우에는 N이라는 문자열을 보낸다.

뭐 두개의 프로그램상 별다른 차이점은 그다지 없다. C#에서는 HttpWebRequset 객체를 생성하고 그 객체에서 리스폰스를 받아 스트림 버퍼로 읽고 그 읽은 값을 뿌려주고 비교해주고, 자바에서는 HttpURLConnection 객체를 URL객체의 커넥션으로 생성해 그 값을 버퍼 리더로 읽어서 뿌려준다.

자바쪽은 따로 Request나 Response 객체를 둔것이 아니라, Connection 객체를 두어 사용함으로서 조금더 간편하다고 할수 있을것이다. 그리고 어차피 읽어오는 응답텍스트 들은 각각의 스트림객체를 통해 읽어오는것은 비슷하다 할수 있겠다.

위처럼 간단한 것을 하기 위해 한참을 몰랐다가 알았을 때는 정말 한심했다. ^^ 물론 C#이 아니라 자바쪽을.... 왠지 자바쪽은 쉽게 접해지지 않는것 같다. 역시 MS쪽에 길들어 져서.

그런데 제일 혼란 스러웠던 것은 저것이 그냥 콘솔이 아니라, 웹 상에서 했기 때문이기도 하다. 요구점은 이것이였다. 웹 서비스에서 유저가 접속을 해서 내 페이지에서 숫자를 입력 하면, 그 결가 데이터가 자체 웹서버의 DB나 파일에 있는게 아니라 다른 웹에 입력값을 전송하고, 그 전송값에 대한 결과 값을 받아서 처리하는.. 그래서 감을 잡기가 힘들었던거 같다.

이놈의 귀차니즘 때문에 @.@ 글을.. 쓰고 싶은데 쏘스가 주어지고 해야될일이 생기니 에휴 ~~ 이놈의 핑계~ 어째던 이번에 알아볼 것은 db에 접속 하는것을 알아 보겠다. 그것도 동일한 sql문에 param 값을 설정 하여서 한개의 sql문으로 처리 하는 방법을 해보는 것이다.


자바 소스
import java.sql.*;
public class CallableTest {
 public static void main(String[] args) throws SQLException{
  Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/mysql", "root", "apmsetup");
 
  PreparedStatement stmt;
 
  String sqlStr = "select * from db where id=?";
 
  stmt = conn.prepareStatement(sqlStr);
 
  stmt.setInt(1, 10);
 
  ResultSet rs = stmt.executeQuery();
 
  while(rs.next())
  {
   System.out.println(rs.getString(1));
  }
 
  stmt.close();
  conn.close();
 }
}



 

그리고 C# 소스
using System;
using System.Data;
using System.Data.SqlClient;

class SqlParamTest
{
    static void Main(string[] args)
    {
        string connStr = "Provider=MySQLProv;Data Source=mysql;" +
                         "Location=localhost;User Id=root;Password=apmsetup";
        string query = "select * from db where id=@ID";
        SqlConnection conn = new SqlConnection(connStr);
        conn.Open();
        SqlCommand comm = new SqlCommand(query, conn);
        comm.Parameters.Add("@ID", SqlDbType.Int);
        comm.Parameters["@ID"].Value = "10";
        SqlDataReader sr = comm.ExecuteReader();
        while (sr.Read())
        {
            Console.WriteLine(sr.GetInt32(0)));
        }
        sr.Close();
        conn.Close();
    }
}



위의 코드는 솔직히 실행해보지는 못했다. 일단 실행을 할려면 MySql 설치해야 하고, 공급자도 설치해야 하고.. 아마도 자바와 닷넷용 모두 설치해야 할것이다. 그렇다고 MSSql을 설치하기도 그렇고. 그러니 이해해 주시기를 바랍니다 ^^

어째던 DB 접속에 둘다 문제가 없다면 두개의 소스가 비슷한 동작을 할것이다. 일단 둘다 각각의 Connection 객체를 통해 일단 DB에 접속 했다. 그런데 여기서 약간의 차이점은 자바에서는 DBManager 를 사용하여 객체를 생성하고, C#에서는 객체 스스로 생성되었다. 그래서 그런지는 모르겠지만 C#으로는 Connection 객체를 open을 해주는데 자바에서는 해주지 않는다.

그리고 다음은 비슷한 동작을 하는 command == statement 이두 객체가 비슷한 동작을 한다. 커넥션 객체에서 각 쿼리를 실행 하기 위한 Sql명령을 가지고 있는 객체이다. 여기서 바뀌게 되는 파라 미터 값을 command 에서는 @param 으로 구분했고 statement 에서는 ?로 구분했다. 그리고 자바에서는 preparedstatement라는 객체를 따로 만들어야 했으나, C#에서는 command라는 객체의 다른 종류는 없었다.

그리고 데이터를 읽는 것은 각각의 Reader로 읽어 값을 읽었고, 마지막으로 각 파라미터에 값을 넣을때 Java에서는 셋팅을 할때 메서드를 호출에서 ? 순서에 따라 각각의 값을 지정하였고, C#에서는 각 파라미터의 @param를 가지고 셋팅후 값을 대입 2번의 수행을 하였다.

뭐 두개다 큰 차이는 없겠지만 자바에서는 param 들이 ?로 표시되어 각각을 지정하는데 유연함이 조금 떨어질수 있겠지만, C#에서는 2번 셋팅을 해주어야 해서 불편하다는 점이 내가 내린 결론!!



에구에구 오랜만에 쓰는데 왜이리 피곤한지.. 그리고 자바에서는 또 특이하게 callablestatement라는 놈이 있다. 이놈은 preparedstatement라는 놈과는 비슷하지만 다른부분이 있다. 좀더 알아보고 기회가 된다면 다름 글에 이야기 해보겠다.

자바와 C#에서의 동일한 작동을 코드로 알아 볼께요.~~~

우선 C#
using System;
using System.Reflection;
class App
{
    static void Main(string[] args)
    {
        App pr = new App();
        Type type = pr.GetType();
        MethodInfo method = type.GetMethod("Sum");
        if (method != null)
        {
            Console.WriteLine(method.ToString());
            Console.WriteLine(method.Invoke(null, new object[] { 1, 2 }));
        }
    }
    public static int Sum(int i,int j)
    {
        return i+j;
    }
}



 

결과
Int32 Sum(Int32, Int32)
3


 

JAVA
import java.lang.reflect.Method;
public class methodInvoke
{
 public static void main(String[] args)
 {
  Method methods[] = methodInvoke.class.getDeclaredMethods();
  for (int i = 0; i < methods.length; i++)
  {
   if (methods[i].toString().equals("public static int methodInvoke.Sum(int,int)"))
   {
    Integer x = new Integer(1);
    Integer y = new Integer(2);
    try
    {
     System.out.println(methods[i].toString());
     System.out.println("1 + 2의 값--");
     System.out.println(methods[i].invoke(null, new Object[] {x,y}));
    }
    catch(Exception e)
    {
        System.out.println(e.getMessage());
    }
   }
  }
 }
 public static int Sum(int x, int y)
 {
  return x + y;
 }
}



 

결과
public static int methodInvoke.Sum(int,int)
1 + 2의 값--
3


일단 중요했던 점은 자바 코드 작성시 예외처리를 아예 빼고 invoke를 사용하게 된다면 실행이 되지 않았다. ㅡ.ㅡ; 뭐 이건 이클립스로 실행한게 아니라 J#으로 했기에 정확하지 않을 수도 있지 않을까?? ^^;; 그리고 나머지 메소드들도 나오지 않아 딱맞는 메서드를 메서드 명으로 찾았다.

일단 대충 같은 결과에서 본 시점은 C#코드가 더 간단하다는 점이다. 특정 만든 클래스에서 Type을 받고 거기에서 특정 함수를 찾기도 쉽고, 실행도 보다 편리 하다는점. 아무래도 자바가 나온 뒤에 C#이 나왔으니 어쩔수 없나? 아님 내가 자바를 많이 모르니 더 쉬운 방법을 못찾을수도 있었을 것이다.

내가 이 invoke를 이번에 다루는 이유는 내가 지금 보는 소스에서 본 내용이기에 써보았다. ^^ 특정 조건에 따라 함수를 실행 하게 되는데 기존에는 실행 함수중에서 조건 값을 가지고 if else if else ~~ 로 분기를 하였으나, xml문서로 조건 값들에 대한 메서드를 설정하고 if else if 를 사용하지 않고 조건에 맞는 문자열을 찾아 method에 값을 받고 invoke한다. 음..  이 방식이 그렇게 빠른가? 솔직히 잘 모르겠다. 그냥 대충 if else if else 로 구별 해도 상관 없지 않을까? 하는 생각이 들기도 했지만.

앞으로 좌절금지 열심히 아자아자다!!

Programing 2007/01/22 22:16

Connection Pool

Connection Pool

이놈은 무엇이냐? 일반적으로 DB접속을 하는 간단한 프로그램을 할때 프로그램을 만드는 순서는 디비 커넥트 후 쿼리 실행 후 디비를 클로우즈 한다. 그런데 이런 디비 작업이 1~2 개각 아닌 수십 수백 이상의 작업을 해야 하는 경우에 각각 작업을 할때마다 디비를 연결했다 닫았다 하면 굉장히 큰 부하가 걸린다. 그리고 속도또한 느리게 된다.

이것을 해결하기 위해 나온 개념이 커넥션 풀~~ 미리 데이터 베이스와 연결을 몇개 해논 다음 디비작업이 필요한 경우 열린 통로로 작업 하고 끝나도 디비를 닫지 않는다. 왜 닫지 않냐 하면 나중에 쓰일 때 다시 쓰기 위해서... 이렇게 몇개의 디비를 열어 놓아서 바로바로 처리 하게 해주는 것이다.
Programing 2007/01/08 16:36

XML 이란..

XML(eXtensible Markup Language)이란?

◈구조(Structure), 데이터(Data) 그리고 표현(Description)이 분리된 데이터 정의를 위한 언어

XML(eXtensible Markup Language)의 구성
◈구조(Structure) : DTD(Document Type Definition)
◈데이터(Data) : DTD에 의해서 트리형태의 XML 문서로 표현된다.
XSL (eXtensible Stylesheet Language) : 데이터를 표현하기 위한 방법을 제공한다.

User inserted image

▣XML의 주목적?

◈표준 데이터 교환에 있다.

▣그렇다면 XML문서를 프로그램적으로 이용하고자 할 때는 XML 문서를 핸들 하기 위한 두가지 방법이 있다.

◈DOM(Document Object Model)
◈SAX(Simple API for XML)

▣두가지 방법의 차이점은 DOM 방식은 XML의 저장된 형식인 tree 구조로 데이터를  핸들 하는 방법이고, SAX는 순차적인 스트림 방식이다.
오늘 좋은 세미나를 들었다. 절때 잊기 전에 정리 해두어야 한다. 정리 해서 내껏으로 만들놓아야 된다. ㅋㅋㅋ 그래야만 오늘 시간을 날리지 않게 될것이니깐.

Aspect Oriented Programming (관점 지향적 프로그램)

위에 놈은 무엇인가? 예를 들어 보자.

public class NetWorkClass : TCPProtocol
{
  public void SendMessage()
  {
       // Good Send Logic!!!
  }
}



위와 같은 클래스는 TCP 메세지를 전송하는데 있어서 완벽한 로직 제공 했고, 그것을 수행하는데 전혀 문제 없는 클래스이다. 한마디로 완벽하다고 할수 있다.

그런데 위 클래스를 사용하는 프로그램을 사용하다가 사용자가 이렇게 요구 할수도 있을 것이다. 메세지를 전송할때 로그를 남겨주세요. 그렇다면 우리는 다음과 같이 소스를 수정할 것이다.

public class NetWorkClass : TCPProtocol
{
  public void SendMessage()
  {
       LogClass log = new LogClass();
       // Good Send Logic!!!
       log.Write(message);
  }
}



첫번째 프로그램이 다음과 같이 수정되었다. 위와 같이 수정된 프로그램을 사용하다가 또 사용자가 메세지를 암호화 해서 보내게 해달라고 했을경우 또 다음과 같이 수정을 하게 될것이다.

public class NetWorkClass : TCPProtocol
{
  public void SendMessage()
  {
       LogClass log = new LogClass();
       SecurityClass sc = new SecurityClass();
       sc.Set(true);
       // Good Send Logic!!!
       sc.Set(false);
       log.Write(message);
  }
}



위와 같이 또 수정 될것이다. 그런데 이와 같은 요구가 계속 늘어나게 된다면 소스 코드가 계속 늘어 나게 되고 복잡해 지고, 엉키고 그렇게 된다. 그리고 원래의 클래스는 아주 이상적으나 후에 엉키게 되는 소스를 보고 사람들은 잘못된 프로그램이라고 말들이 많을 것이다.본래의 의도와는 상관 없이....

이런것을 해결하기 위해서 나온것이 Aspect Oriented Programming (관점 지향적 프로그램) 이다. 다음 소스를 보자.

public class NetWorkClass : TCPProtocol
{
  [Log]
  [Security]
  public void SendMessage()
  {
       // Good Send Logic!!!
  }
}



위와 같이 보내려는 메서드는 그대로이다. 원래의 메서드는 전혀 건들 필요 없이 추가하려는 기능들을 Attribute 로 포함 하여 필요한 기능들을 포함하고 나중에 기능이 필요 없을때에는 Attribute를 빼고 하면 처음보다 엉키지도 않고 알아보기도 쉽고 좋은 프로그램이 될것이다. 이렇게 하는것 이러한 개념이 Aspect Oriented Programming:관점 지향적 프로그램이다.


User inserted image

위의 그림과 같이 메세지를 보내는 기능은 그대로 이고 속성들을 추가하고 바꿀것은 바꾸고 이런것이다.

div>