wafflestudio / seminar-2021

2021 Rookies 세미나
47 stars 110 forks source link

Android 과제 4번 signup POST body 전송 및 response에서 token을 추출하는 방법 #665

Closed JuTaK97 closed 2 years ago

JuTaK97 commented 2 years ago

요약

image

Signup의 POST에서는 이와 같이 Body에 form-data 형식으로 key-value들을 넣게 됩니다. 그런데 저 형식을 맞춰서 전송하는 방법을 모르겠습니다.



상황

오류와 400 bad request를 피해서 여러 방법을 시도해 보다가, 한 방법(밑의 4번)을 찾았는데 500 Internal Server Error 가 뜹니다. 제가 뭔가 잘못 보내준 결과 같은데 원인을 모르겠습니다.



문제 내용

시도해 본 건, 우선

  1. String 네 개로 된 data class를 만들고, 그 객체 params를 만든 후

    @POST("api/v1/signup/")
    fun signup(
        @Body params: RequestSignup
    ): Call<FetchSignup>

    로 전송 : 400 bad request

  2. 위의 예시에 json annotation 달아서 시도 --> 역시 400 bad request

  3. Hashmap 형태로 시도 --> java.lang.IllegalArgumentException: Unable to create @ Body converter for java.util.HashMap<java.lang.String, java.lang.Object> (parameter # 1 오류 발생. 해결 방법도 찾아봤는데 모르겠습니다.

4. @ Field annotation 사용 시도

interface LoginService {

    @FormUrlEncoded
    @POST("api/v1/signup")
    fun signup(@Field("email")email:String,
               @Field("username")username:String,
               @Field("password")password:String,
               @Field("roll")roll:String): Call<FetchSignup>
}

이 방법은 그나마 되는데,
500 Internal Server Error http://ec2-3-37-16-171.ap-northeast-2.compute.amazonaws.com/api/v1/signup
가 뜬 후 수백 줄의 html 문장들이 뜹니다. 어떤 상황인지 전혀 파악이 되질 않아서 이슈로 남깁니다.

추가로,

     response.enqueue(object: Callback<FetchSignup>{
                override fun onFailure(call: Call<FetchSignup>, t: Throwable) {
                    Timber.d("")
                }

                override fun onResponse(call: Call<FetchSignup>, response: Response<FetchSignup>) {
                    Timber.d(response.body()?.user.toString())
                    Timber.d(response.body()?.user)
                    Timber.d(response.body()?.token.toString())
                    Timber.d(response.body()?.token)
                }

            })

으로 user과 token을 서버의 response로부터 추출하도록 해 보았는데, token은 전송되지 않았습니다. logcat 기록 첨부합니다 log.txt .

veldic commented 2 years ago

일단 5XX error 보다는 4XX error 쪽으로 접근하는게 좋습니다. 1번 방법이 제일 적절할 것 같은데... RequestSignUp class 도 보여주시겠어요?

JuTaK97 commented 2 years ago

일단 5XX error 보다는 4XX error 쪽으로 접근하는게 좋습니다. 1번 방법이 제일 적절할 것 같은데... RequestSignUp class 도 보여주시겠어요?

image

1번 방법의 requestsignup입니다.

veldic commented 2 years ago

데이터 넣은것도 보여주시겠어요?

JuTaK97 commented 2 years ago

image

이렇게 넣었습니다. (임시로 그냥 저기서 param 생성해서 넣었습니다) loginService는 image

이렇게 했습니다.

veldic commented 2 years ago

data class에 name이 아니라 username으로 넘겨주셔야 합니다!

JuTaK97 commented 2 years ago

data class에 name이 아니라 username으로 넘겨주셔야 합니다!

아 제가 다시 1번 방법으로 되돌리다가 깜박했네요. 원래 username으로 했었습니다

veldic commented 2 years ago

저렇게 보내서 log 보여주실 수 있나요?

JuTaK97 commented 2 years ago
data class RequestSignup(

    val email: String,
    val username: String,
    val password:String,
    val role:String
)
interface LoginService {

    @POST("api/v1/signup")
    fun signup(@Body params: RequestSignup): Call<FetchSignup>
}
@Singleton
class LoginRepository @Inject constructor(private val loginService: LoginService){
    fun signup(): Call<FetchSignup> {

        val param = RequestSignup("akjdj@naver.com","aaa", "1234",
            "participant")
        return loginService.signup(param)
    }
}
data class FetchSignup (
    val name:String,
    val token:String
)

정리하면 이렇게 했습니다.

JuTaK97 commented 2 years ago

log.txt

로그입니다.

veldic commented 2 years ago

405가 뜨는데 저기 @POST("api/v1/signup") 에 끝에 /로 닫아주세요. @POST("api/v1/signup/")

JuTaK97 commented 2 years ago

405가 뜨는데 저기 @POST("api/v1/signup") 에 끝에 /로 닫아주세요. @POST("api/v1/signup/")

감사합니다 드디어 201이 떴네요ㅠㅠㅠ 정말감사합니다