Extjs4 / Spring MVC and response.responseText - json

In extjs4 controller i call
form.submit({
url: '/bookstore/api/books/add',
waitMsg: 'Uploading your file...',
success: this.onAddBookSuccess,
failure: function(response, opts){
var data = Ext.decode(response.responseText);
Ext.MessageBox.alert('Error', 'Some problem occurred' + data);
}
});
My spring mvc controller code for '/bookstore/api/books/add'
#RequestMapping(value = "/api/books/add", method = RequestMethod.POST)
public
#ResponseBody
Map<String, ? extends Object> addUser(BookUploadBean bean, BindingResult result) {
Map<String, Object> data = new HashMap<String, Object>();
if (bean.getTitle().compareTo("1") == 0) {
data.put("success", Boolean.FALSE);
data.put("errors", "asdasdasd");
return data;
}
Book book = new Book();
book.setTitle(bean.getTitle());
book.setAuthor(bean.getAuthor());
book.setYear(bean.getYear());
book.setPrice(bean.getPrice());
book.setDescription(bean.getDescription());
book = userRepository.save(book);
data.put("success", Boolean.TRUE);
return data;
}
I get from '/bookstore/api/books/add' 2 variants of json response:
Error json : {"errors":"asdasdasd","success":false}
Success json {"success":true}
And server really returned this values
But if i try get response.responseText, i get undefined value. How I can get "errors" values in my failure function?

When u submit a form you get the response still decoded into the property "result" of the second parameter of the callback.
So in your example:
form.submit({
url: '/bookstore/api/books/add',
waitMsg: 'Uploading your file...',
success: this.onAddBookSuccess,
failure: function(form, action){
Ext.MessageBox.alert('Error', 'Some problem occurred' + action.result.errors);
}
});
Hope this help :)

Related

A common request method with decoder passed as parameter in Flutter using Dio

