본문 바로가기
Android Studio(Java)

Android Studio Retrofit (3)

by 히예네 2023. 3. 19.
728x90
반응형

내가 쓴 글씨를 서버로 전송해보자. (1,2는 내가 서버에서 받는거만 함. )

 

https://kofathena.tistory.com/41

 

Android Studio Retrofit (1)

step1. 사전작업 : 라이브러리 3개 추가, 뷰바인딩 Retrofit2버전을 쓰려면 라이브러리에 3개를 추가해줘야한다. (세트라고 생각하면 된다. ) ※ 구글 볼리도 많이 쓴다. 라이브러리명 회사명 기능 retr

kofathena.tistory.com

https://kofathena.tistory.com/42

 

Android Studio Retrofit (2)

https://kofathena.tistory.com/41 Android Studio Retrofit (1) step1. 사전작업 : 라이브러리 3개 추가, 뷰바인딩 Retrofit2버전을 쓰려면 라이브러리에 3개를 추가해줘야한다. (세트라고 생각하면 된다. ) ※ 구글 볼

kofathena.tistory.com

 


step2-3. GET방식으로 서버에 값을 전달하는 작업해보기 @Query

인터페이스를 작성해보자. (요구사항을 적어두는 추상메소드. 허나 코드를 쓰는게 아니다. GET방식 등을 정보를 알려주는 인터페이스이다. )

@GET("Retrofit/getTest.php") 
//(경로/파일명) 내 여기에 데이터를 getTest.php에 전달할것이다.
Call<Item> getMethodTest(@Query("name") String name, @Query("msg") String message); 
//인터페이스, @Query는 ?와 = 을 자동으로 나타내줌

내가 보낸 데이터를 php파일에 넣자. 서버쪽에 이름과 메세지를 보낼것이다.

스트링 2개를 전달받자. (문자열을 서버에 2개를 보내자)

(String name, String message);

하지만 이렇게보면 알아보기 힘들기때문에 식별자를 쓰자.

(@Query("name") String name, @Query("msg") String message)

→ 이게 값전달하는 쿼리이다.

이제 내가 서버에 보낼 데이터를 String에 입력해서 보내자.

void clickBtn3(){
        //12. GET방식으로 값을 서버에 전달
        //서버에 보낼 데이터 만들기
        String name = "홍길동";
        String message = "배고프당 ";
        //url인코더안해도 된다. 레트로핏이 다해준다.

        //12. (1) Retrofit 객체 생성 - 객체생성하는 명령을 다른 class에 만들어두자. 
        Retrofit retrofit = RetrofitHelper.getRetrofitInstance();
				//RetrofitHelper는 new할 필요없다. static이니까 바로 메소드를 가져온다. 

        //12.(2) Service 인터페이스 설계. 요구 명세서 추상메소드 사용
        //getMethodTest()

        //12. (3) Service 인터페이스 객체 생성
        RetrofitService retrofitService = retrofit.create(RetrofitService.class);
					//retrofit아 설계도를 보고 대신 만들어줘 

        //12.(4) 원하는 작업 추상메소드 호출 [서버로 보낼 값 파라미터로 전달]
        Call<Item> call = retrofitService.getMethodTest(name,message); //이순간 네트워크작업이 되는게아니다. 네트워크 해주는 객체를 만든다. Call
				//네트워크 작업을 할수있는 코드가 쓰인 Call객체를 만들자 					

        //12.(5)
        call.enqueue(new Callback<Item>() {
            @Override
            public void onResponse(Call<Item> call, Response<Item> response) {
                Item item = response.body();
                binding.tv.setText(item.name+"-"+item.msg);
                //13. 이제 php파일 만들자
            }

            @Override
            public void onFailure(Call<Item> call, Throwable t) {
                binding.tv.setText("error : "+t.getMessage());
            }
        });
    }
public class RetrofitHelper {

