I called my service with AsyncTask and DefaultHttpClient before but now i want to use Retrofit. I read about this and implement that and onResponse
method called but my response has Bad Request Message and can't get body of response.
My error is:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.retrofitsample.f.retrofitsample/com.retrofitsample.f.retrofitsample.MainActivity}: java.lang.IllegalArgumentException: Unable to create converter for com.retrofitsample.f.retrofitsample.model.HttpResponse<com.retrofitsample.f.retrofitsample.model.MS>
Caused by: java.lang.IllegalArgumentException: class com.retrofitsample.f.retrofitsample.model.MS declares multiple JSON fields named Id
I have a wcf service like below :
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest,
UriTemplate = "GetMS")]
HttpResponse<MS> GetMS(string token,string Id);
I have a HttpResponse and all of my services return a type of T.. I write belo code in client side:
MyActivity:
retrofit2.Call<HttpResponse<MS>> call=service.getAllMonitoringScheduale("971048F6-7ABA-4060-8CC3-BC57EC259FA3","1292");
call.enqueue(new Callback<HttpResponse<MS>>() {
@Override
public void onResponse(retrofit2.Call<HttpResponse<MS>> call, Response<HttpResponse<MS>> response) {
Log.e("Response=",response.body().getResultMessage());
}
@Override
public void onFailure(retrofit2.Call<HttpResponse<MS>> call, Throwable t) {
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
My Interface:
public interface GetDataService {
@POST("GetMonitoringSchedule")
Call<HttpResponse<MS>> getAllMS(@Query("token")String token,@Query("Id") String Id);
}
and this is my models Class:
public class HttpResponse<T> {
@SerializedName("ResultMessage")
private String ResultMessage;
@SerializedName("Result")
private T Result;
public HttpResponse(String ResultMessage,T Result){
this.ResultMessage=ResultMessage;
this.Result=Result;
}
public String getResultMessage(){
return ResultMessage;
}
public void setResultMessage(String ResultMessage){
this.ResultMessage=ResultMessage;
}
public T getResult(){
return Result;
}
public void setResult(T Result){
this.Result=Result;
}
}
public class MS {
@SerializedName("Id")
public long Id;
@SerializedName("PId")
public long PId;
@SerializedName("SType")
public int SType;
@SerializedName("SDateF")
public Date SDateF ;
@SerializedName("SDateT")
public Date SDateT;
..Constructor and setter and getter
}
How to fix this errors and what is my problem? I don't know how to use HttpResponse type in Retrofit2?
I have found a project that uses Retrofit in order to make network requests. You can use it as a reference in order to understand how to use Retrofit.
https://github.com/AcademyTLV/fundamentals-2018-exercise/tree/ex-7-networking
Also be sure to use a POJO In order to create your classes to handle the request: http://www.jsonschema2pojo.org/
Here i have fully example for it.
This dependancy add in gradle
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
annotationProcessor 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
Here now create ApiClient.kt file
object ApiClient {
val BASE_URL = "http://yourwebsite/services/"
private var retrofit: Retrofit? = null
val client: Retrofit
get() {
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
return retrofit!!
}
}
Now create APIInterface.kt
@FormUrlEncoded
@POST("users/login")
fun POST_LOGIN(
@Field("imei_number") imei_number: String,
@Field("device_token") device_token: String,
@Field("mobile") mobile: String,
@Field("password") password: String
): Call<LoginResponse>
@GET("general/init-data")
fun GENERAL_MODULE(
@Header("Authorization") auth_key: String
): Call<InitResponse>
@GET("event-gallery/list")
fun GET_Event_GALLERY(
@Header("Authorization") auth_key: String
): Call<EventListResponse>
@GET("event-gallery/photo-list")
fun GET_Event_GALLERY_PHOTO(
@Header("Authorization") auth_key: String,
@Query("id") id: Int
): Call<EventGallerListResponse>
if Any Header for token the use @Header and also When call @GET that time params use @Query and @Post that time @Fields
Now Response file
data class EventListResponse(
@SerializedName("success")
var success: Boolean,
@SerializedName("data")
var data: EventgalleryModel?,
@SerializedName("server_error"),
@SerializedName("eventgallery")
var eventgallery: ArrayList<EventListData>
var server_error: Boolean,
@SerializedName("message")
var message: String
)
Then create Model class of Response
Now time to Activity code
private fun loadData() {
card_progress.visibility = View.VISIBLE
val apiService = ApiClient.client.create(ApiInterface::class.java)
val call =
apiService.GET_FEE_INSTALMENT_LIST(PreferenceManager.getAuthKey(this@FeesInstalmentActivity)!!)
call.enqueue(object : Callback<FeeInstalmentListResponse> {
override fun onResponse(
call: Call<FeeInstalmentListResponse>,
response: Response<FeeInstalmentListResponse>
) {
card_progress.visibility = View.GONE
val data = response.body()!!.data
if (response.code() == 200 && data != null) {
if (response.body()!!.server_error) {
txt_no_data_fee.visibility = View.VISIBLE
txt_no_data_fee.text = response.body()!!.message
} else {
Log.e("data", data.toString())
if (data != null && data.feesinstalment.isEmpty()) {
txt_no_data_fee.visibility = View.VISIBLE
} else {
txt_no_data_fee.visibility = View.GONE
adapter!!.setItem(data.feesinstalment)
}
}
} else if (response.code() == 401) {
PreferenceManager.removePref(this@FeesInstalmentActivity)
startActivity(
Intent(this@FeesInstalmentActivity, LoginActivity::class.java)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
)
finish()
} else {
Toast.makeText(
this@FeesInstalmentActivity,
R.string.somethingWrong,
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(call: Call<FeeInstalmentListResponse>, t: Throwable) {
card_progress.visibility = View.GONE
Log.e("onFailure", t.message)
txt_no_data_fee.visibility = View.VISIBLE
}
})
}
Sry i forget Adapter here
class FeeInstalmentAdapter(
private val context: Context,
private var items: ArrayList<FeeInstalmentListData>
) : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(context).inflate(R.layout.row_fees_instalment_item, parent, false))
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.due_date.text = DateHelper.parseData(items[position].due_date!!, "yyyy-MM-dd", "dd MMM yyyy")
holder.instalment_title.text = items[position].instalment_title
if (items[position].paid_date == null) {
holder.paid_text.visibility = View.GONE
holder.paid_date.text = context.resources.getString(R.string.UnPaid)
holder.paid_date.setTextColor(Color.parseColor("#DC143C"))
} else {
holder.paid_date.text = DateHelper.parseData(items[position].due_date!!, "yyyy-MM-dd", "dd MMM yyyy")
holder.paid_date.setTextColor(Color.parseColor("#58A259"))
}
//holder.paid_date.text = items[position].paid_date
holder.amount.text = "Rs. " + items[position].amount
holder.amount.setTextColor(Color.parseColor("#ED7136"))
}
override fun getItemCount(): Int {
return items.size
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemViewType(position: Int): Int {
return position
}
fun setItem(holidays: ArrayList<FeeInstalmentListData>) {
items = holidays
notifyDataSetChanged()
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val due_date = view.due_date
val instalment_title = view.instalment_title
val paid_date = view.paid_date
val amount = view.amount
val paid_text = view.paidText
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.