Not sure if what I'm trying to do is a foolish en-devour or ? In the app, I use rest API calls and I'm trying to implement API handling with Dio.
I have gone with an approach like so.
each API method has a generic function. ie: the POST method. goes like
Future<dynamic> postRequest({String? endPoint, dynamic decoder, data}) async {
// late String _fullURL = BaseOptions().baseUrl + endPoint!;
late int? _responseCode;
try {
final response = await _dio.post(
endPoint!, // APIEndpoints.postSignUp,
data: data, //jsonEncode(data),
);
//
// final String _responseString = response.data;
_responseCode = response.statusCode;
//
if (_responseCode == 200) {
final String _responseString = response.data;
final res = decoder(_responseString);
log("post success response ------------ ${res.toString()}");
return SuccessHandler().checkSuccess(res);
} else if (_responseCode == 201) {
log("post success no response ------------ ");
return HTTPResponse<dynamic>(
false,
null,
message: 'empty success',
code: _responseCode!,
//'Something went wrong! Please try again in a moment!',
);
} else {
log("post failed response ------------ ");
return null;
// return ErrorHandler().checkError(_responseCode, _responseString);
}
} on DioError catch (e) {
// print(e.message);
// throw Exception(e.message);
log("exception ------------ ${e.message}");
return HTTPResponse<dynamic>(
false,
null,
message: 'error: ${e.message}',
code: e.response!.statusCode!,
//'Something went wrong! Please try again in a moment!',
);
}
}
Where I try to pass the decoder to get the JSON response read out from the API response. Using a generated class like this
ValidateEmailModel validateEmailModelFromJson(String str) =>
ValidateEmailModel.fromJson(json.decode(str));
String validateEmailModelToJson(ValidateEmailModel data) =>
json.encode(data.toJson());
class ValidateEmailModel {
ValidateEmailModel({
this.email,
this.type,
this.code,
this.expire,
this.createdTime,
});
String? email;
String? type;
String? code;
dynamic expire;
dynamic createdTime;
factory ValidateEmailModel.fromJson(Map<String, dynamic> json) =>
ValidateEmailModel(
email: json["email"],
type: json["type"],
code: json["code"],
expire: DateTime.parse(json["expire"].toString()),
createdTime: DateTime.parse(json["createdTime"].toString()),
);
Map<String, dynamic> toJson() => {
"email": email,
"type": type,
"code": code,
"expire": expire!.toIso8601String(),
"createdTime": createdTime!.toIso8601String(),
};
}
In my method calls. i give the function its paramters like so
res = await APIHandler.instance.postRequest(
endPoint: APIEndpoints.postValidateCode,
decoder: validateEmailModelFromJson,
data: {
"code": val,
"email": _email,
},
)
And await the response to be passed to another common method SuccessHandler() so I can get the data object/s
class SuccessHandler {
dynamic successObject;
SuccessHandler({this.successObject});
Future<dynamic> checkSuccess(dynamic response) async {
return SuccessHandler(successObject: response);
}
}
so far when I try to debug the code. I do get the response.data from the Dio response. but gives me
Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String'
can I achieve what I need to and how can I update the code? Please help me with this or just I think I'm trying to reinvent the wheel here.
validateEmailModelFromJson what this function will do is take a string convert it into json and will parse it you data model but in you postRequest function you are already get a json response from api call so no need to pass a decoder to you function.
where you are returning SuccessHandler().checkSuccess(res); directly return the _responseString so it should be like this,
if (_responseCode == 200) {
final String _responseString = response.data;
log("post success response ------------
${_responseString}");
return SuccessHandler().checkSuccess(_responseString);
}
now try directly using ValidateEmailModel.fromJson on _responseString, you will get the data

How to export JSON to JSP?

I'm having an issue with JSON and JSP. My Java code creates a JSON from a map, like this:
#RequestMapping(value = "/internationalWAExpose", method = RequestMethod.GET)
#ResponseBody
public String exposeWAData(final HttpServletRequest request) {
Map<String, WebAnalyticsDataValue> ajaxDataMap = new HashMap<>();
WAGlobalDataHandler globalHandler = WebAnalyticsFactory.getHandler(WAGlobalDataHandler.class);
globalHandler.setGlobalData(request, "Home", "Content");
ajaxDataMap.putAll(globalHandler.getDataMap());
JSONObject json = new JSONObject();
ajaxDataMap.forEach((k, v) -> {
try {
json.put(k, v);
} catch (JSONException e) {
e.printStackTrace();
}
});
return json.toString();
}
And I need to get the JSON on a JSP to be exposed in the elements section.
So far, I managed to set it in a JS with an Ajax call, but it shows on the console, rather than in the elements section.
AAUI.ajaxRequest({
url: '/home/ajax/internationalWAExpose',
type: 'GET',
dataType: 'json',
timeout: 50000,
onSuccess: function onSuccess(jsonResponse, textStatus) {
var webAnalyticsData = [];
for (var x in jsonResponse) {
webAnalyticsData.push(new KeyValueObject(x, jsonResponse[x]));
}
waTealiumUtils.reportEvent(webAnalyticsData, "view");
},
onError: function onError() {
},
onComplete: function onComplete() {
}
})
Any ideas? Be advised, I'm quite a newbie to JS and JSP.

MVC Return a Json with List and Dictionary

I'm trying to return the following as JSON
List<string>, Dictionary<int, string>
When I try to return
List<string>
everything works great. The issue is the introduction of the Dictionary
My controller is hit and it returns but always returns to the error callback in my ajax function.
I don't understand why.
Some real code now!
[HttpGet]
public JsonResult GetPageLoad()
{
var dc = new Bll.DataAccess();
var urls = dc.GetUrls(1); //List<string>
var templates = dc.GetTemplates(); // dictionary
return Json(new { urls = urls, templates = templates}, JsonRequestBehavior.AllowGet);
}
And the ajax is
$.ajax({
type: type.toUpperCase(),
url: url,
contentType: "application/json;",
data: data,
dataType: "json",
success: function (response) {
successDelegate(response);
},
failure: function (e) {
failDelegate(e.statusText);
},
error: function (e) {
errorDelegate(e.statusText);
}
})
I don't see any error warning other than Internal Server Error but I don't see why. I'm guessing it's something to do with parsing the Dictioanry but I am unable to work out how to fix this
The issue is the key in the dictionary must be of type string or object.
I had Dictionary<int, string>
Changing it to Dictionary<string, int> resolves the issue

Watson SpeechToText Java and javascript model differences

I'm working on integrating the watson-speech.js javascript library with a Spring-based server using the Watson Java SDK. I'm trying to send the output from a WatsonSpeech.SpeechToText.recognizeMicrophone call to the server with no luck. The Speech java classes appear to have the appropriate #SerializedName annotations that match the json being sent from the client, but I'm getting UnrecognizedPropertyException errors from Jackson.
Unrecognized field "keywords_result" (class com.ibm.watson.developer_cloud.speech_to_text.v1.model.SpeechResults), not marked as ignorable (2 known properties: "resultIndex", "results"])
Here's the controller method:
#RequestMapping(value = "/postWatsonRequest", method = RequestMethod.POST)
#ResponseBody
#ResponseStatus(value=HttpStatus.OK)
public ResponseObject postWatsonRequest(#RequestBody SpeechResults speechResults) {
...
}
I'm clearly missing something. Do I need to unpack the json manually on the server side (custom deserializer?) or format it into an acceptable json string on the client side?
It turned out to be a couple of mistakes on my part and although I'm not sure this is the best solution it does work. Here's the full code for anyone that's interested. Key things that made it work:
You must use the receive-jason event to capture the full json result. The data event appears to only return the final text
The result data had to be wrapped in a valid json wrapper - data:{message:data} (this was my big mistake)
Do not include contentType: 'application/json; charset=utf-8', in the ajax call or the controller will not recognize the json data
The Watson Java SDK WebSocketManager receives an okhttp3.ResponseBody from Watson from which it extracts a string. I presume this is similar to what the javascript SDK receives so I used the same code from the WebSocketManager to convert the JSON.stringify string to a SpeechResults object in the controller.
From the okhttp3.ResponseBody javadoc:
A one-shot stream from the origin server to the client application with the raw bytes of the response body
Watson javascript
function listen(token) {
stream = WatsonSpeech.SpeechToText.recognizeMicrophone({
token: token,
readableObjectMode: true,
objectMode: true,
word_confidence: true,
format: false,
keywords: keywordsArray,
keywords_threshold : 0.5,
continuous : false
//interim_results : false
//keepMicrophone: navigator.userAgent.indexOf('Firefox') > 0
});
stream.setEncoding('utf8');
stream.on('error', function(err) {
console.log(err);
stream.stop();
});
stream.on('receive-json', function(msg) {
console.log(msg);
if (msg.state != 'listening') {
if (msg.results[0].final) {
console.log('receive-json: ' + msg);
postResults(msg);
stream.stop();
}
}
});
}
Ajax post
function postResults(results) {
var data = JSON.stringify(results);
console.log('stringify: ' + data);
$.ajax({
type: 'POST',
url: appContextPath + '/postWatsonResult',
dataType: 'json',
data: {message:data}
})
.done(function(data) {
console.log('done data: '+ data);
})
.fail(function(jqXHR, status, error) {
var data = jqXHR.responseJSON;
console.log('fail data: '+ data);
});
}
Spring controller
#RequestMapping(value = "/postWatsonResult", method = RequestMethod.POST)
#ResponseBody
#ResponseStatus(value=HttpStatus.OK)
public ResponseObject postWatsonResult(#RequestParam("message") String message, Locale locale) {
logger.info("postWatsonRequest");
JsonObject json = new JsonParser().parse(message).getAsJsonObject();
SpeechResults results = null;
if (json.has("results")) {
results = GSON.fromJson(message, SpeechResults.class);
}
if (results != null) {
logger.debug("results: " + results.getResults().get(0).getAlternatives().get(0).getTranscript());
}
return new ResponseObject();
}
I still think it should be possible somehow to use #RequestBody SpeechResults speechResults so I'll continue to play around with this, but at least I have a working solution.

