URI (별칭식 경로 : Uniform Resource Identifier 통합 자원 식별자)
URI는 특정 리소스를 식별하는 경로를 의미한다. 웹 기술에서 사용하는 논리적 또는 물리적 리소스를 식별하는 고유한 문자열 시퀀스다.

URL (절대 경로 : Uniform Resource Locator 또는 통칭 web address)
URL은 흔히 웹 주소라고도 하며, 컴퓨터 네트워크 상에서 리소스가 어디 있는지 알려주기 위한 규약이다. URI의 서브셋이다.

 

POST 방식은 기본 (URL)에 요청할 때 BODY 부분에 데이터를 넘겨주는 방식입니다.

Spring 공부를 하면 해당 API 들을 직접 호출 및 테스트 해볼 수 있게 만들면 좋겠네요.

POST 방식은 코드만 올리겠습니다.

1개 보내는 방식, multipart 로 2개 이상의 다른 데이터 보내는 방식입니다.

using System;
using System.IO;  //Stream
using System.Net; //HttpWebRequest, WebRequest 등 사용
using System.Windows.Forms;

using System.Net.Security; //SSL (Secure Sockets Layer) 관련
using System.Security.Cryptography.X509Certificates; //암호화 된 인증서 관련
using System.Text;

namespace WindowsFormsApp_POST_HttpRequest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            PostRequest();
        }

        private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            //인증서에 대한 결과를 보려면 여기서 브레이크 걸고 certificate, chain 등을 살펴보면 됩니다.
            //권장하지 않는 방법이지만 인증 기관에 대해 true로 설정해둡니다.
            return true;
        }

        private void PostRequest()
        {
            //****************************** 이 부분은 첫 사용하기 전에만 넣어주면 됩니다. ***********************************
            //웹 통신 시 System.Net.WebException : 기본 연결이 닫혔습니다. 관련 에러 방지용 프로토콜 정의입니다.
            //Secure Sockets Layer, Transport Layer Secure
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
                                                   SecurityProtocolType.Tls11 |
                                                   SecurityProtocolType.Tls12 |
                                                   SecurityProtocolType.Ssl3;

            //https (hyper text transfer protocol Secure : 전송 규약 보안) 보안이 올바른지 확인하는 구문입니다. 
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
            //****************************************************************************************************************

            //[ContentType] : Body에서 전송되는 콘텐츠의 유형을 서버에 알려줍니다.
            //                MIME (Multipurpose Internet Mail Extensions) 표준을 따릅니다.
            //
            //ex)
            //1. multipart/form-data            2개 이상으로 한 번에 보낼 때 boundary와 함께 사용
            //2. application/json               제이슨 형태
            //3. application/x-www-urlencoded   기본 타입
            //4. image/tiff                     이미지, 확장자
            //   등 등

            //한 개의 데이터를 POST 방식으로 보내기
            PostRequestOne();

            //2개 이상의 데이터를 POST 방식으로 보내기
            //multipart/form-data 방식으로 사용되며 줄 구분을 위한 boundary가 필요   
            PostRequestAll();
        }

        private void PostRequestOne ()
        {
            string uri = textBox_uri.Text;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);   //요청 준비
            HttpWebResponse response = null;

            try
            {
                request.Method = "POST"; //기본 값은 GET 입니다.
                request.ContentType = "application/x-www-form-urlencoded"; //url encoded 방식 변수=값&변수1=값..

                string userName = "name";
                string password = "1234"; //서버와 협의하여 해쉬 등으로 암호화
                string data = string.Format("userName={0}&password={1}", userName, password);

                //request body에 데이터 채우기
                byte[] buffer = Encoding.UTF8.GetBytes(data);
                Stream requestStream = request.GetRequestStream(); //request에 보낼 데이터 입력용
                requestStream.Write(buffer, 0, buffer.Length);
                requestStream.Close();

                //응답 결과 받기
                response = (HttpWebResponse)request.GetResponse();
                Stream responseStream = response.GetResponseStream();
                StreamReader responseStreamReader = new StreamReader(responseStream);

                //응답 값 받아서 리턴하거나 사용하면 됩니다.
                string result = responseStreamReader.ReadToEnd();

                responseStreamReader.Close();
                responseStream.Close();
                response.Close();
            }
            catch (Exception ex)
            {
                //로그 남기면 좋을 듯
                MessageBox.Show("Request Error" + Environment.NewLine + ex.ToString());
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
        }

        private void PostRequestAll ()
        {
            string uri = textBox_uri.Text;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);   //요청 준비
            HttpWebResponse response = null;

            try
            {
                request.Method = "POST"; //기본값은 GET
                                         //그 밖에도 timeout, credential 등 다양한 옵션을 줄 수 있습니다.

                //https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
                //2개 이상 multipart로 보내는 방법
                //보낼 값) field1 = value, 파일 = byte file

                //경계를 통해 데이터 타입 명시 및 다음과 같은 형태로 만들어서 보내면 됩니다.
                /*
                    Content-Type: multipart/form-data; boundary=isBoundary
                
                    --isBoundary
                    Content-Disposition: form-data; name="field1"

                    value
                    --isBoundary
                    Content-Disposition: form-data; name="파일"; filename="myImage.tiff" (filename은 부가적인 부분으로 없어도 된다고 봤네요.)
                    Content-Type: image/tiff (타입에 대한 명시 필요)

                    byte file
                    --isBoundary-- (경계의 끝은 -- 붙여주기)
                 */

                string endLine = "\r\n";            //웹에서 개행을 나타내는 문자열입니다. 
                string boundary = "isBoundary";     //구분자입니다. --isBoundary ~ --isBoundary-- 로 끝나게 됩니다.

                request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
                byte[] boundaryBytes = Encoding.ASCII.GetBytes(endLine + "--" + boundary + endLine);

                Stream requestStream = request.GetRequestStream();
                requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                //
                //--isBoundary
                //

                string field1 = "field1";
                string value = "value";
                string data = string.Format("Content-Disposition: form-data; name=\"{0}\"{1}{2}{3}", field1, endLine, endLine, value);
                byte[] dataBytes = Encoding.UTF8.GetBytes(data);

                requestStream.Write(dataBytes, 0, dataBytes.Length);
                //[진행 현황]
                //
                //--isBoundary
                //Content-Disposition; form-data; name="field1"
                //
                //value

                requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
                //[진행 현황]
                //
                //--isBoundary
                //Content-Disposition; form-data; name="field1"
                //
                //value
                //--isBoundary
                //

                string name = "파일";
                string filename = "myImage.tiff";

                string data2 = string.Format("Content-Disposition: form-data; name=\"{0}\" filename=\"{1}\"{2}Content-Type: image/tiff{3}{4}",
                                                name, filename, endLine, endLine, endLine);
                byte[] data2Bytes = Encoding.UTF8.GetBytes(data2);

                requestStream.Write(data2Bytes, 0, data2Bytes.Length);
                //[진행 현황]
                //
                //--isBoundary
                //Content-Disposition; form-data; name="field1"
                //
                //value
                //--isBoundary
                //Content-Disposition: form-data; name="파일" filename="myImage.tiff"
                //Content-Type: image/tiff
                //
                //

                //예시 경로 파일 바이트로 읽어서 보내기
                string imagePath = @"c:\temp\myImage.tiff";
                FileStream fileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
                byte[] imageBuffer = new byte[4096];
                int bytesRead = 0;
                while (true)
                {
                    bytesRead = fileStream.Read(imageBuffer, 0, imageBuffer.Length);
                    if (bytesRead <= 0) //이미지 바이트 다 읽은 경우
                    {
                        break;
                    }
                    requestStream.Write(imageBuffer, 0, bytesRead);
                }
                fileStream.Close();

                byte[] endBoundaryByte = Encoding.ASCII.GetBytes(endLine + "--" + boundary + "--" + endLine);
                requestStream.Write(endBoundaryByte, 0, endBoundaryByte.Length);
                //[진행 현황]
                //
                //--isBoundary
                //Content-Disposition; form-data; name="field1"
                //
                //value
                //--isBoundary
                //Content-Disposition: form-data; name="파일" filename="myImage.tiff"
                //Content-Type: image/tiff
                //
                //byte file
                //--isBoundary--

                response = (HttpWebResponse)request.GetResponse(); //요청 후 결과 반환
                Stream responseStream = response.GetResponseStream();   //요청에 대한 stream 가져오기
                StreamReader responseStreamReader = new StreamReader(responseStream); //해당 stream 읽기 위한 streamReader

                //응답값 받아서 리턴하거나 사용하면 됩니다.
                string result = responseStreamReader.ReadToEnd();

                responseStreamReader.Close();
                responseStream.Close();
                response.Close();
            }
            catch (Exception ex)
            {
                //로그 남기면 좋을 듯
                MessageBox.Show("Request Error" + Environment.NewLine + ex.ToString());
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }
        }
    }
}

 

+ Recent posts