Как отправить запрос на публикацию с модификацией android-type x-www-form-urlencoded
Я столкнулся с проблемой отправки запроса на публикацию с типом содержимого как x-www-form-urlencoded при модернизации Android. Не уверен, что я делаю при отправке почтового запроса. Когда такой же запрос отправляется через почтальона, я могу получить ожидаемый правильный ответ. Более того, я попытался отправить такой же ответ через html-форму и получил успешный ответ.
public class RequestManager {
private static Retrofit retrofit;
private static final String BASE_URL = "https://ipguat.apps.net.pk/Ecommerce/api/Transaction/";
private OkHttpClient okhttpClient;
static Gson gson = new GsonBuilder()
.setLenient()
.create();
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
//MainActivity, откуда я отправляю почтовый запрос
private void sendPayment(String token) {
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = df.format(c);
Call<ResponseBody> call = service.sendPayment("102", "Arfeen Test", token, "00", "5", "03451234567", "arfeen@arfeen.me", "POSTMAN-TEST-ARF", "01", "Test Purchase", "www.facebook.com", "www.google.com", "TEST-01", formattedDate, "www.youtube.com");
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
renderPage(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
}
);
}
// Интерфейс, где указана конечная точка для API
public interface TokenService {
@FormUrlEncoded
@POST("PostTransaction/")
Call<ResponseBody> sendPayment(@Field("MERCHANT_ID") String id,
@Field("MERCHANT_NAME") String merchantName,
@Field("TOKEN") String token,
@Field("PROCCODE") String proccode,
@Field("TXNAMT") String transaction,
@Field("CUSTOMER_MOBILE_NO") String mobile,
@Field("CUSTOMER_EMAIL_ADDRESS") String email,
@Field("SIGNATURE") String signature,
@Field("VERSION") String version,
@Field("TXNDESC") String productDescription,
@Field("SUCCESS_URL") String successUrl,
@Field("FAILURE_URL") String failureUrl,
@Field("BASKET_ID") String basketID,
@Field("ORDER_DATE") String orderDate,
@Field("CHECKOUT_URL") String checoutUrl);
}
1 ответ
Решение
Используйте аннотацию @Headers.
public interface TokenService {
@FormUrlEncoded
@Headers("Content-Type:application/x-www-form-urlencoded")
@POST("PostTransaction/")
Call<ResponseBody> sendPayment(@Field("MERCHANT_ID") String id,
@Field("MERCHANT_NAME") String merchantName,
@Field("TOKEN") String token,
@Field("PROCCODE") String proccode,
@Field("TXNAMT") String transaction,
@Field("CUSTOMER_MOBILE_NO") String mobile,
@Field("CUSTOMER_EMAIL_ADDRESS") String email,
@Field("SIGNATURE") String signature,
@Field("VERSION") String version,
@Field("TXNDESC") String productDescription,
@Field("SUCCESS_URL") String successUrl,
@Field("FAILURE_URL") String failureUrl,
@Field("BASKET_ID") String basketID,
@Field("ORDER_DATE") String orderDate,
@Field("CHECKOUT_URL") String checoutUrl);
}
Попробуйте настроить OkhttpClient,
OkhttpManager.java
import android.content.Context;
import android.util.Log;
import android.webkit.CookieManager;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
public class OkHttpManager {
private final String TAG = "OkHttpManager";
private final int TIME_OUT_SECONDS = 60;
private static OkHttpManager instance = null;
private WebViewCookieHandler mWebViewCookieHandler = null;
public static OkHttpManager getInstance() {
if (instance == null) {
instance = new OkHttpManager();
}
return instance;
}
private OkHttpManager() {
if (mWebViewCookieHandler == null)
mWebViewCookieHandler = new WebViewCookieHandler();
}
private static ArrayList<String> sCurCookies = new ArrayList<>();
OkHttpClient getOkHttpClientDefault(Context context) {
// init okhttp 3 logger
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
try {
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
return new OkHttpClient()
.newBuilder()
.cookieJar(mWebViewCookieHandler)
.hostnameVerifier((s, sslSession) -> true)
.connectTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.readTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.writeTimeout(TIME_OUT_SECONDS, TimeUnit.SECONDS)
.addInterceptor(interceptor)
.addInterceptor(chain -> {
Request.Builder builder = chain.request().newBuilder();
return chain.proceed(builder.build());
})
.addInterceptor(chain -> {
Response response = chain.proceed(chain.request());
if (!response.headers("Set-Cookie").isEmpty()) {
Log.d(TAG, "getCookie header added");
sCurCookies.addAll(response.headers("Set-Cookie"));
}
response.body();
return response;
})
.build();
} catch (Exception e) {
Log.e(TAG, e.toString());
}
return null;
}
private class WebViewCookieHandler implements CookieJar {
private CookieManager webviewCookieManager = CookieManager.getInstance();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
String urlString = url.toString();
for (Cookie cookie : cookies) {
webviewCookieManager.setCookie(urlString, cookie.toString());
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
String urlString = url.toString();
String cookiesString = webviewCookieManager.getCookie(urlString);
if (cookiesString != null && !cookiesString.isEmpty()) {
//We can split on the ';' char as the cookie manager only returns cookies
//that match the url and haven't expired, so the cookie attributes aren't included
String[] cookieHeaders = cookiesString.split(";");
List<Cookie> cookies = new ArrayList<>(cookieHeaders.length);
for (String header : cookieHeaders) {
cookies.add(Cookie.parse(url, header));
}
return cookies;
}
return Collections.emptyList();
}
}
}
RequestManager.java
public class RequestManager {
private static Retrofit retrofit;
private static final String BASE_URL = "https://ipguat.apps.net.pk/Ecommerce/api/Transaction/";
private OkHttpClient okhttpClient;
static Gson gson = new GsonBuilder()
.setLenient()
.create();
public static Retrofit getRetrofitInstance(Activity activity) {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.client(OkHttpManager.getInstance().getOkHttpClientDefault(activity))
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}