2022. 12. 21. 22:25ㆍAndroid
-인터파크 Api 를통해 도서목록을 가져오기.
네이버나 구글에 검색해서 사이트를 들어가 캡쳐햇습니다,,
1. 요청 URL (request url)
http://book.interpark.com/api/bestSeller.api
2-1. 요청 변수 (request parameter)
요청 변수값설명
key | string (필수) | 이용 등록을 통해 받은 인증키를 입력합니다. |
categoryId | 분야의 고유 번호(필수) 카테고리 파일 다운. |
지정한 카테고리의 베스트 셀러를 검색합니다. |
2-2. 상세 검색-요청 변수 (request parameter)
※ 상세 검색은 검색 필수 사항을 보자 세부적으로 설정하여 검색할 수 있도록 합니다.
요청 변수변수 옵션설명
output | xml(기본값) : REST XML형식 json : JSON방식 |
검색 결과의 출력 방식을 설정합니다. |
--> Chrome Postman 으로 작성.
간단하게 API 가 동작하는 지 우선확인해보고 싶어서 결과를 확인해보았습니다.
GRADLE 의존성 추가
-모듈에 의존성을 추가해준다.
mplementation 'com.squareup.retrofit2:retrofit:버전'
implementation 'com.google.code.gson:gson:버전'
implementation 'com.squareup.retrofit2:converter-gson:버전'
- 괄호안에 버전을 넣으라고하는데 깃허브들어가면 버전이 잇어 최근에맞게 넣어주면된다.
- gson 라이브러리에서 파싱한 것을 dto 객체로 바꿔주는 라이브러리
- Retrofit의 필수 라이브러리 (최신버전은 retrofit와 같은걸써야한다.)
implementation 'com.squareup.retrofit2:retrofit:2.7.1'
implementation 'com.squareup.retrofit2:converter-gson:2.7.1
-gson
gson은 이 json을 편하게 사용할 수 있도록 google에서 만든 json관련 라이브러리 입니다.
json과 java객체 간의 직렬화(Serialization)와 역직렬화(Deserialization)를 쉽게 할 수 있게 도와주기 때문에 json자체의 파싱보다는 업무로직 자체에 집중할 수 있도록 도와줍니다.
dependencies {
implementation 'com.google.code.gson:gson:2.10'
}
- API 패키지 파일을 생성해준다.
- BookService 인터페이스를 만들어줍니다.
package com.example.myapplication.api
import com.example.myapplication.model.BestSellerDTO
import com.example.myapplication.model.SearchBookDTO
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query
interface BookService {
@GET("/api/search.api?output=json")
fun getBooksByName(
@Query("key") apiKey: String,
@Query("query") keyword: String,
): Call<SearchBookDTO>
@GET("/api/bestSeller.api?output=json&categoryId=100")
fun getBestSellerBooks(
@Query("key") apiKey: String
): Call<BestSellerDTO>
}
GET : 데이터 요청 시 반환 http
POST : http body에 넣어 전달
-> 모델이 없기때문에 Book이라는 데이터클래스를 만들어줍니다
package com.example.myapplication.model
import com.google.gson.annotations.SerializedName
data class Book (
@SerializedName("itemId") val id:Long,
@SerializedName("title") val title :String,
@SerializedName("description") val description: String,
@SerializedName("coverSmallUrl") val coverSmallUrl: String
)
전체모델에서 데이터를 꺼내올수있게 DTO도 만들어줍니다.
- SearchBookDTO
package com.example.myapplication.model
import com.google.gson.annotations.SerializedName
data class SearchBookDTO (
@SerializedName("title") val title: String,
@SerializedName("item") val books: List<Book>
)
- BestrSellerDTO
package com.example.myapplication.model
import com.google.gson.annotations.SerializedName
data class BestSellerDTO (
@SerializedName("title") val title: String,
@SerializedName("item") val books: List<Book>
)
- API 호출하기
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
위에 코드를 참고로 인터페이스를 구현해서 메인클래스를 생성
- 이 책을 표시하는 리사이클러뷰 목록화면구성
- 뷰바인딩 그래드모듈에 추가한다.
- 어댑터에서 해당 레이아웃 해당하는 바인딩을 사용해 코드작성
package com.example.myapplication.Adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.myapplication.databinding.ItemBookBinding
import com.example.myapplication.model.Book
// 어댑터 준비
class BookAdapter : ListAdapter<Book, BookAdapter.BookitemViewHolder>(diffUtil) {
// 뷰 홀더 준비
inner class BookitemViewHolder(private val binding: ItemBookBinding) : RecyclerView
.ViewHolder(binding.root) {
fun bind(bookModel: Book) {
binding.titleTextView.text = bookModel.title
}
}
// 미리 만들어진 뷰 홀더가 없을 경우 생성하는 함수.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookitemViewHolder {
return BookitemViewHolder(ItemBookBinding.inflate(LayoutInflater.from(parent.context),
parent,
false))
}
//실제 뷰 홀더가 뷰에 그려지게 됬을 때 데이터를 바인드하게 되는 함수
override fun onBindViewHolder(holder: BookitemViewHolder, position: Int) {
holder.bind(currentList[position])
}
//같은 값이 있으면 할당 해줄 필요없다.
companion object {
val diffUtil = object : DiffUtil.ItemCallback<Book>() {
override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean {
return oldItem.id == newItem.id
}
}
}
}
- 메인액티비티 코드 작성
package com.example.myapplication
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.myapplication.Adapter.BookAdapter
import com.example.myapplication.api.BookService
import com.example.myapplication.databinding.ActivityMainBinding
import com.example.myapplication.model.BestSellerDTO
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var adapter: BookAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initBookRecyclerView()
val retrofit = Retrofit.Builder()
.baseUrl("https://book.interpark.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
var bookService = retrofit.create(BookService::class.java)
//베스트 셀러가져오기
bookService.getBestSellerBooks("54538E2B4AC7B8E584CA2D046AF776BCE8C2E736B3F0019D1C50B09EAB47A963")
.enqueue(object : Callback<BestSellerDTO> {
override fun onResponse(
call: Call<BestSellerDTO>,
response: Response<BestSellerDTO>,
) {
if (response.isSuccessful.not()) {
Log.e(TAG, "NOT!! SUCCESS")
return
}
//받은 응답의 바디가 채워져잇을때(null이 아닐때) 블록이 실행됨
response.body()?.let {
Log.d(TAG, it.toString())
it.books.forEach { book ->
Log.d(TAG, book.toString())
}
adapter.submitList(it.books)
}
}
override fun onFailure(call: Call<BestSellerDTO>, t: Throwable) {
Log.e(TAG, t.toString())
}
})
}
private fun initBookRecyclerView() {
adapter = BookAdapter()
binding.bookRecyclerView.layoutManager = LinearLayoutManager(this)
binding.bookRecyclerView.adapter = adapter
}
companion object {
private const val TAG = "MainActivity"
}
}
실행했더니 에러가낫다.. 최신버전이라서 그런지 아래있는 그래들에 종속성을 추가해주자.
implementation 'com.squareup.okhttp3:okhttp:4.9.2'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
이렇게 세개의 종속성이 추가된걸볼수있다,
-애뮬레이터 실행화면
아직 이미지뷰를 만들지않앗기때문에 다음에는 이미지뷰를 넣어 도서목록리스트랑 검색페이지를 만들어보겟다
'Android' 카테고리의 다른 글
중고 거래 앱 만들기 (1) - 프래그먼트 (액티비티처럼 동작하는 뷰) (0) | 2022.12.29 |
---|---|
도서리뷰 앱 만들기(2) - 도서리뷰저장하기 (0) | 2022.12.23 |
전자액자 만들기 (2) - 액티비티 생명주기 (0) | 2022.12.16 |
<전자액자 앱만들기>파일 접근 권한과 이미지 업로드 이해와 사용 (0) | 2022.12.13 |
전자액자 앱만들기(1) (0) | 2022.12.13 |