android volley does not receive php json object - json

I'm using android volley for send request to server side, in the other hand on server side I use php.
Here is my android code to receive response from server(does not matter what params is, because I do not need params on server side yet!):
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d("ATA d Response", response.toString());
VolleyLog.v("ATA Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("ATA Response", " RESPONSE ERROR");
VolleyLog.e("Error: ", error.getMessage());
}
});
req.setShouldCache(false);
queue.getCache().clear();
queue.add(req);
Now, when in server side i return as response something like this:
if( isset($_POST)) {
echo json_encode(array("x"=>"y", "m"=>"n"));
exit();
}
every this is ok, and response is what server sends!
But! when in server side I return as response something like this:
if( isset($_POST)) {
echo json_encode(array(array("0"=>"1"),array("2"=>"3"),array("4"=>"5")));
exit();
}
Response is not ok and get this error:
06-17 02:28:53.456 D/Volley: [1296] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] MY_URL 0xa64d9c1b NORMAL 1> [lifetime=3645], [size=60], [rc=200], [retryCount=0]
06-17 02:28:53.466 D/ATA Response: RESPONSE ERROR
06-17 02:28:53.466 E/Volley: [1] 2.onErrorResponse: Error:
What's wrong with my code?

Try sending a content type header. application/json should do the job.
header("Content-type:application/json");
send header before producing any outputs (i.e before echo statement).

Related

Is there any way within middleware running on ASP.NET Core 2.2 to detect if the request is for an ApiController?

I have an application with both MVC and 'new' ApiController endpoints in ASP.NET Core 2.2 co-existing together.
Prior to adding the API endpoints, I have been using a global exception handler registered as middleware using app.UseExceptionHandler((x) => { ... } which would redirect to an error page.
Of course, that does not work for an API response and I would like to return an ObjectResult (negotiated) 500 result with a ProblemDetails formatted result.
The problem is, I'm not sure how to reliably determine in my 'UseExceptionHandler' lambda if I am dealing with an MVC or a API request. I could use some kind of request URL matching (eg. /api/... prefix) but I would like a more robust solution that won't come back to bite me in the future.
Rough psuedo-code version of what I'm trying to implement is:
app.UseExceptionHandler(x =>
{
x.Run(async context =>
{
// extract the exception that was thrown
var ex = context.Features.Get<IExceptionHandlerFeature>()?.Error;
try
{
// generically handle the exception regardless of what our response needs to look like by logging it
// NOTE: ExceptionHandlerMiddleware itself will log the exception
// TODO: need to find a way to see if we have run with negotiation turned on (in which case we are API not MVC!! see below extensions for clues?)
// TODO: ... could just use "/api/" prefix but that seems rubbish
if (true)
{
// return a 500 with object (in RFC 7807 form) negotiated to the right content type (eg. json)
}
else
{
// otherwise, we handle the response as a 500 error page redirect
}
}
catch (Exception exofex)
{
// NOTE: absolutely terrible if we get into here
log.Fatal($"Unhandled exception in global error handler!", exofex);
log.Fatal($"Handling exception: ", ex);
}
});
});
}
Any ideas?
Cheers!
This might be a bit different than what you expect, but you could just check if the request is an AJAX request.
You can use this extension:
public static class HttpRequestExtensions
{
public static bool IsAjaxRequest(this HttpRequest request)
{
if (request == null)
throw new ArgumentNullException(nameof(request));
if (request.Headers == null)
return false;
return request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
}
And then middleware with an invoke method that looks like:
public async Task Invoke(HttpContext context)
{
if (context.Request.IsAjaxRequest())
{
try
{
await _next(context);
}
catch (Exception ex)
{
//Handle the exception
await HandleExceptionAsync(context, ex);
}
}
else
{
await _next(context);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
//you can do more complex logic here, but a basic example would be:
var result = JsonConvert.SerializeObject(new { error = "An unexpected error occurred." });
context.Response.ContentType = "application/json";
context.Response.StatusCode = 500;
return context.Response.WriteAsync(result);
}
see this SO answer for a more detailed version.
If you want to check whether the request is routed to ApiController, you could try IExceptionFilter to hanlde the exceptions.
public class CustomExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (IsApi(context))
{
HttpStatusCode status = HttpStatusCode.InternalServerError;
var message = context.Result;
//You can enable logging error
context.ExceptionHandled = true;
HttpResponse response = context.HttpContext.Response;
response.StatusCode = (int)status;
response.ContentType = "application/json";
context.Result = new ObjectResult(new { ErrorMsg = message });
}
else
{
}
}
private bool IsApi(ExceptionContext context)
{
var controllerActionDesc = context.ActionDescriptor as ControllerActionDescriptor;
var attribute = controllerActionDesc
.ControllerTypeInfo
.CustomAttributes
.FirstOrDefault(c => c.AttributeType == typeof(ApiControllerAttribute));
return attribute == null ? false : true;
}
}
Thanks to all of the advice from others, but I have realised after some more thought and ideas from here that my approach wasn't right in the first place - and that I should be handling most exceptions locally in the controller and responding from there.
I have basically kept my error handling middleware the same as if it was handling MVC unhandled exceptions. The client will get a 500 with a HTML response, but at that point there isn't much the client can do anyway so no harm.
Thanks for your help!

