HttpURLConnection 을 이용한 데이터 전송(POST)

황씨·2024년 4월 19일
post-thumbnail

개발자로 취업한 뒤 이제 수습이 끝났다.
첫 글을 써보려고 한다.
내가 사용했던 코드들을 정리하면 다음에 다시 보면서 공부도 하고,
다시 쓸 때에도 도움이 될 것 같다.
(틀린 점이 있을 수도 있지만,, 알게될 때마다 고쳐야지..)

🚩 고객사 서버쪽으로 데이터를 보내야할 일이 생겼다.

처음에 GET 방식으로 요구를 했고,
보내야할 Key 값들과 데이터 포맷들을 전달 받았다.

그리고 구현을 했지만 변경이 되어야 할 것 같다고
POST 방식으로 바꾸게 되었다 FormData 형식으로 달라고하네,,

단말기에 태깅을 하였을 때 카드에 있는 태깅 정보를 고객사 서버로 넘겨줘야하는 로직인데
근데 컨트롤러에서 거쳐야할 로직들이 많아서 코드를 쳐서 구현을하니
속도 때문인지 이유는 정확하게 모르지만
태깅이 많이 들어오게 되면 중간에 멈추는 현상이 일어났다.

그래서 고민을 하던중 내가 생각한건,,
runnable jar 파일을 따로 돌려주는 프로젝트를 새로 생성하였다.

try {
		service.insertTagdataTransfer(paramMap2);
			boolean isLinux = System.getProperty("os.name").toLowerCase().startsWith("linux");
			Process process;
			if (isLinux) 
			{
				try {
				System.out.println("일로 들어왔음");
				String command = String.format("java -jar /home/gnbismngr/apps/datasender/DataSender2.jar \"%s\" \"%s\" \"%s\" \"%s\"", paramMap2.get("cardLoc").toString(), paramMap2.get("originDestination").toString(), paramMap2.get("cardUid").toString(), paramMap2.get("tagTime").toString());
				System.out.println("실행 명령: " + command); // 실행 명령이 올바르게 구성되었는지 확인
				process = Runtime.getRuntime().exec(command);

			    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			    String line;
			    while ((line = reader.readLine()) != null) {
			        System.out.println("Runnable 파일 콘솔값 : "+line);
			    }

			    // 프로세스의 에러 출력도 캡처하여 콘솔에 출력
			    BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
			    String errorLine;
			    while ((errorLine = errorReader.readLine()) != null) {
			        System.out.println("Error: " + errorLine);
			    }

			    // 프로세스가 종료될 때까지 대기
			    int exitCode = process.waitFor();
			    System.out.println("프로세스 종료 코드: " + exitCode);
			    
				}catch (IOException e) {
				    e.printStackTrace();
				}
			} 
	} catch (Exception e) {
		e.printStackTrace();
	}

우선 DB에 태깅정보를 저장하고,

리눅스 서버에 jar파일을 올려놓고 태깅 될 때 마다 해당 API를 타고 와서
실행시키는 방법으로 구현을 해보았다.

그리고 jar 파일이 잘작동하는지 콘솔에 찍어보고 싶어서
버퍼를 이용해서 콘솔에 결과값이 나오도록 해놨다.

이제 해당 runnable jar파일을 뽑아낸 프로젝트에 코드이다.

 Map<String, String> formData = new HashMap<>();
 
 String cardLoc = args[0];
 String originDestination = args[1];
 String cardUid = args[2];
 String tagTime = args[3];

넘겨준 인자를 받아서 변수에 담아주는 작업을 한다.

formData.put("area", sPass_gb);
formData.put("course", sCos);
formData.put("keyId", sKey_id);
formData.put("time", sTime);

