Step-by-Step

[Spring] 9. 안드로이드 통신 - HttpUrlConnection 본문

프로젝트/Eggo (Mobile App)

[Spring] 9. 안드로이드 통신 - HttpUrlConnection

희주(KHJ) 2022. 5. 21. 01:54

안드로이드 스튜디오에서 Spring으로 데이터를 전송한 후 DB에 넣는 작업을 하려한다.

++ Retrofit2로 성공했다! 코드는 없지만 마지막에 간단히 설명하려고 한다

 

HttpURLConnection

HTTP 통신을 가능하게 해주는 클래스

- Header : 데이터 정보

- Body : 데이터

 

나는 Class를 만들어서 내부 메소드에 연결 코드를 저장하고.

Activity에서 객체 만들어서 호출하였다.

 

[Activity 부분 - POST]

Thread th = new Thread(new Runnable() {
               @Override
               public void run() {
                    SpringConnection sc = new SpringConnection();
                    UserDTO userDTO = new UserDTO(UserId,Name,Email,Password);
                    String Message = sc.HttpConnPOSTUser("Controller에 들어가는 Path", userDTO);
                    System.out.println(Message);
               }
           });
th.start();

- Button에 onClickListener를 넣어주어 오버라이드된 Onclick 메소드 안에 넣어주었다

- Thread를 생성하여 안에서 실행되며,  HttpConnPOSTUser은 메소드 이름이며 인자도 내가 설정한 파라미터대로 넣어준다

 

 

[POST]

public String HttpConnUser(String path, UserDTO userDTO) {

    // private static final 써서 전역 필드값으로 설정하기
    String HOST = "http://IP주소:포트번호";	
    
    public String HttpConnPOSTUser(String path, UserDTO userDTO) {
        String result = "";
        try {
	    String URL = HOST + path;		// 최종 URL 설정	
	    URL urls = new URL(URL);		// URL 객체 만들때, 생성자 인자로 URL 넣어주기
            
            HttpURLConnection conn = (HttpURLConnection) urls.openConnection();
            StringBuilder sb = new StringBuilder();	
            
            if (conn != null) {
                conn.setConnectTimeout(10000);			// 서버에 연결되는 TIMEOUT 설정
                conn.setRequestMethod("POST");			// HTTP 통신 방식 설정
                conn.setRequestProperty("Content-Type", "application/json");	// 보낼 타입
                conn.setUseCaches(false);				
                conn.setDoOutput(true);					// POST로 데이터 넘겨줄때 사용
                conn.setDoInput(true);					// InputStream으로 서버 응답 받음
                
                JSONObject jsonObject = new JSONObject();	// 보낼 데이터 JSONObject에 담기
                jsonObject.put("userId", userDTO.getUserId());
                jsonObject.put("name", userDTO.getName());
                jsonObject.put("email", userDTO.getEmail());
                jsonObject.put("password", userDTO.getPassword());
                
                OutputStream os = conn.getOutputStream();	//RequestBody에 Data 담기
                os.write(jsonObject.toString().getBytes());	//Data 세팅
                os.flush();			// RequestBody에 Data 입력
                
                if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {	//연결 성공시
                    
                    InputStream is = conn.getInputStream();
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] byteBuffer = new byte[1024];
                    int nLength;
                    while ((nLength = is.read(byteBuffer, 0, byteBuffer.length)) != -1) {
                        baos.write(byteBuffer, 0, nLength);
                    }
                    byte[] byteData = baos.toByteArray();
                    JSONObject responseJSON = new JSONObject(new String(byteData));
                    
                    // 필요한 정보 추출
                    result = responseJSON.get("Name").toString();
                    result = responseJSON.get("Message").toString();
                }
                // 연결 끊기
                conn.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

 

 

 

 

[Activity부분 - GET]

Thread th = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        SpringConnection sc = new SpringConnection();
                        String query = "?userId="+UserId;		//쿼리 만들어줌
                        String Message = sc.HttpConnGETUser("Controller path값"+query);
                        System.out.println(Message);
                    }
                });
th.start();

- 여기는 POST는 body에 담을 값도 넣어줬는데 여긴 그냥 쿼리로 만들어서 넣어줌

 

[GET]

 public String HttpConnGETUser(String path) {
        String result = "";
        try {
            String URLs = HOST + path;
            URL urls = new URL(URLs);
            HttpURLConnection conn = (HttpURLConnection) urls.openConnection();

            StringBuilder sb = new StringBuilder();
            if (conn != null) {
                conn.setConnectTimeout(10000);
                conn.setRequestMethod("GET");
                conn.setDoInput(true);	
                // GET은 Body에 담을 내용이 없어서 setOutput은 따로 설정 안함

                if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    InputStream is = conn.getInputStream();
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] byteBuffer = new byte[1024];
                    int nLength;
                    while ((nLength = is.read(byteBuffer, 0, byteBuffer.length)) != -1) {
                        baos.write(byteBuffer, 0, nLength);
                    }
                    byte[] byteData = baos.toByteArray();

                    JSONObject responseJSON = new JSONObject(new String(byteData));
                    result = responseJSON.get("Message").toString();
                }
                conn.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

 

 

++ 이런식으로 먼저 설정해 놓고, 팀원이 코딩하고 있는 안드로이드 코드 git clone해서 적용하려고 했는데,,

안드로이드는 렉이 엄~~~~청 심하고...ㅠㅠㅠㅠ 에뮬레이터는 작동도 하지 않고...흑흑

사실 이 부분은 내가 따로 새로운 프로젝트를 만들어서 해본 것이었다.

사실상 Java이니만큼 객체지향의 장점을 살리려면 retrofit으로 작성하는게 맞다!

 

 

Retrofit2로 최근에 성공했기 때문에 간략하게 말하면

1) @Body 형식으로 보내는 것은 직렬화 해서 보내지기 때문에 Spring에서 @RequestBody로 안읽혔다

- @Field를 이용하여 key - value 형식으로 보내고

- Spring에서는 @RequestBody 어노테이션을 제거하여 받았더니 성공하였다!

 

2) GET 방식은 Spring으로 받을 때 @RequestParam("key값")을 사용하였다

 

3) Spring으로 데이터를 보낼때는 key값을 소문자로 보내자

- 자꾸 null값이 들어오길래 구글링 해봤는데 

- Spring 은 JSON 데이터를 매핑하기 위한 Message Converter 로 Jackson 을 사용하고

- 내가 받는 DTO 부분을 lombok을 이용하면 이상한 제약이 생기게 된다 (아래 블로그 참조)

https://bcp0109.tistory.com/309

- 이부분은 중요하니 두고두고 봐야겠다!!!!!!!!!!!

 

4) 응답 메세지는 String으로 전해줬다

- org.json.simple의 JSONObject를 사용하면 응답 메세지가 잘 전달 되지 않았다 

- gson을 이용한 JsonObject를 이용하였다 (위의 JSONObject랑 다름 . 철자가 같아서 검색하기 힘들었다ㅠㅠ)

	Gson gson = new Gson();
	JsonObject resultJSON = new JsonObject();
	resultJSON.addProperty("message", "This ID is available.");
        
	return gson.toJson(resultJSON);

이런식으로 JsonObject에 값을 넣고 gson.toJson을 이용하여 return 하였는데, 해당 값의 타입은 String이다 ★

 

 

 

암튼  retrofit2은 성공하기만 하면 짱이다 

HttpUrlConnection은 연결은 정말 잘 되었지만, 코드가 너무 길다..

하지만 여러 데이터타입으로 주고받아도 에러가 거의 나지 않았다 그건 좋았음!

 

Comments