JsonObjectRequest doesn't response neither listener or errorListener - android-volley

My JsonObjectRequest doesn't do as my instructions.
Does volley API go on strike?
My log cat just says "Requested URL: http://..".
My log cat doesn't say neither "Json Parsing Error:" or "HTTP Request Error:".
Please, anybody, tell me What did I do wrong.
String url = REST_URL + "?seq=" + mLastSeq;
Log.i(DEBUG_TAG, "Requested URL: "+url);
JsonObjectRequest req = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
mLastSeq = response.getInt("last");
mNewCount = response.getInt("count");
Log.i(DEBUG_TAG, mLastSeq+"");
Log.i(DEBUG_TAG, mNewCount+"");
if (mNewCount>0) {
String title = mCtx.getResources().getString(R.string.app_name);
String message = mCtx.getResources().getString(R.string.new_news_alert);
showNotification(title, message);
}
} catch (JSONException error) {
Log.d(DEBUG_TAG, "Json Parsing Error: " + error.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(DEBUG_TAG, "HTTP Request Error:" + error.getMessage());
}
});

The application may be doing too much work on its main thread.

Related

Sending large messages through STOMP failes on Client-Side

I want to send a file (like 4/5 MB) from my Angular-Frontend to a SpringBoot-Server. I am using STOMP via StompJS and whenever i try to send the content of the file, my client looses connection... (i think because of the message size => small strings work).
Is there a way to send a very big string or the whole file to my java backend? I also tried to send the bytes but than the result on the server-side was and empty file. Thanks!
PS: I already changed the buffer size of the server, so the problem must be at the stompjs-client...
Connection-Service (frontend):
public setupConnection() {
console.log("Initialize WebSocket Connection");
let ws = new SockJS(this.webSocketEndPoint);
this.stompClient = Stomp.over(ws);
this.stompClient.maxWebSocketChunkSize = 10000000;
this.stompClient.splitLargeFrames = true;
const _this = this;
_this.stompClient.connect({}, function (frame) {
_this.stompClient.subscribe(_this.subscribeDestination, _this.stompClient.send("/app/userdata", {}, "data"), function (sdkEvent) {
_this.onMessageReceived(sdkEvent);
});
//_this.stompClient.reconnect_delay = 2000;
}, this.errorCallBack);
}
onMessageReceived(message) {
console.log("Message Recieved from Server :: " + message);
var result = JSON.stringify(message.body);
console.log(result);
}
errorCallBack(error) {
console.log("errorCallBack -> " + error )
setTimeout(() => {
this.setupConnection();
}, 5000);
}
send(message) {
console.log("Sending message...");
this.stompClient.send("/app/config", {}, message);
}
public selfRegistration(){
this.stompClient.send("/app/userdata",{}, "userdata");
}
File-Input-Handling (frontend):
// as string
onFileChangeString(event){
this.file= event.target.files[0];
const reader = new FileReader();
reader.onload = (e) => {
this.fileLoaded = true;
this.filecontent = reader.result as String;
this.connectionService.send(this.filecontent);
}
reader.readAsText(this.file);
}
//as arraybuffer
onFileChangeBuffer(event){
this.file= event.target.files[0];
const reader = new FileReader();
reader.onload = (e) => {
this.fileLoaded = true;
this.filecontent = reader.result as ArrayBuffer;
var array = new Uint8Array(this.filecontent);
this.connectionService.send(array);
}
reader.readAsArrayBuffer(this.file);
}
Message-Handling (backend):
#Override
public void configureWebSocketTransport(WebSocketTransportRegistration registry) {
registry.setMessageSizeLimit(100000000);
registry.setSendBufferSizeLimit(100000000);
}
//try string
#MessageMapping("/config")
#SendToUser("/ba/configuration")
public String recieveConfigurationFileString(String message, #Header("simpSessionId") String sessionId, Principal principal) throws Exception {
System.out.println("Received config message from" + message +" " + principal.getName() +" " + sessionId);
return "testresult";
}
//try byte array
#MessageMapping("/config")
#SendToUser("/ba/configuration")
public String recieveConfigurationFile(byte[] message, #Header("simpSessionId") String sessionId, Principal principal) throws Exception {
System.out.println("Received config message from" + message +" " + principal.getName() +" " + sessionId);
// how to handle byte input?
return "testresult";
}
The console output is :
Sending message...
compat-client.js:32 >>> SEND
destination:/app/config
content-length:1970879
compat-client.js:32 chunk sent = 1969497, remaining = 0
compat-client.js:32 Connection closed to undefined