    public static Retrofit getRetrofitInstance(){ //void가 아니다. Retrofit을 리턴한다. static은 객체를 만들지 않아도 함수만써도 되게한다.
        
	//리턴 타입 : Retrofit , 혹시 패키지가 다른곳에서도 쓸수있으니까 public
	//객체 생성 안하고 함수를 쓸 수 있게끔 static 설정한다. 
				Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl("http:------------.co.kr");
        builder.addConverterFactory(GsonConverterFactory.create());
        Retrofit retrofit = builder.build();

        return retrofit;
    }
}
<?php
    header('Content-Type:application/json; charset=utf-8');

    $name= $_GET['name'];
    $message= $_GET['msg']; //인터페이스에 적은 식별자와 같아야한다.  

    //잘 받았는지 확인하기 위해 안드로이드 쪽으로 다시 응답 echo
    //단, 안드로이드에서 응답결과를 json 형식으로 받아 처리하도록 되어 있음.
		//지금 레트로핏으로 하고있는데..응답을 Item으로 받을건데? (gson하겠다는뜻)
		//근데 json이 아니면 파싱이 안된다. 그럼 내가 php만들때 json으로 만들어야함. 

    //php언어는 연관배열을 json으로 쉽게 바꿔줌
    //echo할 데이터값 $name, $message를 연관배열로 만들기
    $arr= array(); //빈 배열 하나 만들자
    $arr['name']= $name;
    $arr['msg']= $message;

    //연관배열 --> json문자열
    echo json_encode($arr); //encode : 배열을 코드화 시켜줘라 

?>

header에는 php의 정보를 쓴다.

Content-Type:application/json; 내가 echo시켜주는건 json이다.

charset=utf-8 나는 유니코드를 쓰겠다.

echo json_encode($arr); //encode : 배열을 코드화 시켜줘라

step2-4. Map Collection을 이용하여 한방에 값 전달하기

보내는 값이 2개가 아니라 20개라면? 파라미터 값을 다 넣어줘야하는데 그거는 너무 불편하다.

값을 보낼 때 여러개를 한번에 보낼 수도 있다. Map Collection (대량의 데이터를 저장하기 위한 class들)을 이용하자. (연관배열)

@GET("Retrofit/getTest.php")
Call<Item> getMethodTest2(@QueryMap Map<String,String> datas); 
//@Query()는 하나씩 보내는거 이거는 ()안에 식별자를 써준다.
//한꺼번에 Map으로 받는다. 얘도 제네릭이있다. <식별자, 값>  서버로 전달될때 여러개를 한꺼번에 보낸다는 뜻으로 @QueryMap을 쓴다.
void clickBtn4(){
        //14 GET방식으로 전달할 데이터들을 Map Collection으로 한방에 보내기
        //보낼 데이터들을 Map객체로 만들기 ,인터페이스니까 Map은 그냥 쓸 수없다 그걸 상속받은 HashMap을 데려온다.
        //ArrayList도 List를 상속받은 녀석이다.
        //Map도 제네릭을 끌고다닌다. <식별자, 값>이 무슨 형태인지 알려주자. 
        HashMap<String, String> datas = new HashMap<>();
        datas.put("name","Robin"); //식별자를 주세요 
        datas.put("msg","sleep"); //값을 주세요.

        //14.(1) Retrofit객체 만들기
        Retrofit retrofit = RetrofitHelper.getRetrofitInstance();

        //14 (2) Service 인터페이스와 추상메소드 설계. 이미 getMethodTest2()로 만듬
        //14 (3) Service 인터페이스 객체 생성
        RetrofitService retrofitService = retrofit.create(RetrofitService.class);
        //14 (4) 원하는 작업 추상메소드를 호출
        Call<Item> call = retrofitService.getMethodTest2(datas);

        //14 (5) 작업시작
        call.enqueue(new Callback<Item>() {
            @Override
            public void onResponse(Call<Item> call, Response<Item> response) {
                Item item = response.body(); //아이템으로 곧바로 파싱되서 옴
                binding.tv.setText(item.name+" , "+item.msg);
            }

            @Override
            public void onFailure(Call<Item> call, Throwable t) {
                binding.tv.setText("error : "+t.getMessage());
            }
        });
    }

보낼 데이터들을 Map객체로 만들기 ,인터페이스니까 Map은 그냥 쓸 수 없다. 그걸 상속받은 HashMap을 데려온다. ※ArrayList도 List를 상속받은 녀석이다. Map도 제네릭을 끌고다닌다. <식별자, 값>이 무슨 형태인지 알려주자.

