将json post请求更改为multipart / form-data

时间:2017-05-31 00:04:38

标签: android json

我试图在Android中开发一个简单的POST API调用,所以我认为请求内容类型是json。原来它期待multipart/form-data格式,我正在努力改变我的功能。 我想知道是否有任何图书馆来管理这个。如果没有,我想知道如何以多部分格式传递我的参数。

@Override
    public boolean post(String poiId, String description, ArrayList<String> tags, Resource resource) {

        RequestQueue queue = mRequestQueue;
        poiId = "1";
        description = "Test post";
        final HashMap<String, Object> params = new HashMap<>();
        params.put("poiID", poiId);
        params.put("description", description);
        System.out.println("POI ID " + description);
        params.put("tags", tags);
        params.put("resource", resource);


        RequestFuture<JSONObject> future = RequestFuture.newFuture();
        JsonObjectRequest request = new JsonObjectRequest(
                Request.Method.POST,
                API_POST_URL,
                new JSONObject(params),
                future, future) {
            @Override
            public HashMap<String, String> getHeaders() {
                System.out.println(PostRepositoryImpl.this.getHeaders());
                return PostRepositoryImpl.this.getHeaders();
            }
        };

        queue.add(request);

        try {
            future.get(TIMEOUT, TIMEOUT_TIME_UNIT); // this will block
        }catch (InterruptedException | ExecutionException | TimeoutException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

我对某些值进行了硬编码,因为我想使用poiIDdescription进行测试

所以我想在我的multipart / form-date中发送这些值: - poiID:String - 描述:字符串 - 资源:图片 - 标签

有没有办法像我提出json请求那样做?

亲切的问候

编辑:

@Override
public boolean post(String poiId, String description, ArrayList<String> tags, Resource resource) {
    RequestQueue queue = mRequestQueue;
    StringRequest postRequest = new StringRequest(Request.Method.POST, API_POST_URL,
            new Response.Listener<String>()
            {
                @Override
                public void onResponse(String response) {
                    // response
                    Log.d("Response", response);
                }
            },
            new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // error
                    Log.d("Error.Response", "400");
                }
            }
    ) {
        @Override
        protected HashMap<String, String> getParams()
        {
            HashMap<String, String>  params = new HashMap<String, String>();
            params.put("poiID", "Alif");
            params.put("description", "http://itsalif.info");

            return params;
        }
    };
    queue.add(postRequest);

    return true;
}

如何添加标题?

2 个答案:

答案 0 :(得分:0)

如果它不是JSON,只需使用StringRequest。

不确定如何使用Future with Volley,所以相应地改变

然后,params以重写方法添加

    Request request = new StringRequest(
            Request.Method.POST,
            API_POST_URL, 
            future, future) {
        @Override
        public HashMap<String, String> getHeaders() {
            HashMap<String, String> headers = PostRepositoryImpl.this.getHeaders();
            System.out.println(headers);
            return headers;
        }
        @Override
        public HashMap<String, String> getParams() {
            // TODO: Put your params here
        }
    };

对于Multipart,请参阅Working POST Multipart Request with Volley and without HttpEntity

答案 1 :(得分:0)

使用Retrofit 2,你可以这样做:

//让我们假设你有这个邮递员,或者你想提出这样的请求 postman request

// ServiceCreator(在我的情况下,我使用oauth2,所以有AccessToken)。这是一个工作和生产示例,因此您必须进行自己的更改,但我附加示例所有组件。

public class APIRestClient {

    public static String API_BASE_URL = "http://186.151.238.14/";

    private static OkHttpClient.Builder httpClient;

    private static Retrofit.Builder builder;
    public static Retrofit retrofit;
    private static Activity mActivity;
    private static AccessToken mToken;

    /**
     * setupBase URL
     * @param _baseActivity
     */
    public static void setupBaseUrl(Context _baseActivity){
        String tmpBase = SharedPreferenceUtilities.getDomain(_baseActivity);
        if (tmpBase != null && tmpBase.length() > 0){
            if (tmpBase != API_BASE_URL) {
                APIRestClient.API_BASE_URL = tmpBase;
            }
        }
    }