AJAX + Spring MVC: Cannot find destination

I have a form which should send user input via ajax to my spring mvc controller.
But I always get an Error as you can see below. I implemented into getSearchResultViaAjax a System.out.println("in getSearchResultViaAjax");
but it is never called in the console. Any idea how I could fix that?
Error Message:
{
"readyState": 4,
"responseText": "{\"timestamp\":\"2018-03-24T18:33:14.749+0000\",\"status\":404,\"error\":\"Not Found\",\"message\":\"No message available\",\"path\":\"/$%7Bhome%7D/search/api/getSearchResult\"}",
"responseJSON": {
"timestamp": "2018-03-24T18:33:14.749+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/$%7Bhome%7D/search/api/getSearchResult"
},
"status": 404,
"statusText": "error"
}
I tried in AJAX also paths like:
url: "/search/api/getSearchResult"
url: "search/api/getSearchResult"
and get this then for example
{
"readyState": 4,
"responseText": "{\"timestamp\":\"2018-03-24T19:48:43.638+0000\",\"status\":500,\"error\":\"Internal Server Error\",\"message\":\"Error resolving template \\\"search/api/getSearchResult\\\", template might not exist or might not be accessible by any of the configured Template Resolvers\",\"path\":\"/search/api/getSearchResult\"}",
"responseJSON": {
"timestamp": "2018-03-24T19:48:43.638+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Error resolving template \"search/api/getSearchResult\", template might not exist or might not be accessible by any of the configured Template Resolvers",
"path": "/search/api/getSearchResult"
},
"status": 500,
"statusText": "error"
}
Controller:
#Controller
#RequestMapping("")
public class View {
#Autowired
PController controller;
List<User> users;
/**
* After user coin choice is filled with details, it arrives here.
*
* #param httpEntity the http entity
* #return the string
*/
#RequestMapping(method = RequestMethod.POST)
public String arriveAfterSetup(
HttpEntity<String> httpEntity,
#RequestParam(required = false, value = "name") String name,
#RequestParam(required = false, value = "age") String age,
final ModelMap modelMap
) {
modelMap.put("elementList", controller.getDatabase().getPersonLinkedList());
return "main/mainpage";
}
#RequestMapping(method = RequestMethod.GET)
public String exchangeViewAfterEdit(ModelMap modelMap
) {
modelMap.put("elementList", controller.getDatabase().getPersonLinkedList());
return "main/mainpage";
}
#RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
public void editPerson(ModelMap modelMap,
#PathVariable String id,
#RequestParam("name") String name,
#RequestParam("age") Double age
) {
//update db
}
// #RequestBody - Convert the json data into object (SearchCriteria) mapped by field name.
// #JsonView(Views.Public.class) - Optional, limited the json data display to client.
#JsonView(Views.Public.class)
#RequestMapping(value = "/search/api/getSearchResult")
public AjaxResponseBody getSearchResultViaAjax(#RequestBody SearchCriteria search) {
System.out.println("in getSearchResultViaAjax");
AjaxResponseBody result = new AjaxResponseBody();
if (isValidSearchCriteria(search)) {
List<User> users = findByUserNameOrEmail(search.getUsername(), search.getEmail());
if (users.size() > 0) {
result.setCode("200");
result.setMsg("");
result.setResult(users);
} else {
result.setCode("204");
result.setMsg("No user!");
}
} else {
result.setCode("400");
result.setMsg("Search criteria is empty!");
}
//AjaxResponseBody will be converted into json format and send back to client.
return result;
}
private boolean isValidSearchCriteria(SearchCriteria search) {
boolean valid = true;
if (search == null) {
valid = false;
}
if ((StringUtils.isEmpty(search.getUsername())) && (StringUtils.isEmpty(search.getEmail()))) {
valid = false;
}
return valid;
}
// Init some users for testing
#PostConstruct
private void iniDataForTesting() {
users = new ArrayList<User>();
User user1 = new User("mkyong", "pass123", "mkyong#yahoo.com", "012-1234567", "address 123");
User user2 = new User("yflow", "pass456", "yflow#yahoo.com", "016-7654321", "address 456");
User user3 = new User("laplap", "pass789", "mkyong#yahoo.com", "012-111111", "address 789");
users.add(user1);
users.add(user2);
users.add(user3);
}
// Simulate the search function
private List<User> findByUserNameOrEmail(String username, String email) {
List<User> result = new ArrayList<User>();
for (User user : users) {
if ((!StringUtils.isEmpty(username)) && (!StringUtils.isEmpty(email))) {
if (username.equals(user.getUsername()) && email.equals(user.getEmail())) {
result.add(user);
continue;
} else {
continue;
}
}
if (!StringUtils.isEmpty(username)) {
if (username.equals(user.getUsername())) {
result.add(user);
continue;
}
}
if (!StringUtils.isEmpty(email)) {
if (email.equals(user.getEmail())) {
result.add(user);
continue;
}
}
}
return result;
}
}
JS
$(document).ready(function () {
$('#myModal').on('shown.bs.modal', function () {
$('#myInput').focus();
});
$("#search-form").submit(function(event) {
// Disble the search button
enableSearchButton(false);
// Prevent the form from submitting via the browser.
event.preventDefault();
searchViaAjax();
});
});
function searchViaAjax() {
var search = {}
search["username"] = $("#username").val();
search["email"] = $("#email").val();
$.ajax({
type: "POST",
contentType: "application/json",
url: "${home}/search/api/getSearchResult",
data: JSON.stringify(search),
dataType: 'json',
timeout: 100000,
success: function (data) {
console.log("SUCCESS: ", data);
display(data);
},
error: function (e) {
console.log("ERROR: ", e);
display(e);
},
done: function (e) {
console.log("DONE");
enableSearchButton(true);
}
});
}
function enableSearchButton(flag) {
$("#btn-search").prop("disabled", flag);
}
function display(data) {
var json = "<h4>Ajax Response</h4><pre>"
+ JSON.stringify(data, null, 4) + "</pre>";
$('#feedback').html(json);
}
function searchAjax() {
var data = {}
data["query"] = $("#query").val();
$.ajax({
type: "POST",
contentType: "application/json",
url: "${home}search/api/getSearchResult",
data: JSON.stringify(data),
dataType: 'json',
timeout: 100000,
success: function (data) {
console.log("SUCCESS: ", data);
display(data);
},
error: function (e) {
console.log("ERROR: ", e);
display(e);
},
done: function (e) {
console.log("DONE");
}
});
}
Thank you a lot!
"${home}/search/api/getSearchResult" in searchViaAjax seems very odd.
${home} looks like a template string, but it's not being replaced, you can tell since your error message says: "path": "/$%7Bhome%7D/search/api/getSearchResult"