Obtaining JSON data from server into $.ajax call

I have a problem with JSON and JQUERY. In my web application I submit some data (through an $.ajax call) to a servlet and want to receive back some informations from this servlet once it has done.
I'm using JSONObject in this way:
function check(){
$.ajax({
url: "/check",
type: "POST",
dataType: "json",
success: on_check_ok,
error: function(){
alert("something wrong happened");
},
data: {
players_code: $("#players_code").val(),
},
});
return false;
}
function on_check_ok(data) {
var json = data;
$("#display").text(json.check); //"display" is a <div> into index.html
};
and this is doPost() method in my servlet code:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("application/json");
PrintWriter out = response.getWriter();
String code_array = request.getParameter("players_code");
System.out.println("Player's code is: " + code_array);
int arr = Integer.parseInt(code_array);
LinkedList<Integer> stack = new LinkedList<Integer>();
while(arr > 0){
stack.push(arr%10);
arr = arr/10;
}
int index = 0;
while(!stack.isEmpty()){
array[index] = (int)stack.pop();
index++;
}
mm.checkGuess(array);
response.getWriter().write(mm.ris + " ");
tries++;
System.out.println("TRIES: " + tries);
JSONObject obj = new JSONObject();
obj.put("check", tries);
String json = obj.toString();
out.write(json);
System.out.println("JSON " + json);
}
}
but cannot get displayed any information. Seems that JSONObject has been created correctly, since I can display it on console. I'm having hard times on getting this data back to javascripts.
That's my code, what I'm doing wrong? Or, is there an alternative way to get the same result? thanks for the help!