    /**
     * auth2 Authorization Bearer...token create Service instance
     * @param _serviceClass
     * @param _baseActivity
     * @param <S>
     * @return
     */
    public static <S> S createService(Class<S> _serviceClass, final Activity _baseActivity) {
        AccessToken accessToken = TaskManagementApplication.getInstance().getAccessToken();
        if (_baseActivity != null) {
            setupBaseUrl(_baseActivity);
        }

        httpClient = new OkHttpClient.Builder();
        httpClient.connectTimeout(30000, TimeUnit.SECONDS)
                .readTimeout(30000,TimeUnit.SECONDS);

        if (BuildConfig.DEBUG) {
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
            httpClient.addInterceptor(logging);
            httpClient.addNetworkInterceptor(new StethoInterceptor());
        }

        builder = new Retrofit.Builder()
                .baseUrl(API_BASE_URL)
                .addConverterFactory(GsonConverterFactory.create());

        if (accessToken == null){
            accessToken = new AccessToken();
            accessToken.setAccessToken("");
            accessToken.setTokenType("Bearer");
            accessToken.setScope("");
            accessToken.setRefreshToken("");
            accessToken.setClientID("");
            accessToken.setClientSecret("");
            accessToken.setExpiry(0);
        }

        if(accessToken != null) {
            mActivity = _baseActivity;
            mToken = accessToken;
            final AccessToken token = accessToken;
            httpClient.addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request original = chain.request();

                    Request.Builder requestBuilder = original.newBuilder()
                            .header("Accept", "application/json")
                            .header("Content-type", "application/json")
                            .header("Authorization",
                                    token.getTokenType() + " " + token.getAccessToken())
                            .method(original.method(), original.body());

                    Request request = requestBuilder.build();
                    return chain.proceed(request);
                }
            });

            httpClient.authenticator(new Authenticator() {
                @Override
                public Request authenticate(Route route, Response response) throws IOException {
                    if(responseCount(response) >= 2) {
                        // If both the original call and the call with refreshed token failed,
                        // it will probably keep failing, so don't try again.
                        LoginUtilities.initLogin(_baseActivity,LoginActivity.LOGININTENTRESULT,null);
                        return null;
                    }

                    // We need a new client, since we don't want to make another call using our client with access token
                    OAuthInterface tokenClient = createAuthService(OAuthInterface.class,mActivity);
                    Call<AccessToken> call = tokenClient.getRefreshAccessToken(
                            Grant_type.REFRESH_TOKEN.toString(),
                            token.getRefreshToken(),
                            StringUtilities.API_OAUTH_CLIENTID(_baseActivity),
                            StringUtilities.API_OAUTH_SECRET(_baseActivity),
                            "");
                    try {
                        retrofit2.Response<AccessToken> tokenResponse = call.execute();
                        if(tokenResponse.code() == 200) {
                            AccessToken newToken = tokenResponse.body();
                            mToken = newToken;
                            SharedPreferenceUtilities.setAccessToken(mActivity,mToken);
                            TaskManagementApplication.getInstance().setupToken(mToken);

                            return response.request().newBuilder()
                                    .header("Authorization", newToken.getTokenType() + " " + newToken.getAccessToken())
                                    .build();
                        } else {
                            LoginUtilities.initLogin(_baseActivity,LoginActivity.LOGININTENTRESULT,null);
                            return null;
                        }
                    } catch(IOException e) {
                        LoginUtilities.initLogin(_baseActivity,LoginActivity.LOGININTENTRESULT,null);
                        return null;
                    }
                }
            });
        }

        OkHttpClient client = httpClient.build();
        Retrofit retrofit = builder.client(client).build();
        return retrofit.create(_serviceClass);
    }

    /**
     * not auth create Service instance
     * @param _serviceClass
     * @param _context
     * @param <S>
     * @return
     */

    private static int responseCount(Response response) {
        int result = 1;
        while ((response = response.priorResponse()) != null) {
            result++;
        }
        return result;
    }
}

// ApiInterface

    public interface StudentInterface 
    {
        public static final String ENVIARTAREAAPI = "api/estudiante/entregatarea";
        @Multipart
        @POST(ENVIARTAREAAPI)
        Call<TareaCalificacion> entregatarea(@Part("Descripcion") RequestBody Descripcion,
                                            @Part("IdTarea") RequestBody IdTarea,
                                            @Part("IdEstudiante") RequestBody IdEstudiante);

    }

// ApiCall(在你的活动,片段或wetheaver中)这应该在你执行api调用时使用

RequestBody descripcionRequestBody = RequestBody.create(
                okhttp3.MediaType.parse("text/plain; charset=utf-8"),
                mensageEntregaTmp);

RequestBody idTareaRequestBody = RequestBody.create(
                okhttp3.MediaType.parse("text/plain; charset=utf-8"),
                String.valueOf(mTarea.getIdTarea()));

RequestBody idEstudianteRequestBody = RequestBody.create(
                okhttp3.MediaType.parse("text/plain; charset=utf-8"),
                String.valueOf(currUser.getPerfil().getSisId()));

StudentInterface studentInterface = APIRestClient.createService(StudentInterface.class,DetalleTareaActivity.this);
Call<TareaCalificacion> call = studentInterface.entregatarea(
        descripcionRequestBody,
        idTareaRequestBody,
        idEstudianteRequestBody);

call.enqueue(new Callback<TareaCalificacion>() {
    @Override
    public void onResponse(Call<TareaCalificacion> call, Response<TareaCalificacion> response) {
        int statusCode = response.code();
        if(statusCode == 200) {
            Toast.makeText(getApplicationContext, "Success Request", Toast.LENGTH_SHORT).show();
        } else {
            //todo some kind of error
        }
    }
    @Override
    public void onFailure(Call<TareaCalificacion> call, Throwable t) {
        //todo some kind of error
    }
});

我用这个来上传照片,所以我必须使用这个样本来做到这一点,这就是我没有使用Content Type application / json的原因。

希望有助于该怎么做。

某些类(pojo)就像TareaCalificacion(我对响应的期望就是类,我和GSON一起使用),所以TareaCalificacion.java就像:

public class TareaCalificacion {
    @SerializedName("sisId")
    @Expose
    private long sisId;

    @SerializedName("sisDescripcion")
    @Expose
    private String sisDescripcion;

    @SerializedName("sisEstado")
    @Expose
    private String sisEstado;

    @SerializedName("sis")
    @Expose
    private int sis;

    @SerializedName("sisUsuario")
    @Expose
    private String sisUsuario;

    @SerializedName("CalificacionObtenida")
    @Expose
    private double CalificacionObtenida;

    @SerializedName("IdEstudiante")
    @Expose
    private long IdEstudiante;

    @SerializedName("IdTarea")
    @Expose
    private long IdTarea;

    @SerializedName("Adjunto")
    @Expose
    private int Adjunto;

    @SerializedName("ObservacionCalificacion")
    @Expose
    private String ObservacionCalificacion;

    @SerializedName("IdCatedratico")
    @Expose
    private long IdCatedratico;

    public TareaCalificacion() {
    }
}

如果您有疑问,请附上一些可以帮助您的链接:

Retrofit Documentation

Another example using this

让我知道这是否有效或者不清楚该怎么做 问候。