step2-5. POST방식으로 값 전달하기 @Body

@POST("Retrofit/postTest.php") //아직 안만들엇어
Call<Item> postMethodTest(@Body Item item); 
//그걸 갖고잇는 아이템을 통째로 보내자
//이작업을 하려면 이미 GSON이 있어야한다.

POST로 보내는 방식으로 값 전달

서버로 보낼 데이터를 객체를 아예 전달한다. 객체를 전달하면 이 객체의 멤버변수를 json문자열로 변환하여 서버로전송한다 → [@Body]

내가 전달할 Item 객체를 미리 준비해야한다. 이 작업을 하려면 @Body를 써줘야한다.

@Body는 왜 () 생성자가 없을까? Item에 이미 변수가 있으니까(변수의 이름이 자동 식별자가 됨)

public class Item {

    String name;
    String msg;

    public Item(String name, String msg) {
        this.name = name;
        this.msg = msg;
    }

    public Item() {
    }
}
void clickBtn5(){
      
        Item item = new Item("kim","flower");
        //POST방식으로 전달 값을 아예 객체로 만든다 . 
				//Retrofit이 자동으로 객체를 json 문자열로 변환하여 전송함.

        
        Retrofit retrofit = RetrofitHelper.getRetrofitInstance();
      
        RetrofitService retrofitService = retrofit.create(RetrofitService.class);
     
        Call<Item> call = retrofitService.postMethodTest(item); 
				//@Body를 줘! 이 item은 내가 43번줄 아이템
    
        call.enqueue(new Callback<Item>() {
            @Override
            public void onResponse(Call<Item> call, Response<Item> response) {
                Item i = response.body(); //아이템으로 곧바로 파싱되서 옴
                binding.tv.setText(i.name+"        "+i.msg);
            }

            @Override
            public void onFailure(Call<Item> call, Throwable t) {
                binding.tv.setText("error : "+t.getMessage());
            }
        });

    }

Item item = new Item("kim","flower"); POST방식으로 전달 값을 아예 객체로 만든다 . Retrofit이 자동으로 객체를 json 문자열로 변환하여 전송함.

<?php
    header('Content-Type:application/json; charset=utf-8');

    //@Body로 보낸 json문자열은 $_POST라는 배열에 자동 저장되지 않음.
    //$name= $_POST['name'];

    //json으로 넘어온 데이터는 별도의 임시공간[php://input]에 파일로 보관되어 있음.
    //이 파일을 읽어서 $_POST 배열변수에 대입해주기
    $data= file_get_contents('php://input');
    //사실 여기서 echo해도 상관없다. 이미 여기서 json으로 만들어졌으니까
		//파일에서 데이터를 읽어와. 툭하니 리턴 받는다. 
    //$data는 json으로 된 문자열(당연한 결과 내가 json으로 던졌으니까)

    $_POST= json_decode($data, true); 
//$_POST라는 배열에 $data(json문자열)을 decode해줘
//true:연관배열로 할지 여부
//$_POST배열에 넣었다 !!!!!!

    $name= $_POST['name'];
    $message= $_POST['msg'];

    // 잘 받았는지 확인해보기 위해 안드로이드로 echo
    // 안드로이드는 json으로 보내줘야 하기에..

//빈 배열 만들고 POST로 전달받은 값(json)들을 다시 배열에 넣는다. 
//그 안에 name과 message를 넣는다.
    $arr= array();
    $arr['name']= $name;
    $arr['msg']= $message;

    // 응답 : json으로 인코딩해서 $arr을 보낼것이다. 
    echo json_encode($arr);

?>

step2-6. POST방식으로 값 하니씩 전달하기 @Field

내가 서버를 보낼때 json으로 보내야한다. 그거뿐만 아니라 객체를 보내면 자동으로 json으로 보내고 이럴때면 Gson이 항상 준비가 되어있어야한다. 그래서 이번엔 하나씩 보내보자

@FormUrlEncoded //글을보낼때는 @FormUrlEncoded
@POST("Retrofit/postTest2.php")
Call<Item> postMethodTest2(@Field("name") String name, @Field("msg") String message); 
//단 @Field를 사용하려면 반드시 @FormUrlEncoded와 함께 지정

