I'm using GWT 2.3 and I have json-p requests in my code similar to this:
JsonpRequestBuilder jsonp = new JsonpRequestBuilder();
jsonp.requestObject(jsonUrl, new AsyncCallback<T>() {
public void onFailure(Throwable throwable) { // error }
public void onSuccess(T t) { //do something }
});
some GET-requests return 200, others 302 and so on, and I should be
able to return a different "answer" respect to this value. How can I
know what's the response value returned?
I think you can not access the response code using the JsonpRequestBuilder. But if you use the standard RequestBuilder instead you can get the response code using getStatusCode(). Of course you have to then the parse the response text yourself.
RequestBuilder r = new RequestBuilder(RequestBuilder.GET, jsonUrl);
r.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// error
}
public void onResponseReceived(Request request, Response response) {
if (response.getStatusCode() == 200) {
//do something
} else if (response.getStatusCode() == 302) {
//do something else
}
}
});
Related
I have the following method that runs some web services commands in Android.
Response.Listener Success = new Response.Listener<JSONObject >() {#Override
public void onResponse(JSONObject response) {
JSONObject S = response;
// do something with the response
}};
Response.ErrorListener Fail = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error.networkResponse.statusCode == 400) {
Success.notify(); // <<<<< According to some technical custom logic, this should be considered as a successful REST command. Hence run Success Response Listener
}
else {
// operation failed, do something
}
}
};
JSONObject J = new JSONObject();
J.put("param", some parameters);
RequestQueue queue = Volley.newRequestQueue(Act);
JsonObjectRequest JsonRequestObject = new JsonObjectRequest(Method, URL, J, Success, Fail);
queue.add(JsonRequestObject);
According to some custom technical logic, the requests that get 400 as a response should be considered as successful and hence run the success calback.
I tried this code but it crashes at the line :
Success.notify(); // <<<<<
Does anyone know how can I execute the Success call back manually please ?
Thanks
Cheers,
Instead of notify() you should call onResponse() like Success.onResponse() with null argument or with some JSONObject mapped from error.networkResponse.
More generalized way - create custom Response Listener (to listen to the success/error events in one place):
public abstract class ResponseListener<T> implements Response.Listener<T>,
Response.ErrorListener {
#Override
public final void onErrorResponse(VolleyError error) {
if (error.networkResponse.statusCode == 400) {
// redirect to onResponse()
onResponse(null /* or some response T object mapped from [error.networkResponse] */);
} else {
onError(error);
}
}
public abstract void onError(VolleyError error);
}
...
final ResponseListener<JSONObject> responseListener =
new ResponseListener<JSONObject>() {
#Override
public void onResponse(#Nullable JSONObject response) {
// do something with the response
}
#Override
public void onError(VolleyError error) {
// operation failed, do something
}
};
//
final JsonObjectRequest JsonRequestObject =
new JsonObjectRequest(Method, URL, J, responseListener, responseListener);
//
I calling to the api with the basic retrofit Call object:
public interface dataApi {
#GET("animal/cats")
Call<AllAnimals> getAllData(
#Query("api_key") String apiKey
);
}
And I can get the response inside my view model like this:
call.enqueue(new Callback<AllAnimals>() {
#Override
public void onResponse(Call<AllAnimals> call, Response<AllAnimals> response) {
animals.setValue(response.body());
}
#Override
public void onFailure(Call<AllAnimals> call, Throwable t) {
Log.i(TAG, "onFailure: " + t);
}
});
Nothing speical here.
I've several problem with this approach
FIRST - if I give the wrong api key for example, the response should give me a response with the code of the problem, instead I just get null body.
SECOND I am planning to have more api calls, and it's a huge code duplication to handle errors every call I wrote.
How can I implement custom error handling for this situation, that will be apply to other calls too?
I think you can use okhttp interceptor and define yourself ResponseBody converter to fix your problem.
First,intercept you interested request and response;
Second,check the response,if response is failed then modify the response body to empty。
define a simple interceptor
Interceptor interceptor = new Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String url = request.url().toString();
System.out.println(request.url());
okhttp3.Response response = chain.proceed(request);
if (!response.isSuccessful() && url.contains("animal/cats")) {
// request failed begin to modify response body
response = response.newBuilder()
.body(ResponseBody.create(MediaType.parse("application/json"), new byte[] {}))
.build();
}
return response;
}
};
define self ResponseBody converter
most code from com.squareup.retrofit2:converter-jackson we just add two lines:
final class JacksonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final ObjectReader adapter;
JacksonResponseBodyConverter(ObjectReader adapter) {
this.adapter = adapter;
}
#Override public T convert(ResponseBody value) throws IOException {
try {
if (value.contentLength() == 0) {
return null;
}
return adapter.readValue(value.charStream());
} finally {
value.close();
}
}
}
the below code is added:
if (value.contentLength() == 0) {
return null;
}
Might be a dumb question but how can I retrieve the value of the response given by the RequestBuilder in a JSON format. My code is this:
try {
Request request = builder.sendRequest(json, new RequestCallback() {
public void onError(Request request, Throwable exception) {
System.out.println("CAN'T CONNECT");
// Couldn't connect to server (could be timeout, SOP violation, etc.)
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
System.out.println("SUCCESS");
System.out.println(response.getText());
// Process the response in response.getText()
} else {
System.out.println("ERROR" + response.getStatusCode() + response.getText());
// Handle the error. Can get the status text from response.getStatusText()
}
}
});
} catch (RequestException e) {
System.out.println(e);
}
Currently, the response gives me {faceAmount: 29921}. How do I access the value for faceAmount and store it to a variable? Is the response providing me with a JSON format or just straight up text string?
You can use com.google.gwt.json.client, or use JSNI and overlay types, or better, use JsInterop. You'll find more in the docs: http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSON.html, http://www.gwtproject.org/doc/latest/tutorial/JSON.html, http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJsInterop.html
#JsType(isNative=true)
interface Response {
#JsProperty int getFaceAmount();
}
Response r = (Response) (JavaScriptObject) JsonUtils.parse(json);
I am using deferredResult on Spring MVC, but using this code, the timeout still are sending back the HTTP code 503 to the client.
future.onCompletion(new Runnable() {
#Override
public void run() {
if(future.isSetOrExpired()){
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
}
});
Any idea what else to try?
I ran into the same issue. My Spring MVC Controller method originally returned DeferredResult<Object>, but then I realised I wanted to control the HTTP status code. I found the answer here:
https://www.jayway.com/2014/09/09/asynchronous-spring-service/
#RequestMapping("/async")
DeferredResult<ResponseEntity<?>> async(#RequestParam("q") String query) {
DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();
ListenableFuture<RepoListDto> repositoryListDto = repoListService.search(query);
repositoryListDto.addCallback(
new ListenableFutureCallback<RepoListDto>() {
#Override
public void onSuccess(RepoListDto result) {
ResponseEntity<RepoListDto> responseEntity =
new ResponseEntity<>(result, HttpStatus.OK);
deferredResult.setResult(responseEntity);
}
#Override
public void onFailure(Throwable t) {
log.error("Failed to fetch result from remote service", t);
ResponseEntity<Void> responseEntity =
new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
deferredResult.setResult(responseEntity);
}
}
);
return deferredResult;
}
Just use DeferredResult<ResponseEntity> and you can set both the response and the Http response code in the ResponseEntity.
I am using gwt with php.
I am trying to get data fom the http://typing.lc/userInfo.php url.
but the following code returns nothing, but response.getText() is 200, however when i ask http://typing.lc/userInfo.php through browser it returns value.
try
{
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "http://typing.lc/userInfo.php");
builder.setHeader("Content-Type", "application/x-www-form-urlencoded");
builder.sendRequest("", new RequestCallback()
{
#Override
public void onError(Request request, Throwable exception)
{
Window.alert("Error");
}
#Override
public void onResponseReceived(Request request, Response response)
{
Window.alert("Success: " + response.getText());
}
});
}
catch (RequestException e)
{
Window.alert("Exception");
}
You are probably running into a SOP (Same Origin Policy) issue.
See here for possible solutions.