Multipart Request - retrofit

Using Retrofit to make request to a spring-data-rest instance, running into trouble sending multipart request.
Retrofit
#Multipart
#POST(URI)
void save(#Part("request[data][param][event]") Event event,
Callback<Resource<Event>> callback);
Spring
#RequestMapping(value=URI, method=RequestMethod.POST)
public #ResponseBody HttpEntity<Event> addEvent(#RequestPart Event event) {
...
}
With this, I'm getting a 400 Bad Request: "Required request part 'event' is not present."
Assuming the Event object has a String name & Bitmap image, what's the proper way to handle this?

Almost had it, the save method signature should be:
#Multipart
#POST(URI)
void save(#Part("event") Event event,
Callback<Resource<Event>> callback);

Related

ContentCachingResponseWrapper : How to get application response object (not httpResponse) using ContentCachingResponseWrapper

Using Interceptors to validate the requests in Spring Web.
I've extended HandlerInterceptorAdapter to implement postHandle method.
I want to check the value inside application response object and accordingly do some action.
I tried IOUtils to get the app response object but getting a "" string.
public class XYZInterceptor extends HandlerInterceptorAdapter {
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
// need to retrieve application response object
return;
}
}
After going through many docs, and hands on I figured out that the input stream / output steam can be accessed only once. The response object would already have written output stream somewhere before it reaches postHandler. So output stream is empty in response object of postHandle.
If you wish to access response object in postHandle is to setAttribute for request object with actual response object.

Handling 405 errors

I am trying to handle 405 (Method not Allowed) errors generated from WebApi.
E.g.: Basically this error will be handled whenever someone calls my Api with a Post request instead of a Get one.
I'd like to do this programatically (i.e. no IIS configuration), right now there are no documentation of handling this kind of error and the IExceptionHandler is not triggered when this exception happens.
Any ideas ?
Partial response:
By looking at the HTTP Message lifecycle from here, there is a possibility to add a Message Handler early in the pipeline, before HttpRoutingDispatcher.
So, create a handler class:
public class NotAllowedMessageHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (!response.IsSuccessStatusCode)
{
switch (response.StatusCode)
{
case HttpStatusCode.MethodNotAllowed:
{
return new HttpResponseMessage(HttpStatusCode.MethodNotAllowed)
{
Content = new StringContent("Custom Error Message")
};
}
}
}
return response;
}
}
In your WebApiConfig, in Register method add the following line:
config.MessageHandlers.Add(new NotAllowedMessageHandler());
You can check the status code of the response and generate a custom error message based on it.

RxAndroid: Retrofit doesn't work on the second time?

I am using RxAndroid and Retrofit for httpRequest, my code is as below:
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(logging)
.authenticator(new DigestAuthenticator())
.build();
// retrofit with custom client
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(NetUtil.getServerBaseUrl())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(client)
.build();
ApiService apiService = retrofit.create(ApiEndpoints.class);
CustomerSubscriber mSubscriber = new CustomerSubscriber();
apiService.checkAccount(mUser.getEmail()).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.newThread()).subscribe(mSubscirber);
//Retrofit
#Headers({
"Accept: application/json;charset=utf-8",
"Content-Type: application/json;charset=utf-8"
})
#HEAD("/account")
Observable<Result<Void>> rxHeadAccount(
#Query("email") String encryptedEmail);
My scenario like this: every time when I click the button "apiService.checkAccount()" method will be triggered. The first time:click button, the httpRequest is sent and I can get response
However, click the second time, no httpRequest was sent and the logs shows " I/Choreographer: Skipped 115 frames! The application may be doing too much work on its main thread."
However if I change code to
apiService.checkAccount(mUser.getEmail()).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.newThread()).subscribe(new Subscriber<Result<Void>>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(Result<Void> voidResult) {
}
});
}
});
The Retrofit works very well, it can send HttpRequest as many times as your want?
Looks like the "Subscriber" can't be one instance?
Why, Any idea about it?
Thanks
Once an observable emits a terminal event (a complete or error event) it is not going to emit any more events (see here). Each call to apiService.checkAccount(mUser.getEmail()) creates a new observable to which you can subscribe with a subscriber. This creates a subscription.
You probably want to store your subscription objects and unsubscribe from them when you're done.

This method cannot be called once the request has fully transitioned to a WebSocket request

I've been trying to call HttpContext.Current.Server.Execute in OnMessage event implemented in a subclass of WebSocketHandler:
public class MySocketService : WebSocketHandler
{
public override void OnMessage(string message)
{
// some activity which decides to update an area in client browser
var html = HttpContext.Current.Server.Execute("Login.ascx", writer, true);
Send(html);
}
}
But I always receive the same exception. Is there any way to make this call? Or maybe I will have to consider using WebClient?
Thanks for your help.

Reading http content from POST in MVC 4 WebApi

I have a MVC 4 application, using WebApi. An external client is POST'ing to it, and I need to collect that data. I can get model binding to work with
public void Post([FromBody] Alert alert) { ... }
where Alert is a class defining the complex type. However, I have a case where I want to read whatever is in the body, even when I don't know what the structure is. So how do I read the raw header and body of the incoming POST request. I tried with this:
public void Post(HttpContent content) { ... }
but when POST'ing to the service, the Post method does not get invoked at all.
Input?
Thanks
Try binding HttpRequestMessage instead of HttpContent. That should work and will give you access to the request headers and the body.
public void Post(HttpRequestMessage request) { ... }
You can also access the Request property on your controller which should be set correctly:
public void Post() { var content = Request.Content; }

Resources