식별자를 명시할 때 @Field( )를 쓴다. (쿼리문과 비슷해)

단, **@Field( )**를 쓰고싶다면 반드시 @FormUrlEncoded를 수반해야한다.

※POST방식은 기본을 바디로 권장함. 그러면 gson을 써야함.

이미지였으면 @Multipart

POST방식으로 개별 데이터(String)를 보내자.

void clickBtn6(){
      
        String name = "suzume";
        String message = "have a good day";

        Retrofit retrofit = RetrofitHelper.getRetrofitInstance();
        RetrofitService retrofitService = retrofit.create(RetrofitService.class);
        Call<Item> call = retrofitService.postMethodTest2(name,message);
        call.enqueue(new Callback<Item>() {
            @Override
            public void onResponse(Call<Item> call, Response<Item> response) {
                Item item = response.body(); //아이템으로 곧바로 파싱되서 옴
                binding.tv.setText(item.name+" ~ "+item.msg);
                //여태 json객체를 받아오기만햇다. 19부터는 Arraylist로도 받아보자
            }

            @Override
            public void onFailure(Call<Item> call, Throwable t) {
                binding.tv.setText("error : "+t.getMessage());
            }
        });

    }
<?php
    header('Content-Type:application/json; charset=utf-8');
    
    $name= $_POST['name'];
    $message= $_POST['msg'];

    // 잘 받았는지 확인해보기 위해 안드로이드로 echo
    // 안드로이드는 json으로 보내줘야 하기에..
    $arr= array();
    $arr['name']= $name;
    $arr['msg']= $message;

    // 응답 : json으로..
    echo json_encode($arr);

?>

step2-7. GET방식, JSONArray값 읽어와서 바로 ArrayList<Item>로 곧바로 파싱

@GET("Retrofit/boardArr.json")
    Call<ArrayList<Item>> getBoardArray();

//아이템이 하나가 아니라 여러개임! 그래서 ArrayList를 쓴다. 

[
    {"name":"sam", "msg":"Hello"},//아이템 1
    {"name":"robin", "msg":"Nice"}, //아이템 2
    {"name":"hong", "msg":"Good"} //아이템 3
]
//아이템이 하나가 아니라 여러개임! 그래서 ArrayList를 쓴다. 
void clickBtn7(){
        //20. JsonArray를 읽어와서 곧바로 ArrayList<Item>으로 파싱

        Retrofit retrofit = RetrofitHelper.getRetrofitInstance();
        RetrofitService retrofitService = retrofit.create(RetrofitService.class);
        Call<ArrayList<Item>> call = retrofitService.getBoardArray();
        call.enqueue(new Callback<ArrayList<Item>>() {
            @Override
            public void onResponse(Call<ArrayList<Item>> call, Response<ArrayList<Item>> response) {
                ArrayList<Item> items = response.body(); //아이템으로 곧바로 파싱되서 옴
                binding.tv.setText("아이템 갯수 : "+items.size());
            }

            @Override
            public void onFailure(Call<ArrayList<Item>> call, Throwable t) {
                binding.tv.setText("error : "+t.getMessage());
            }
        });
}

step2-8. 그냥 문자열로 응답결과를 받아보기( GSON- 자동으로 Item객체로 파싱하지 않고 )

@GET("Retrofit/board.json")
    Call<String> getJsonString();
void clickBtn8(){
        //22. 서버의 응답결과가 json이 아닐때 사용..
        //서버의 응답결과를 그냥 String으로 받아보기 [ No parse ]
        //결과를 String으로 받으려면 ScalarsConverter 필요 - 추가 라이브러리가 필요하다. 추가하고와 converter-scalars
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl("http:--------------------co.kr");
        builder.addConverterFactory(ScalarsConverterFactory.create()); 
				//반영안될수도잇으니까 그냥 손으로 써라
        Retrofit retrofit = builder.build();

        RetrofitService retrofitService = retrofit.create(RetrofitService.class);
        Call<String> call = retrofitService.getJsonString();
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                String s = response.body();
                binding.tv.setText(s); //이건 파싱안하고 그냥 글씨만 보는거임
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                binding.tv.setText("error : "+t.getMessage());
            }
        });
    }
728x90
반응형