web-dev-qa-db-ja.com

Retrofit2でフォームデータを送信する方法android

こんにちは、サーバーに送信するjsonがあります(メソッドをポスト){"country":"india","devicetype":"Android"}これは、このjsonのキーがdataのようなフォームデータモデルです。つまり、サーバーはこれを受け入れます。

data={"country":"india","devicetype":"Android"}レトロフィットを使用しています。このようにマルチパートを使用しています。

@Multipart
@POST("initiate")
@Headers({
        "Content-Type: application/json",
        "Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(@Part(value="data") UserInfo mUserInfo);

ここUserInfoはjsonですが、FormUrlEncodedメソッドを使用した後、サーバーから失敗メッセージが表示されます

 @FormUrlEncoded
@POST("initiate")
@Headers({
        "Content-Type: application/json",
        "Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(@Field(value="data",encoded = false) String mUserInfo);

その出力もサーバーからの同じ失敗の結果ですが、サーバーに送信するデータは形式にあります

data=%7B%22country%22%3A%22india%22%2C%22devicetype%22%3A%22%22%7D

UserInfo.class

public class UserInfo {


public String country;

public String devicetype;

public UserInfo( String country,String devicetype) {

    this.country=country;

    this.devicetype=devicetype;
}
}

私のアダプタークラス

RemoteRetrofitInterfaces mService;
    Retrofit mRetrofit;
  HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)
                .writeTimeout(20, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS).addInterceptor(interceptor)
                .build();

        mRetrofit = new Retrofit.Builder()
                .baseUrl(AppConstant.Host).addConverterFactory(GsonConverterFactory.create())
                .client(client)
                .build();
        mService = mRetrofit.create(RemoteRetrofitInterfaces.class);

   Call<UserInfoServerResponse> api = mService.getUserInfoRequest(new Gson().toJson(mUserInfo));

        api.enqueue(new Callback<UserInfoServerResponse>() {
            @Override
            public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) {

                if (response.body().status != null) {
                    if (response.body().status.equals("success")) {
                        Log.d(TAG, "success---");
                    }

                } else {
                    Log.d(TAG, "Failed---");

                }


            }

            @Override
            public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) {
                t.printStackTrace();
            }


        });

それで、レトロフィットを使用してjsonをサーバーに正常に送信して、 retofit document を実行し、いくつかの手順に従うことができますが、結果が得られません。誰もがこれで私を助けることができますか

ありがとうございました

13
Ramz

最後に私はこれが他のいくつかを助けることを望んでいる解決策を見つけました

私は FieldMap を使用して解決策を達成します

改造の。

@POST("initiate")
@FormUrlEncoded

Call<UserInfoServerResponse> getUserInfoRequest(@FieldMap Map<String,String> params);

rest Adapterセクションで、リクエストデータを文字列からハッシュマップフォームに次のように変更しました

 Log.d(TAG, "sendUserInfo called");
UserInfo mInfo=new UserInfo("countyname","Android");
        String request=new Gson().toJson(mUserInfo);

        //Here the json data is add to a hash map with key data
        Map<String,String> params = new HashMap<String, String>();
        params.put("data", request);


        Call<UserInfoServerResponse> api = mService.getUserInfoRequest(params);


        api.enqueue(new Callback<UserInfoServerResponse>() {
            @Override
            public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) {

                if (response.body().status != null) {
                    if (response.body().status.equals("success")) {
                        Log.d(TAG, "success---" + response.body());
                    }

                } else {
                    Log.d(TAG, "Failed---");

                }


            }

            @Override
            public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) {
                t.printStackTrace();
            }


        });

基本的に私が使用したもの@ FormUrlEncodedフォームデータと@ FieldMapキー値としてのリクエストJSON。私はこの方法に従って解決策を得ました、これが誰かを助けることを願っています:)

20
Ramz

上記のソリューションは機能しますが、使用するのが面倒です。@ Multipart formDataのコンバーターを使用することをお勧めします

@Multipart FormDataを続行するには、次のコードを使用してください。

""が投稿文字列に追加されます

import Java.io.IOException;
import Java.lang.annotation.Annotation;
import Java.lang.reflect.Type;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

/**
 * Created by kural on 10/27/17.
 */

public class StringConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");

public static StringConverterFactory create() {
        return new StringConverterFactory();
        }

@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (String.class.equals(type)) {
        return new Converter<ResponseBody, String>() {

@Override
public String convert(ResponseBody value) throws IOException {
        return value.string();
        }
        };
        }
        return null;
        }

@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    if (String.class.equals(type)) {
        return new Converter<String, RequestBody>() {
            @Override
            public RequestBody convert(String value) throws IOException {
                return RequestBody.create(MEDIA_TYPE, value);
            }
        };
    }

    return null;

}
}

後付けクライアントにこの行を追加します

。addConverterFactory(StringConverterFactory.create())

public class RetroFitClient {
    private static Retrofit retrofit = null;

    public static Retrofit getClient(String baseUrl) {
        if (retrofit==null) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

            /*retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(client)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();*/
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(client)
                    .addConverterFactory(StringConverterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();


        }
        return retrofit;
    }
1
mughil

これは私にとってはうまくいき、jsonを返して新しい有効なMicrosoft Azureトークンを取得します:

私のエンドポイント:

@PostMapping(value = "/get-new-token", consumes = {"application/JSON"}, produces = {"application/JSON"})
@Timed
public ResponseEntity<String> getNewToken(@RequestBody String refreshToken) throws IOException {
    JSONObject json = tokenService.getNewTokenByRefreshToken(refreshToken);
    return new ResponseEntity<>(json.toString(), HttpStatus.OK);
}

My getGraphRepository

public GraphRepository getGraphRepository() {
    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(interceptor).build();

    // Create and configure the Retrofit object
    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(" https://login.microsoftonline.com")
        .client(client)
        .addConverterFactory(JacksonConverterFactory.create())
        .build();

    // Generate the graph repo
    return retrofit.create(GraphRepository.class);
}

My Token Service:

public JSONObject getNewTokenByRefreshToken(String refreshToken) throws IOException {
    GraphRepository graphRepository = getGraphRepository();

    // My list of -> Key : Value
    Map<String,String> params = new HashMap<String, String>();
    params.put("grant_type", "refresh_token");
    params.put("client_id", this.client_id);
    params.put("client_secret", client_secret);
    params.put("refresh_token", refreshToken);

    RefreshToken data = graphRepository.getRefreshToken(tenantId, params).execute().body();
    JSONObject json = new JSONObject(data);

    return json;
}

My GraphRepository:

@POST("/{tenant_id}/oauth2/v2.0/token")
@FormUrlEncoded
Call<RefreshToken> getRefreshToken(
    @Path("tenant_id") String tenant_id,
    @FieldMap Map<String, String> params
);

これが誰かの役に立つことを願っています。

0
XenoX