Spring MVC either sending JSON or Redirecting to another page

Hello I have been using Spring 3 for my project, I have been stuck in on point.
if(ajax){
User user = userTemplate.getUser(form.getCreator_id());
int isPremium = user.getPremium();
if ( isPremium == 1 ){
Map<String,String> resultMap = new HashMap<String,String>();
response.setHeader("Access-Control-Allow-Headers", "*");
response.addHeader("Access-Control-Allow-Origin", "*");
resultMap.put("result", "success");
return new Gson().toJson(resultMap);
}else{
return "redirect:/f/redirectedUrl?url="+form.getWeb_page();
}
}
redirectedUrl controller is just for redirecting, but if the request is ajax request then i want to response the request as json.
How can I achieve this, thanks.
Edit : I can understand if request is ajax or not. My problem is if it is ajax i want to response json, if it is not then i want to redirect.
Use this code in your controller to identify if request is ajax or not and based on that you can add your logic.
boolean ajax = "XMLHttpRequest".equals(
getRequest().getHeader("X-Requested-With"));
You can decide it from header("X-Requested-With") of your httpRequest object.
public ModelAndView getDetails(HttpServletRequest request, HttpServletRespone response) {
if(ajax) {
try {
new MappingJacksonHttpMessageConverter().write(object, MediaType.APPLICATION_JSON, new ServletServerHttpResponse(response));
} catch(Exception e) {
logger.error("Error when converting to json");
}
return null;
} else {
return new ModelAndView("viewName");
}
}

POSTing JSON with HttpsURLConnection & OutputStreamWriter fails

