Execution stops automatically at getOutputStream() function Push notification using servlets - java

I have a problem while getting a push notification on the server side. I am using C2DM sever connection to achieve the push notification. Its working fine on android but not in the Java Servecr. I'm able to get the registration ID and authentication code but the handling stops when it comes to the line:
OutputStream out = conn.getOutputStream();
It does not throw anything, just stops.
If anyone has a solution for this then please guide me. I am adding the whole code so you can go through and tell me where I'm wrong in getting the result.
import org.apache.http.client.methods.HttpPost;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import javax.print.DocFlavor.INPUT_STREAM;
import org.apache.http.HttpClientConnection;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.DefaultHttpClientConnection;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
public class Server {
private static String key=null;
// private final static String AUTH = "authentication";
private static final String UPDATE_CLIENT_AUTH = "Update-Client-Auth";
public static final String PARAM_REGISTRATION_ID = "registration_id";
public static final String PARAM_DELAY_WHILE_IDLE = "delay_while_idle";
public static final String PARAM_COLLAPSE_KEY = "collapse_key";
private static final String UTF8 = "UTF-8";
private static String Authcode = null;
// Registration is currently hardcoded
private final static String YOUR_REGISTRATION_STRING = "reg id";
public void getAuthentification() {
System.out.println("check");
//HttpPost post = new HttpPost("http://www.google.com/accounts/ClientLogin");
try {
System.getProperties().put("proxySet", true);
System.getProperties().put("proxyHost","proxy" );
System.getProperties().put("proxyPort","8080");
System.out.println("getAuthentication method called****************************");
URL url=new URL("https://www.google.com/accounts/ClientLogin");
URLConnection connection=url.openConnection();
connection.setDoOutput(true);
HttpURLConnection conn=(HttpURLConnection)connection;
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(true);
StringBuilder content = new StringBuilder();
content.append("Email=").append("xyz#gmail.com");
content.append("&Passwd=").append("asdfgt");
content.append("&service=").append("ac2dm");
content.append("&source=").append("MY_APP-V0.1");
content.append("&accountType=").append("HOSTED_OR_GOOGLE");
OutputStream out = conn.getOutputStream();
out.write(content.toString().getBytes("UTF-8"));
out.close();
int res = conn.getResponseCode();
System.out.println(res + "Success");
StringBuffer resp = new StringBuffer();
if(res == HttpsURLConnection.HTTP_OK){
InputStream in = conn.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = rd.readLine()) != null) {
System.out.println(line);
System.out.println("inside");
if (line.startsWith("Auth=")) {
Authcode = line.substring(5);
resp.append(line.substring(5));
System.out.println(line.substring(5));
System.out.println("something to be done here..");
}
}
rd.close();
}
}
}
public void sendMessage() {
try {
System.out.println(YOUR_REGISTRATION_STRING);
System.out.println("Authcode = " + Authcode);
System.getProperties().put("proxySet", true);
System.getProperties().put("proxyHost","proxy" );
System.getProperties().put("proxyPort","8080");
URL url1 = new URL("https://android.apis.google.com/c2dm/send");
System.out.println("here2.5");
HttpURLConnection conn1 = (HttpURLConnection) url1.openConnection();
System.out.println("here2.6");
conn1.setDoInput(true);
conn1.setDoOutput(true);
conn1.setUseCaches(false);
conn1.setRequestMethod("POST");
conn1.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
conn1.setRequestProperty("Authorization", "GoogleLoginauth="+ Authcode);
System.out.println("here2.7");
OutputStream out = conn1.getOutputStream();
System.out.println("send Message method.");
String auth_key="n/a";
if(key!=null) {
auth_key=Authcode;
}
System.out.println("here");
// Send a sync message to this Android device.
StringBuilder postDataBuilder = new StringBuilder();
postDataBuilder.append(PARAM_REGISTRATION_ID)
.append("=").append(YOUR_REGISTRATION_STRING);
System.out.println("here1");
postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY)
.append("=").append("0");
System.out.println("here2");
postDataBuilder.append("&").append("data.payload")
.append("=").append(URLEncoder.encode("Lars war hier", UTF8));
byte[] postData = postDataBuilder.toString().getBytes(UTF8);
conn1.setRequestProperty("Content-Length",
Integer.toString(postData.length));
// Hit the dm URL.
System.out.println("out created");
out.write(postData);
System.out.println("data written");
out.close();
System.out.println("here3");
int responseCode = conn1.getResponseCode();
System.out.println(String.valueOf(responseCode));
// Validate the response code
if (responseCode == 401 || responseCode == 403) {
// The token is too old - return false to retry later, will
// fetch the token
// from DB. This happens if the password is changed or token
// expires. Either admin
// is updating the token, or Update-Client-Auth was received by
// another server,
// and next retry will get the good one from database.
System.out.println("C2DM, Unauthorized - need token");
}
} catch (Exception ignore) {
// the editor that corrected the indentation of the code could not find any code here so he closed all methods to have a syntactically correct class.
}
}
}

Make sure that you are posting message to url from background thread not from the UI thread.
I hope after this change it will work. Good Luck!!!