formData에 담아주고,

 String url = "http://apiURL을 넣는다";
 
 // URL객체 생성
 URL apiUrl = new URL(url);
 //URL 객체사용해서 HTTP 연결 오픈, 나중에 HTTP 요청보내는데 사용함
 HttpURLConnection connection = (HttpURLConnection) apiUrl.openConnection();
 connection.setRequestMethod("POST");	
 connection.setRequestProperty("X-Authorization", "인증 토큰 값");
 //HTTP 요청에서 데이터를 전송할 수 있도록한다.
 connection.setDoOutput(true);
 
 // 연결을 통해 데이터를 전송하는데 사용되는 출력 스트림을 연다.
 try (OutputStream os = connection.getOutputStream()) {
            	//Post 요청에 포함된 데이터를 구성하는 StringBuilder 객체를 생성한다.
                StringBuilder postData = new StringBuilder();
                //formData 맵의 각 항목을 반복한다.
                for (Map.Entry<String, String> entry : formData.entrySet()) {
                	System.out.println("formData : " + formData);
                	// 이미 postData에 데이터가 추가된 경우, 항목들을 '&'구분한다.
                    if (postData.length() != 0) {
                        postData.append('&');
                    }
                    // 키와 값을 URL 인코딩 하고, '='로 연결하여 postData에 추가한다.
                    postData.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
                    postData.append('=');
                    postData.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
                    System.out.println("postData : "+ postData);
                }
                //구성된 데이터들을 바이트 배열로 반환한다.
                byte[] postDataBytes = postData.toString().getBytes(StandardCharsets.UTF_8);
                System.out.println("postDataBytes : " + postDataBytes);
                // 바이트 배열을 출력 스트림에 쓴다. 이는 서버로데이터를 전송하는 과정
                os.write(postDataBytes);
            }
//서버로 부터 받은 HTTP응답 코드를 가져온다.
int responseCode = connection.getResponseCode();
//응답 코드가 HTTP_OK(200) 인 경우 , 요청이 성공적으로 처리되었음을 의미한다.
if (responseCode == HttpURLConnection.HTTP_OK) {
            		updateDatabase(1,cardUid,tagTime);
	                // 응답 본문 읽기 위해 BufferedReader 를 생성한다.
	                try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
	                    StringBuilder response = new StringBuilder();
	                    String responseLine;
	                    // 응답 본문의 각 라인을 읽고, 전체 응답을 하나의 문자열로 구성한다.
	                    while ((responseLine = br.readLine()) != null) {
	                        response.append(responseLine.trim());
	                    }
	                    // 응답 내용 콘솔에 출력
	                    System.out.println("HTTP POST 요청 결과: " + response.toString());
	                    // 응답을 파일에 기록
	                    try (FileWriter fileWriter = new FileWriter("output123.txt")) {
	                        fileWriter.write(response.toString());
	                    } catch(IOException e ) {
	                    	e.printStackTrace();
	                    }
	                }
            } else {
	            	System.out.println("HTTP POST 요청 실패. 응답 코드: " + responseCode);
	            	updateDatabase(0,cardUid,tagTime);
            }
            connection.disconnect();

updateDataBase는 아까 태깅정보를 인서트 했었는데
그 테이블에 태깅정보가 잘넘어갔는지 안넘어갔는지 플래그 처리를 해주기 위해 하는 작업이다.

정리

단말기에 태깅했을 때 컨트롤러에 태깅 API로 들어오게 되고 해당 API에서 특정 경로에 있는 jar파일을 실행시키도록 하였고,
그 jar파일에서는 HttpURLConnection을 통해서 필요한 데이터들을 넘겨주고 있다.

부족한 점

jar 파일을 실행시킬 때 console에 print 라도 찍어서 보고 싶었는데,
볼 수 있는 방법을 몰라 시간이 좀 걸렸는데 버퍼에 담아 출력스트림으로 jar파일을 실행시키는
본 프로젝트에서 로그내용들을 볼 수 있게 하였다.
부족한 점들이 너무너무너무 많치만 차근차근 한단계씩 밟아가봐야할듯.

profile
성격존나급한 개발자

0개의 댓글