How to upload file using angular4 rest API and spring-boot

i implemented this part of code with spring for the backend part
#PostMapping("/upload")
public ResponseEntity<String> handleFileUpload(#RequestParam("file") MultipartFile file) {
String message = "";
try {
sp.store(file);
files.add(file.getOriginalFilename());
message = "You successfully uploaded " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.OK).body(message);
} catch (Exception e) {
message = "FAIL to upload " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
}
}
and fo the angular part i have this for the frontend but i have an error in the hhtpRequest the /post
pushFileToStorage(file: File): Observable<HttpEvent<{}>> {
let formdata: FormData = new FormData();
formdata.append('file', file);
const req = new HttpRequest('POST', '/post', formdata, {
reportProgress: true,
responseType: 'text'
});
return this.http.request(req);
}

how to call ajax success and error function from controller?

I have ajax function
$.ajax({
....
type: "POST",
url: "",
data: "",
success: function(){
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
}
});
& controller code is
public #ResponseBody
GenericResponse abc() {
try {
....
} catch (Exception ex) {
ex.printStackTrace();
return new GenericResponse("Failed", ex.getMessage(), 500);
}
return new GenericResponse("Success", "", 200);
}
where GenericResponse is
public class GenericResponse
{
private String status;
private String error;
private int code;
public GenericResponse(String s, String e, int c)
{
this.status = s;
this.error = e;
this.code = c;
}
....
}
So for success & failure I am sending genericresponse with status but for both it goes inside success callback function.
I understand that it is gennericResponse so ajax would consider it as success only . If exception comes
I want it to go to error callback function. How to do that?
Instead of returning a GenericResponse, try returning a ResponseEntity instead.
You would do:
return new ResponseEntity<GenericResponse>(successGenericResponse, HttpStatus.OK);
or
return new ResponseEntity<GenericResponse>(failGenericResponse, HttpStatus.INTERNAL_SERVER_ERROR);

