我试图在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;
}
我对某些值进行了硬编码,因为我想使用poiID
和description
进行测试
所以我想在我的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;
}
如何添加标题?
答案 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,你可以这样做:
// 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() {
}
}
如果您有疑问,请附上一些可以帮助您的链接:
让我知道这是否有效或者不清楚该怎么做 问候。