I'm trying to call a web service I made using Jersey.
I tested the services by calling them from a console java app, and its working perfectly fine.
When calling from Android, it first gave me android.os.NetworkOnMainThreadException, I searched and found out that i should use AsyncTask to solve that,
the following code crashes when "response.getEntity(String.class)" is called
while calling a get service, if i return the status ( response.getStatus()) instead of getEntity, it works fine. But the same thing doesnt work in case of a post request. getEntity() crashes on both
public String postTest(String arg){
Log.d("Service", "postRegister1");
client = Client.create();
WebResource service=client.resource(getBaseURI());
Log.d("Service", "postRegister2");
Form form = new Form();
form.add("arg", "lol");
int status;
ClientResponse response=null;
try{
response = service.path("test").get(ClientResponse.class);
//post
// response = service.path("post").path("test").post(ClientResponse.class,from);
Log.d("Service", "postRegister3");
status = response.getStatus();
//comment out the following if statement and the code will work perfectly fine, returning the stats
if(status == 200){
return response.getEntity(String.class);
}
return String.valueOf(response.getStatus());
}
catch(ClientHandlerException e){
Log.d("Exception1",e.getMessage()+ " ");
}
catch(UniformInterfaceException e){
Log.d("Exception2",e.getMessage()+ " ");
}
catch(Exception e){
Log.d("Exception3",e.getMessage()+ " ");
}
return "exception";
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
Log.d("doInback", params[0]);
return postTest(params[0]);
}
the code above code is part of the class:
public class Service extends AsyncTask<String, Void, String>{
and is called like:
try {
alert(new Service().execute("lol").get(),view);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
the alert method just displays an alert.
Solved by using a library for implementing Async Http
client.
The tutorial which i followed can be found here.
Related
In my current code i had a servlet from which if i create post to the servlet it will open a new websocket client , that mean 10 client connection each running for same purpose but with different api and secret , so i need to close particular session
I am using Jetty :: Websocket :: Client v9.4.48.v20220622
Please suggest , as i can get the session details but unable to use because it's not working with String data type . only in Session session it is working and i am unable to store session details anywhere else , as only in String data type i can save .
Whereas a is my API and b is my Secret Key ;
PS : Websocket connection is working fine to send expected data
class connector {
String a;
String b;
public void start() {
WebSocketClient client = new WebSocketClient();
MyWebSocket socket = new MyWebSocket();
try {
client.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
URI destUri = null;
try {
destUri = new URI("wss://socket.delta.exchange");
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ClientUpgradeRequest request = new ClientUpgradeRequest();
System.out.println("Connecting to: " + destUri);
try {
client.connect(socket, destUri, request);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
socket.awaitClose(3600, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
client.stop();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#WebSocket
public class MyWebSocket {
private final CountDownLatch closeLatch = new CountDownLatch(1);
#OnWebSocketConnect
public void onConnect(Session session) throws IOException {
session.getRemoteAddress();
System.out.println("Connection opened");
PingPong newObj = new PingPong();
newObj.session = session;
Authorization authMe = new Authorization();
Identifier getSt = new Identifier();
newObj.enableHeartBeat();
System.out.println(session);
session.getRemote().sendString(authMe.data(a, b));
}
#OnWebSocketMessage
public void onMessage(String message) {
MessageHandler objmsg = new MessageHandler();
objmsg.check();
System.out.println(
"Current Thread ID: "
+ Thread.currentThread().getId());
System.out.println("Message from Server: -- " + message);
}
#OnWebSocketClose
public void onClose(int statusCode, String reason) {
System.out.println("WebSocket Closed. Code:" + statusCode);
}
public boolean awaitClose(int duration, TimeUnit unit)
throws InterruptedException {
return this.closeLatch.await(duration, unit);
}
}
}
I want to do session.close() for a particular session details which i got from
session.getRemoteAddress().toString();
Session session ;
String sessionDetailSaved ;
i want to search for sessionDetailSaved and compare with all the on running sessions and close it
Or else any other way i can close particular session with different method may be interrupting session thread but sure it will not completely close connection .
Maven Dependency i am using
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-client</artifactId>
<version>9.4.48.v20220622</version>
</dependency>
Calling Session.close() will initiate a close handshake where the remote endpoint should reply with a response close frame, and once the close response has been received the WebSocket connection will be closed. You can send custom close status code and reason with Session.close(int statusCode, String reason).
You also have the option to call Session.disconnect() which will do a hard close of the underlying connection without sending this close frame.
In regards to your code, it looks like you are never completing the closeLatch in the OnWebSocketClose method, so your awaitClose method will always timeout.
Also, if possible you should try to re-use the same WebSocketClient instance for multiple connections because it is a heavy weight object. It is expensive to create a new one for each request.
I am trying to fetch the data and store it in database.
Created a Get mapping for invoking the data from url and storing it in database using service class .
#GetMapping("/")
public String root(Model model) throws IOException {
model.addAttribute("test1","Hello user");
service.populate();
return "mainTemplate";
}
my populate method in service class add data to database.
public void populate() throws IOException{
URL url = new URL("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_daily_reports/01-01-2021.csv");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
int res= connection.getResponseCode();
CSVReader reader=null;
if(res==200) {
log.info("Connected to github");
try {
BufferedReader readurl = new BufferedReader(new InputStreamReader(connection.getInputStream()),8192);
reader=new CSVReader(readurl);
String[] line;
int i=0;
while((line=reader.readNext())!=null) {
if(i==0) {
i++;
continue;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
Corona corona = new Corona();
corona.setLastupDate(LocalDateTime.parse(line[4],formatter));
corona.setConfirmed(Long.valueOf(line[7]));
corona.setRecovered(Long.valueOf(line[9]));
corona.setActive(Long.valueOf(line[10]));
corona.setCombinedKey(line[11]);
log.info(corona.toString());
repo.save(corona);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CsvValidationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
if(reader!=null) {
try {
reader.close();
} catch (IOException e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}
}
else {
log.info("URL is wrong");
}
}
Everything is working fine when i hit the resource url ,but i have to wait for some time to show my webpage , until all data does not get stored in database.
I want to show "Data is being added" in mainTemplate.html as soon as i hit the url. So that my populate method runs in background and i don't have to wait for completion of method to show my mainTemplate .
I tired to add #Async method annotation but that does not seem to be worked .
My post request code as follows
When post request to the server it reach twice in to the server
and i am sure call httpRequest once.When i call once the request reach server twice or thrise;
private void invokePostOrderRestService(
final RestPostDataCallback<Order> callback,
final RequestOrder requestOrder) {
String URL = BASE_URL + "postOrder";
Log.e("post ordercccccc", "orderPosted");
JSONObject jsonObject = convertOrderRequestToJson(requestOrder);
if (jsonObject != null) {
OrderProApplication
.getContext()
.getRestClient()
.postJsonObject(URL, jsonObject,
new ResponseListener<JSONObject>() {
#Override
public void onSuccess(JSONObject response) {
// TODO Auto-generated method stub
Log.e("Order Post Success","Post Order Successssssssssssssssss");
String status = "";
try {
status = response.getString("status");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (status.equals("OK")) {
callback.onRestPostDataCompleted(
ResultCode.RESULT_OK, null);
} else {
callback.onRestPostDataCompleted(
ResultCode.RESULT_FAIL, null);
}
}
#Override
public void onRestError(RestError error) {
// TODO Auto-generated method stub
Log.e("Order Post Failed","Post Order failedddddddddddddddddddd");
i = i + 1;
callback.onRestPostDataCompleted(
ResultCode.RESULT_FAIL, null);
}
});
} else {
callback.onRestPostDataCompleted(ResultCode.RESULT_FAIL, null);
}
}
And am pretty sure my url is correct.
Thanks:).
Most likely your method is being called twice. Check where you are calling out the method - this might be occurred thanks to misunderstanding of Activity/Fragment lifecycle.
Put a print in the beginning of your invoke method and check, if it prints out twice.
In the AsyncTask android. When calling a method in another class gets an exception which equals to null in the doInBackGround() task.
Even the hard coded inside the rest.request(url, method, json) doesn't work
protected JSONArray doInBackground(Void... arg0) {
try {
return rest.request(url, method, json); // <-- returns json array
} catch (Exception e) {
this.e = e;
}
return null; // <--- returning this null
}
Other things are like this,
private class doRequest extends AsyncTask<Void, JSONArray, JSONArray>
protected void onPostExecute(JSONArray data)
/*rest client class*/
public class AndrestClient {
// The client to use for requests
DefaultHttpClient client = new DefaultHttpClient();
public JSONArray request(String url, String method, String json) throws RESTException {
if (method.matches("GET")) {
return get(url);
} else if (method.matches("POST")) {
return post(url, json);
} else if (method.matches("PUT")) {
//return put(url, data);
} else if (method.matches("DELETE")) {
//return delete(url);
}
throw new RESTException("Error! Incorrect method provided: " + method);
}
public JSONArray get(String url) throws RESTException {
String jsonjr = "['Chanuthi','Damsith','Dunili','Isath','Minuka','Uvin','Vidath']";
JSONArray jsonAraay = null;
try {
jsonAraay = new JSONArray(jsonjr);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonAraay;
}
}
The exception I got is e=null. All the other things work properly. When I am hard coding the result inside in the doInBackGround it works properly. Also the rest client get method returns the exact thing.
It appears you're using AsyncTask improperly. Firstly, you must subclass/nest your AsyncTask as per the Android documentation:
http://developer.android.com/reference/android/os/AsyncTask.html
In addition, you should follow the fundamental rules for calling methods of an outter class from a nested class.
There are some alternatives, like:
Create the AndrestClient object in onPreExecute() of the AsyncTask
Pass the AndrestClient object to the doInBackground as a parameter, then call its methods by doing something like this in the outter class:
doRequest.execute(rest);
I am trying to write a Http API in android. I am using a AsyncTask to run the calls to my web service.I am not interested in updating the UI, instead all I want is the data to use in my application logic. This is what I have so far:
public class DataManager{
public static String result;
public DataManager ()
{
}
public String get ()
{
User user = new User ();
user.execute("http://someuri/service/users/id/21001");
return user.getResult();
}
}
public class User extends AsyncTask <String,Void,String>{
private String result;
#Override
protected String doInBackground(String... arg0)
{
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet (arg0[0]);
try
{
HttpResponse response = client.execute (get);
if (response.getStatusLine().getStatusCode () == 200)
{
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity);
}
}
catch (ClientProtocolException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
this.result = result;
}
public String getResult ()
{
return result;
}
}
I want a typical call to be:
DataManager manager = new DataManager ();
String value = manager.get ();
But when I run this I get back null. What is causing this and how can I refactor this code to get the desired behavior.
The whole idea of a thread is that it runs concurrently. Basically, here's what you're doing:
User user = new User (); // Create User object
user.execute("http://someuri/service/users/id/21001"); // Start thread
return user.getResult(); // Return thread result
However, there is no time for the thread to run between "start" and "return result".
I would suggest using some kind of callback; first, make get() return void, and remove the return statement. Then, you pass in some object which implements YourCallback, and then call onCallback(result) from within onPostExecute().
Your calling code would then look like this:
DataManager x = new DataManager();
x.get(new YourCallback() {
public void onCallback(String result) {
// ...
}
});
There is a much fuller example in this fantastic answer.