How to handle the 400 response from youtube gdata "response"?

I have app that allows users to fill a form containing a youtube link. Many a times, the video link is invalid and I'd have to fix it manually. I want to validate the url before I allow user to submit the form.
I'm wrote some code on the firebug console:
function test() {
// var x1 = "http://gdata.youtube.com/feeds/api/videos/OvcaXrWFM2Q";
var x1 = "http://gdata.youtube.com/feeds/api/videos/VIDEO_ID?alt";
var asd = false;
$.ajax({
dataType: 'jsonp',
async: false,
url: x1,
/* success: function(data) {
console.log("success --> ", data.length);
return true;
},
error: function(error) {
console.log("error --> ", error);
},
*/ complete: function(e){
console.log("complete --> ", e);
return true;
}
});
// return false ;
return asd;
}
var y = test();
if (y) {
console.log("success y --> " + y);
} else {
console.log("error y --> " + y);
}
Invalid 400 request:
>>> function test() { // var x1 = "http://gdata.y...} else { console.log("error y --> " + y); }
error y --> false
"NetworkError: 400 Bad Request - http://gdata.youtube.com/feeds/api/videos/VIDEO_ID?alt&callback=jsonp1375741532312&_=1375800027900"
Valid response:
>>> function test() { var x1 = "http://gdata.you...} else { console.log("error y --> " + y); }
error y --> false
success --> 4516
jquery....min.js (line 29)
complete --> undefined
jquery....min.js (line 29)
What can I do to catch that 400? Also, it seems the code gets to "console.log("success y --> " + y);" before it gets to the success: function().
Edit:
My other option is to send this validation to backend using java, but I'd prefer it using js.
public static void main(String[] args) throws ParseException {
String[] urls = new String[2];
urls[0] = "http://gdata.youtube.com/feeds/api/videos/OvcaXrWFM2Q";
urls[1] = "http://gdata.youtube.com/feeds/api/videos/23487978923789423789342sufyu";
HttpURLConnection con;
HttpURLConnection.setFollowRedirects(false);
for (String url : urls) {
try {
con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("HEAD");
System.out.println(con.getResponseCode());
} catch (IOException e) {
System.out.println(e);
}
}
}
Output I get as expected, 200 for valid video id, 400 for the invalid one.
To get the response status code, I had to move the check to backend java. Javascript just couldn't do it.
public static void main(String[] args) throws ParseException {
String[] urls = new String[2];
urls[0] = "http://gdata.youtube.com/feeds/api/videos/OvcaXrWFM2Q";
urls[1] = "http://gdata.youtube.com/feeds/api/videos/23487978923789423789342sufyu";
HttpURLConnection con;
HttpURLConnection.setFollowRedirects(false);
for (String url : urls) {
try {
con = (HttpURLConnection) new URL(url).openConnection();
con.setRequestMethod("HEAD");
System.out.println(con.getResponseCode());
} catch (IOException e) {
System.out.println(e);
}
}
}

Resources