Related

Why am I not getting a MalformedURLException on incorrect URL's?

Here's my code, I'm wondering why I'm not getting a MalformedURLException on this, on wrong URL's it just prints Site is Down, when it should be Incorrect URL. Maybe I'm misunderstanding the exception, for example, I thought https://goofdggle.djaosi a malformed URL, but my thing is returning Site is Down when it should be Incorrect URL. This is a Spring Boot app by the way.
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class URLCheckController {
private String siteup = "Site is up!";
private String sitedown = "Site is down";
private String incorrectURL = "Incorrect URL!";
#GetMapping("/check")
public String getURLStatusMessage(#RequestParam String url) {
String returnMessage = "";
try {
URL urlObj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
conn.setRequestMethod("GET");
conn.connect();
int responseCategory = conn.getResponseCode() / 100;
if(responseCategory != 2 && responseCategory != 3) {
returnMessage = sitedown;
} else {
returnMessage = siteup;
}
} catch (MalformedURLException e) {
returnMessage = incorrectURL;
} catch (IOException e) {
returnMessage = sitedown;
}
return returnMessage;
}
}

Send automatic message on a given date

I have made a SMS application with Java that works like a charm. I want the application to send SMS on a given date. I am using the Quartz Job Scheduling for that. First I need these two applications to be connected to each other. Then I need Quartz to collect a date and time from a list (can be excel list) and send a message. Is this possible? Appreciate any help.
Here is the message application:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.codec.binary.Base64;
public class SMSApplication {
public static void main(String[] args) {
try {
String phoneNumber = "+XXXXXXXXX";
String appKey = "XXXXXXX";
String appSecret = "XXXXXXXX";
String message = "Hello world!";
URL url = new URL("https://messagingapi.sinch.com/v1/sms/" + phoneNumber);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
String userCredentials = "application\\" + appKey + ":" + appSecret;
byte[] encoded = Base64.encodeBase64(userCredentials.getBytes());
String basicAuth = "Basic " + new String(encoded);
connection.setRequestProperty("Authorization", basicAuth);
String postData = "{\"Message\":\"" + message + "\"}";
OutputStream os = connection.getOutputStream();
os.write(postData.getBytes());
StringBuilder response = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ( (line = br.readLine()) != null)
response.append(line);
br.close();
os.close();
System.out.println(response.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is the Quartz job class:
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class QuartzJob implements Job{
#Override
public void execute(JobExecutionContext jec) throws JobExecutionException {
System.out.println("Hello");
System.out.println(new Date())
}
}
And here is the Quartz main class:
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.ScheduleBuilder;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
public class QuartzMain {
public static void main(String[] args) throws SchedulerException {
JobDetail job = JobBuilder.newJob(QuartzJob.class).build();
Trigger tl = TriggerBuilder.newTrigger().withIdentity("SimpleTrigger").startNow().build();
Scheduler sc = StdSchedulerFactory.getDefaultScheduler();
sc.start();
sc.scheduleJob(job, tl);
}}
To start at a given date:
In the trigger replace .startNow() with .startAt(date) with date being a java.util.Date that represents the date and time it should start.
To connect:
In your Quartz job class call your sendSMS() method (currently your main method in SMSApplication) any variables (such as the phone number) should be passed to the job class in the job builer with .usingJobData("key","value"). See http://www.quartz-scheduler.org/documentation/quartz-2.3.0/ and read through the Tutorials and Cookbook for more information.

Read HTTP POST from mobile in java

I have iOS Swift code, which sends a POST request to server. If i send this code directly to apple server i get response back with proper data. But when i send this to my server, server could not get the body of the HTTP POST.
I have no idea whether this issue is related to client side or server side.
Here is the Swift code.
func validateReceipt(completion : (status : Bool) -> ()) {
let receiptUrl = NSBundle.mainBundle().appStoreReceiptURL!
if NSFileManager.defaultManager().fileExistsAtPath(receiptUrl.path!)
{
if let receipt : NSData = NSData(contentsOfURL: receiptUrl)
{
let receiptdata: NSString = receipt.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.EncodingEndLineWithLineFeed)
let dict = ["receipt-data" : receiptdata]
let jsonData = try! NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions(rawValue: 0))
let request = NSMutableURLRequest(URL: NSURL(string: ReceiptURL.MAIN_SERVER.rawValue)!)
let session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
request.HTTPBody = jsonData
let task = session.dataTaskWithRequest(request, completionHandler: { data, response, error in
if let dataR = data
{
self.handleData(dataR, completion: { status in
completion(status: status)
})
}
})
task.resume()
}
else
{
completion(status: false)
}
}
else
{
completion(status: false)
}
}
and here is my Java code in server side, there are two Java classes which take care of this
MyRequestWrapper.Java
package webservice;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MyRequestWrapper extends HttpServletRequestWrapper {
private final String body;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[100000];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
body = stringBuilder.toString();
}
#Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
#Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
And here is the another class.
GetResult.Java
package webservice;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.log4j.Logger;
import org.json.JSONException;
import org.json.JSONObject;
#Path("/service")
public class GetResult {
static Logger logger = Logger.getLogger(GetResult.class);
// #Produces("application/json; charset=UTF-8")
//#Produces("text/plain")
#POST
#Produces (MediaType.APPLICATION_JSON)
public Response inapp(#Context HttpServletRequest request,
#Context HttpServletResponse response) throws Exception {
System.out.println("response===" + response);
System.out.println("Request-Header===" + request.getHeader("receipt-data"));
System.out.println("Request===" + request.getParameter("receipt-data"));
// System.out.println("Request==="+request.getReader());
// reader(request,response);
// getBody(request);
doFilter(request,response);
String result = "";
result = " " /* jsonObject */;
return Response.status(200).entity(result).build();
}
We could get the client IP and client Port from this request but unable to get the body. In production also we could not get the body. Some Java developers told me that you cant directly get the raw bytes in Java, i don't know about this.
Somebody please take a look at this, and tell me what i am doing wrong.
You may have to explicitly set the content type of the input post body you send to the server. This can be achieved as follows:
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
Set the content type after setting the http method and son data to the request object( NSMutableURLRequest object)
This may help you!
Edited:
Actually the header field name is "Content-Type".

JSONException Twitter client side application

I am currently trying to build a client application for twitter. One of the functionalities of the app is to search tweet (including historical tweet). I tried to modify the code that I got from Github. However, when I tried to debug the code, I got JSONException cause by null value. Here is my code:
package thematicanalysis;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import twitter4j.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import twitter4j.JSONException;
/**
*
* #author adichris
*/
public class TweetManager {
private static String getURLResponse(String since, String until, String querySearch, String scrollCursor,int counter) throws Exception{
String appendQuery = " ";
if(since!=null)
appendQuery+= " since:"+since;
if(until!=null)
appendQuery+= " until:"+until;
if(querySearch!=null)
appendQuery+= " "+querySearch;
String url = String.format("https://twitter.com/search?src=typd&q=%s&scroll_cursor=%s", URLEncoder.encode(appendQuery, "UTF-8"),scrollCursor);
System.out.println("URL: "+ url);
URL obj = new URL (url);
HttpURLConnection con = (HttpURLConnection)obj.openConnection();
con.setRequestMethod("GET");
//StringBuilder response;
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while((inputLine=in.readLine())!=null)
response.append(inputLine);
in.close();
con.disconnect();
//System.out.println(response.toString());
saveToFile(response.toString(),counter);
return response.toString();
}
private static void saveToFile(String content,int counter) throws IOException
{
try (PrintWriter pw = new PrintWriter("newOutput"+counter+".txt","UTF-8")) {
pw.printf("%s\n",content);
pw.close();
}
}
public static void getTweets (String since, String until, String querySearch) throws JSONException, Exception{
try{
String refreshCursor = null;
int counter = 1;
while(true)
{
String response = getURLResponse(since,until,querySearch,refreshCursor,counter);
JSONObject json = new JSONObject(response);
if(json.equals(null))
System.out.println("hereeee");
counter++;
System.out.println(counter);
refreshCursor = json.getString("scroll_cursor");
Document doc = Jsoup.parse((String)json.get("items_html"));
Elements tweets = doc.select("div.js-stream-tweet");
System.out.println(tweets.size());
if (tweets.isEmpty()){
break;
}
for (Element tweet: tweets){
String userName = tweet.select("span.username.js-action-profile-name b").text();
String text = tweet.select("p.js-tweet-text").text().replaceAll("[^\\u0000-\\uFFFF]", "");
long dateMs = Long.valueOf(tweet.select("small.time span.js-short-timestamp").attr("data-time-ms"));
Date date = new Date(dateMs);
System.out.println(userName);
//saveToFile(text);
}
}
}catch(JSONException e){
e.printStackTrace();
}
}
}

Cannot Resolve Symbol 'execute', android studio 8.0 beta

I know many people have issues like mine, but the answers I found didn't seem to work.
import android.os.AsyncTask;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
/**
* Created by DJ on 6/29/2014.
*/
public class RetrieveTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... values){
String result;
try{
ArrayList<NameValuePair> nvp = new ArrayList<NameValuePair>();
HttpClient httpc = new DefaultHttpClient();
HttpPost httpp = new HttpPost("http://" + values[0] + "/AndroidConnection/Select.php");
httpp.setEntity(new UrlEncodedFormEntity(nvp));
HttpResponse httpr = new httpc.execute(httpp);
HttpEntity httpe = httpr.getEntity();
InputStream is = httpe.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while((line = br.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch(Exception e){
return e.getMessage();
}
return result;
}
}
`
As you can see in this code, I used the HttpClient.execute command, but Android studio refers to .execute command as an error: cannot resolve symbol 'execute'.
I have already tried Invalidating Cache and restart. I also turned on Maven's auto import check box.
OS: win7 32-bit
JDK: jdk7(Java EE)
Android Studio: 8.0 beta
Remove the new in this line:
HttpResponse httpr = new httpc.execute(httpp);
You do not have to create a new object. You will only call the method execute

Categories