내가 쓴 글씨를 서버로 전송해보자. (1,2는 내가 서버에서 받는거만 함. )
https://kofathena.tistory.com/41
https://kofathena.tistory.com/42
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());
}
});
}
'Android Studio(Java)' 카테고리의 다른 글
Android Studio Firebase를 이용하여 채팅방 만들기 (1) | 2023.03.20 |
---|---|
Android Studio Retrofit (2) (0) | 2023.03.16 |
Android Studio Retrofit (1) (0) | 2023.03.16 |
Android Studio BackEnd (0) | 2023.03.10 |
Android Studio Fragment랑 FragmentActivity 차이점 (0) | 2023.03.06 |