Jump to content
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr ×
과거의 기술자료(읽기 전용): https://tech.devgear.co.kr

멀티플랫폼 3티어 REST Client Application 구현 방법


Recommended Posts

"3티어 구축을 위한 REST 서버를 쉽고 간단하게 구현 방법" 에 대한 글에 이어서 클라이언트 앱 구현 방법에 대해 설명 합니다.

서버 구현 방법은 아래 링크를 참고 하시기 바랍니다.

REST 서버 구축 Part1 보러가기

REST 서버 구축 Part2 보러가기

REST 서버 구축 Part3 보러가기

REST 서버 구축 Part4 보러가기

서버 프로젝트 모듈의 조회 조건을 하나 추가 하기 위하여 아래 소스에 주석에 "파라미터 항목 추가" 라고 표시된 내용을 넣어서 select 의 Where 조건을 만듭니다. 기존에는 테이블의 전체 쿼리를 하였다면 sno 항목수를 추가하여 쿼리문의 Where 조건을 제어 합니다.

따라서 요청 URL은 http://127.0.0.1:8080/querytb?tname=productinfo&sno=10  와 같이 &sno=10 을 추가하면 됩니다.

// http://127.0.0.1:8080/querytb?tname=productinfo&sno=10
procedure TWebModule1.WebModule1WebActionItem2Action(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  JTopObj, JsubObj : TJSONObject;        // Uses System.JSON,
  JArr  : TJSONArray;
  JPair : TJSONPair;
  tname : string;
  i, sno  : integer;
begin
  tname  := Request.ContentFields.Values['tname'];
  sno    := Request.ContentFields.Values['sno'].ToInteger; // 파라이터 항목 추가

  JTopObj := TJSONObject.Create;  // 메인 블럭 정의
  try
    FDConnection1.Open;

    try
      FDQuery1.Close;
      FDQuery1.SQL.Clear;
      FDQuery1.SQL.Add( 'select * from ' + tname + ' '  );
      FDQuery1.SQL.Add( 'where ProductID <= :p_sNo ');   // 파라이터 항목 추가 
      FDQuery1.ParamByName('p_sNo').AsInteger := sno;    // 파라이터 항목 추가
      FDQuery1.Open;

 

클라이언트 앱은 FMX 로 제작 하여 모바일 플랫폼에서도 작동 되게 합니다.

Form 화면에 TStringGrid 를 넣어서 조회한 테이블 데이터를 출력 할 수 있게 합니다.

지정된 URL 과 파라미터를 입력 받아 Post 형태로 서버 프로젝트에 전송 합니다.

전송 요청 방법은 TNetHTTPClient 와 TNetHTTPRequest 를 사용 하였습니다.

TNetHTTPClient 로 전송을 요청하고 응답은  TNetHTTPRequest의  OnRequestCompleted 이벤트 메소드가 발생하면 데이터를 수신 하게 됩니다.

NetHTTPRequest1 의 Client Option 에 NetHTTPClient1 을 지정하여 연결해 줍니다. 

상세 방법은 아래 소스에서 설명 합니다.

image.png

 

TNetHTTPClient 와 TNetHTTPRequest 를 이용하여 Post 로 파라미터를 넣어 전송 하는 방법은 아래와 같습니다.

NetHTTPRequest1.Post( sURL, sParamList );  와 같은 형태로 URL 과 파라미터를 TStringList 에 넣어서 전송 합니다.

TStringList 를 사용 하므로 파라미터의 갯수를 따로 지정 하지 않고 넣을수 있습니다.

만약 서버쪽에서 지정 되지 않는 파라미터를 전송 하였을 경우에는 에러 없이 무시 됩니다.

샘플 프로젝트에서는 URL 과 파라미터를 화면에서 입력 받은 값으로 조합하여 전송 하였습니다.

//---------------------------------------------------------------------------------------------------
// targetURL : Post 위치 유닛의 서브 URL
procedure TMCForm.Request_PostSet( targetURL, tbName : string; sno : integer );
var
  i : integer;
  sParamList :TStringList;
  sURL : string;
begin
  sURL := ET_Server.Text + targetURL;                // http://127.0.0.1:8080/

  NetHTTPClient1.ContentType   := 'application/json';
  NetHTTPClient1.AcceptCharSet := 'UTF-8';

  sParamList := TStringList.Create;
  sParamList.Add( 'tname=' + tbName  );       // 테이블 명
  sParamList.Add( 'sno=' + sno.ToString  );   // 항목 수

  NetHTTPRequest1.Post( sURL, sParamList );
end;

//*****************************************************************************************************************
// http://127.0.0.1:8080/querytb?tname=productinfo&sno=10
procedure TMCForm.BT_Post1Click(Sender: TObject);
begin
   Request_PostSet( 'querytb', 'productinfo', NumberBox1.Text.ToInteger );   //  파라미터 2개 : 테이블명, 항목수
end;

 

Post 전송 후에 응답 대기로 들어가면 서버로 부터 응답이 오면  TNetHTTPRequest 의  OnRequestComplted 이벤트가 발생 합니다.

따라서 이곳에서  sJsonData := AResponse.ContentAsString(); 형태로 결과값을 String으로 받아서 Json 값들을 파싱 합니다.

샘플 소스에서는 Json 파싱값을 TStringGrid에 출력 하기 위해서 GDListType 레코드를 만들어서 사용 하였는데 이 부분은 각자 익숙한 방법으로 화면에 표현 하면 됩니다.

// StringGrid에 기록될 데이터 배열 세트
type GDListType = record
  CNo : integer;                     // 컬럼수
  CHeadName : TStringList;           // 컬럼 타이들
  DArr : array of TStringList;       // 데이터 Row
end;


//*****************************************************************************************************************
procedure TMCForm.NetHTTPRequest1RequestCompleted(const Sender: TObject; const AResponse: IHTTPResponse);
var
  sJsonData, pInfo : string;
  gDSet : GDListType;
  i, k, arrCount : Integer;
  oJRson, oJField: TJSONObject;
  oArr: TJsonArray;

begin
  if AResponse.StatusCode <> 200 then
  begin
    LogMemo.Lines.Add(  'HTTP response code: ' + AResponse.StatusCode.ToString );
    Exit;
  end
  else
    LogMemo.Lines.Add( 'HTTP response : '  +   AResponse.StatusText );

  sJsonData := AResponse.ContentAsString();

  oJRson := TJSONObject.ParseJSONValue( sJsonData ) as TJSONObject;
  try
    pInfo  := oJRson.GetValue<string>('PathInfo');
    arrCount := oJRson.GetValue<integer>('Count');        //  oJRson.Get('Count').JsonValue

    LogMemo.Lines.Add( 'Count :' + arrCount.ToString );
    if arrCount = 0 then
       Exit;    // -> finally

    oArr := oJRson.Get('Items').JsonValue as TJSONArray;

    // 첫번째 배열 (oArr.Items[0]) 에서 타이틀(페어명) 획득 -------------
    oJField := oArr.Items[0] as TJSONObject;
    gDSet.CNo := oJField.Count;  // 컬럼수
    gDSet.CHeadName := TStringList.Create;

    for k := 0 to oJField.Count - 1  do     
    begin
      gDSet.CHeadName.Add( oJField.Pairs[ k ].JsonString.Value );
    end;

    SetLength( gDSet.DArr, oArr.Count );

    for i := 0 to oArr.Count - 1 do
    begin
      oJField := oArr.Items[i] as TJSONObject;

      gDSet.DArr[ i ] := TStringList.Create;
      for k := 0 to oJField.Count - 1  do
         gDSet.DArr[ i ].Add( oJField.GetValue( oJField.Pairs[ k ].JsonString.Value ).Value  );   // 페어명 해당 데이터 Read
    end;

  finally
    // 데이터 종류별 화면 처리 분기 ------------------------------
    if pInfo = '/querytb' then
       StringGrid_Write( StringGrid1, gDSet )

    else if pInfo = 'ERROR_MSG' then
       LogMemo.Lines.Add( GDSet.DArr[0][0] );

    oJRson.Free;
  end;
end;

 

TStringGrid 에 Json 데이터를 출력하기 위한 프로시져는 아래와 같이 구성 하였습니다.

//---------------------------------------------------------------------------------------------
// Json Data =>  TStringGrid
procedure TMCForm.StringGrid_Write( TargetGrid : TStringGrid; GDSet : GDListType );
var
  i, k, j, rc : Integer;
begin
  rc := high( GDSet.DArr ) + 2;           //  High(GDSet.DArr) 는 배열 최고값 + 1 = 배열전체수   + 1 (컬럼헤드 자리) =  row Count

  // 컬럼 헤더 타이틀 출력 ----------
  for i := 0 to GDSet.CNo - 1  do
    TargetGrid.Cells[ i+1, 0 ] := GDSet.CHeadName[ i ];

  // 데이터 출력 ------------------
  TargetGrid.RowCount := rc;

  for k := 0 to rc - 2 do  // 헤드타이틀 제외 하므로 -2
  begin
    TargetGrid.Cells[ 0, k+1 ] := (k+1).ToString;  // Grid 자체 인덱싱 표시
    for j := 0 to GDSet.CNo - 1 do
        TargetGrid.Cells[ j+1, k+1 ] := GDSet.DArr[ k ][ j ];   // TStringList의 동적배열 이므로 2차원 배열
  end;
end;

 

실행 결과.

image.png

 

 

이 댓글 링크
다른 사이트에 공유하기

  • c2design changed the title to 멀티플랫폼 3티어 REST Client Application 구현 방법

이 토의에 참여하세요

지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.

Guest
이 토픽(기고/질문)에 답하기

×   서식있는 텍스트로 붙여넣기.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   이전에 작성한 콘텐츠가 복원되었습니다..   편집창 비우기

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

중요한 정보

이용약관 개인정보보호정책 이용규칙 이 사이트가 더 잘 작동하기 위해 방문자의 컴퓨터에 쿠키가 배치됩니다. 쿠키 설정 변경에서 원하는 설정을 할 수 있습니다. 변경하지 않으면 쿠키를 허용하는 것으로 이해합니다.