프로젝트에서 AWS와 노드로 서버를 구성하고
안드로이드 클라이언트 Retrofit2 통신에서 평소 @Field를 사용했는데, 계속 Json으로 서버에서 못받고 이상한 값이 넘어오는 현상이발생했다.
서버문제인지 클라이언트의 모델 문제인지 무슨 문제인지!!!!!! 삽질을 꽤 오래하고 틀리지도 않는 부분을 고쳐댔다........
(에러도 안나고 서버쪽에 값이 이상하게 들어가기만해서 몇줄이 틀렸는지 알 수가 없었다.ㅠ.ㅠ)
원인은 Retrofit2 인터페이스가 잘못되었었다. 먼저 요점만 말하면 @Field가 아니라 @Body를 사용해야했다. 덕분에 둘의 차이점을 알아보는 시간을 가지고 포스팅을 하게 되었다.
사건 배경(처음에 실수한 코드 사진)
밑과 같이 Json으로 보낼려고 했다.
(DTO, POJO)
Routes 클래스이다. Routes객체의 리스트를 갖고있다.
Route이다. 실질적인 값들이 들어가 있다.
Retrofit2 인터페이스 부분인데 결론적으로 이부분의 @Field가 잘못의 원인이었다.
통신 코드이다.
고친것 : 인터페이스의 Field를 Body로 고치고 Body는 FormUrlEncoded를 사용하지 않으므로 지운다.
수정된 코드
만약 Field로 할거면 다음과 같이해도 될 것 같다.(이건 실험안해봤습니다.)
@FromUrlEncoded
@POST("/route/createRoute")
Call<Routes> saveMyRoute(
@Field("routes") List<Route> routes;
);
이제 @Body와 @Field의 차이점을 알아보면 다음과 같다.
@Field
인자를 form-urlencoded 으로 보낼때 사용한다.
여기서 form-urlencoded는 key=value&key=value 와 같은 형태로 데이터를 전달하는 것을 말한다. ( 즉 키벨류 형식)
또한 레트로핏에서 @Field는 @FormUrlEncoded 와 함께 쓰인다.
다음은 예시다. 키 벨류 값이 들어갈 것으로 볼 수 있다.
P.S 만약 User의 멤버변수가 밑에처럼 6개를 가지고 있다면 saveUser를 Body형식으로 바꾸면
@Body User user로 바꿀수도 있을 것이다.
@Body
서버에서는 유일한 매개 변수로 받고, 클라이언트에서 Java Object를 통째로 직렬화 해서 보낼때 사용한다.
Java Object를 직렬화해서 보낼 수 있는것은, Retrofit이 Gson 컨버터와 함께 쓰이기 때문이다.
@Body RequestPut parameters : 통신을 통해 전송하는 값이 특정 JSON 형식일 때 그러한 형태를 매번 만들지 않고 객체를 통해서 넘겨주는 방식입니다. 이러한 방식에서는 @Body라는 Annotation을 사용합니다. (PUT뿐만 아니라 다른 통신 방식에서도 마찬가지로 사용가능합니다)
즉 내가 만든 객체를 Json형식으로 넘겨줄때 밑과같은 Json형식처럼 넘겨주고 싶을 때 간편하게 사용할 수 있다. (진짜 쉽게말하면 그냥 객체쉽게 json 형식으로 보낼때 사용한다고 생각하자)
수정된 코드
이상 포스팅을 마치겠습니다.
감사합니다.!
원글 출처 : https://youngest-programming.tistory.com/135
해당 글의 출처 및 참고:
'Back-End > 그 외' 카테고리의 다른 글
[Lombok] Lombok @Getter,@Setter Annotation 인식 안됨 [해결] (0) | 2023.02.10 |
---|---|
eclipse로 개발할 때 maven으로 다운받은 jar의 소스와 javadoc을 자동으로 붙이기 (0) | 2023.02.10 |
[Android] 사설 SSL 인증서를 이용한 https 통신 (0) | 2023.02.09 |
[Android] Retrofit2 GET, POST 로 API 호출해서 JSON 데이터 받아오기 (0) | 2023.02.09 |
[Android] Android에서 SpringBoot JPA 서버와 연동하기 (0) | 2023.02.09 |