I'm using Processing 2.0.2 and importing java's java.net,javax.net, and java.io classes.
I'm trying to send a JSONObject to "https://www.bitstamp.net/api/balance/".
The JSONObject contains login info. I create it with this function:
JSONObject BitstampLoginJSON() {
JSONObject loginJSON = new JSONObject();
loginJSON.setString("password", "mypassword");
loginJSON.setString("user", "username");
return loginJSON;
}
I setup my connection successfully and then pass the connection to this function to send the request.
void SendBitstampBalanceRequestFromConnection(HttpsURLConnection givenCon) {
try {
givenCon.setDoOutput(true);
givenCon.setDoInput(true);
givenCon.setRequestProperty("Content-Type", "application/json");
givenCon.setRequestProperty("Acccept", "application/json");
givenCon.setRequestMethod("POST");
givenCon.connect();
OutputStreamWriter requestSender = new OutputStreamWriter(givenCon.getOutputStream());
String JSONString = BitstampLoginJSON().toString();
requestSender.write(JSONString);
requestSender.flush();
requestSender.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
I get a response code 200 and returned message of "OK". Bitstamp returns a JSON Object that says this:
"error": "Missing user and/or password POST parameters"}
I'm quite confused as to why Bitstamp is not receiving or accepting my JSONObject. I have read about a half dozen posts on SO about JSON and POSTing but I can't seem to get it.

ASP.NET MVC client valitation on ui-dialog?

Razor:
#Html.TextBoxFor(kod => kod.Name)
#Html.ValidationMessage("Name","Client Error Message")
Controller:
[HttpPost]
public JsonResult JsonAddCustomer(Customers customer, string returnUrl)
{
if (customer.Name.Trim().Length == 0)
{
ModelState.AddModelError("Name", "Server Error Message");
}
//Eğer hata yoksa veri tabanına kayıt yapılıyor.
if (ModelState.IsValid)
{
try
{
CusOpp.InsertCustomer(customer);
return Json(new { success = true, redirect = returnUrl });
}
catch (Exception e)
{
ModelState.AddModelError("", "Error");
}
}
return Json(new { errors = GetErrorsFromModelState() });
}
I want to write validation error message. I did this like above, but #Html.ValidationMessage("Name","Client Error Message") does not work. In fact, I was already expecting it.
I want to show like this statement's result: #Html.ValidationMessageFor(m => m.name) ,but I cant use this, because I used entity-data-model.
Should I add [Required] statement to data-model classes or any way that I do this. Sorry for bad explanation.
Thanks.
You should return PartialViews instead of JSON in this case. Only in the case of success you could return JSON:
[HttpPost]
public ActionResult JsonAddCustomer(Customers customer, string returnUrl)
{
// Warning: the following line is something horrible =>
// please decorate your view model with data annotations or use
// FluentValidation.NET to validate it.
// Never write such code in a controller action.
if (customer.Name.Trim().Length == 0)
{
ModelState.AddModelError("Name", "Server Error Message");
}
//Eğer hata yoksa veri tabanına kayıt yapılıyor.
if (ModelState.IsValid)
{
try
{
CusOpp.InsertCustomer(customer);
return Json(new { success = true, redirect = returnUrl });
}
catch (Exception e)
{
ModelState.AddModelError("", "Error");
}
}
return PartialView(customer);
}
Now inside the success callback of your AJAX request you can test whether the POST action succeeded or not:
success: function(result) {
if (result.redirect) {
// we are in the success case => redirect
window.location.href = result.redirect;
} else {
// a partial view with the errors was returned => we must refresh the DOM
$('#some_container').html(result);
// TODO: if you are using unobtrusive client side validation here's
// the place to call the $.validator.unobtrusive.parse("form"); method in order
// to register the unobtrusive validators on the newly added contents
}
}
Here's a similar post that you might also read through.
Your Idea with the Required annotation on the model is a good approach. You can set a Error Message on the Required annotation.
[Required(ErrorMessage = "Please enter a name")]
and remove your if in your action..this:
if (customer.Name.Trim().Length == 0)
{
ModelState.AddModelError("Name", "Server Error Message");
}
the ModelState.IsValid will do the job for you on the client and server side.
And use your #Html.ValidationMessageFor(m => m.name) in your view

restlet client side POST request with header and JSON

Could you please comment what wrong with this client side restlet code.
It is necessary:
Add HTTP header X-MF-Auth-Token with value token
Place JSON file to the body of HTTP request
Make POST request to server
Post request generates "400" error. Thank you very much!
ClientResource cr = new ClientResource(servername + "/json/place");
cr.getRequest().getAttributes().put("X-MF-Auth-Token", token);
Form form = new Form ();
form.add("Category", "");
form.add("CategoryId", "A1EECAB9-3E66-4F14-92E9-465EDFB22BA7");
form.add("Latitude", "0");
form.add("Longitude", "0");
form.add("Name", "Loremipsum");
form.add("PlaceId", "00000000-0000-0000-0000-000000000099");
cr.post(form, MediaType.APPLICATION_JSON);
if (cr.getStatus().isSuccess()) {
// Register Successful
Log.v("Register()", "Successeful");
return true;
} else {
Log.v("Register()", "ERROR");
return false;
}
} catch (ResourceException e) {
// Login Error
Log.v("AddPlace() error:", e.getStatus().toString());
return false;
}
You can use JSONObject instead of Form:
JSONObject jo = new JSONObject();
try {
jo.add("Category", "");
jo.add("CategoryId", "A1EECAB9-3E66-4F14-92E9-465EDFB22BA7");
jo.add("Latitude", "0");
jo.add("Longitude", "0");
jo.add("Name", "Loremipsum");
jo.add("PlaceId", "00000000-0000-0000-0000-000000000099");
} catch (JSONException ex) {
}
cr.post(new JsonRepresentation(jo), MediaType.APPLICATION_JSON);
i think you're not adding X-MF-Auth-Token to the header.
try
Form headers = (Form) cr.getRequest().getAttributes("org.restlet.http.headers");
if (headers == null) {
headers = new Form();
cr.getRequest().getAttributes.put("org.restlet.http.headers", headers);
}
headers.add("X-MF-Auth-Token", token);