I have a list of screen names on Twitter and I wish to get meta data about their twitter profile. I am using Twitter's REST API for the same. The users/show method is apt for my task. The API documentation clearly states that it requires no authentication. Here's the code I wrote for my task:
package Twitter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class TwitterAPI {
private static String url = "http://api.twitter.com/1/users/show/";
/*
* Sends a HTTP GET request to a URL
* #return - The response from the end point
*/
public static String sendGetRequest(String endpoint, String screen_name) {
String result = null;
if (endpoint.startsWith("http://")){
//Send HTTP request to the servlet
try {
//Construct data
StringBuffer data = new StringBuffer();
//Send data
String urlStr = endpoint ;
if(screen_name!=null && screen_name.length() > 0){
urlStr += screen_name + ".json";
}
System.out.println(screen_name.length());
System.out.println("The URL call is: " + urlStr);
URL url = new URL(urlStr);
URLConnection conn = url.openConnection ();
//Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while((line = rd.readLine())!=null){
sb.append(line);
}
rd.close();
result = sb.toString();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
//If API issue, collect screen names to write to API issue file
System.out.println("Twitter API issue :" + screen_name);
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return result;
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String result = sendGetRequest(url, "denzil_correa");
System.out.println(result);
}
}
However, on running the same I receive the following exception :
13
The URL call is: http://api.twitter.com/1/users/show/denzil_correa.json
Twitter API issue :denzil_correa
java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:365)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:227)
null
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:214)
at java.net.Socket.connect(Socket.java:531)
at java.net.Socket.connect(Socket.java:481)
at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:233)
at sun.net.www.http.HttpClient.New(HttpClient.java:306)
at sun.net.www.http.HttpClient.New(HttpClient.java:323)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:783)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:724)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:649)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:972)
at Twitter.TwitterAPI.sendGetRequest(TwitterAPI.java:43)
at Twitter.TwitterAPI.main(TwitterAPI.java:76)
The URL is correct as when I try the URL : http://api.twitter.com/1/users/show/denzil_correa.json in my browser I receive the following:
{"time_zone":"Mumbai","description":"","lang":"en","profile_link_color":"1F98C7","status":{"coordinates":null,"contributors":null,"in_reply_to_screen_name":"shailaja","truncated":false,"in_reply_to_user_id":14089830,"in_reply_to_status_id":16789217674,"source":"web","created_at":"Tue Jun 22 19:43:46 +0000 2010","place":null,"geo":null,"favorited":false,"id":16793898396,"text":"#shailaja Harsh !"},"profile_background_image_url":"http://s.twimg.com/a/1276711174/images/themes/theme2/bg.gif","profile_sidebar_fill_color":"DAECF4","following":false,"profile_background_tile":false,"created_at":"Sun Jun 29 20:23:29 +0000 2008","statuses_count":1157,"profile_sidebar_border_color":"C6E2EE","profile_use_background_image":true,"followers_count":169,"contributors_enabled":false,"notifications":false,"friends_count":246,"protected":false,"url":"http://https://sites.google.com/a/iiitd.ac.in/denzilc/","profile_image_url":"http://a3.twimg.com/profile_images/643636081/Cofee_Mug_normal.jpg","geo_enabled":true,"profile_background_color":"C6E2EE","name":"Denzil Correa","favourites_count":3,"location":"India","screen_name":"denzil_correa","id":15273105,"verified":false,"utc_offset":19800,"profile_text_color":"663B12"}
which is in the JSON format I want.
Kindly let me know if I am doing anything stupid here.
Regards,
--Denzil
Hank/Splix as told I tried using the HTTP Components Client. Here's my modified code :
package Twitter;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class TwitterAPI {
private static String url = "http://api.twitter.com/1/users/show/denzil_correa.json";
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
try {
HttpResponse response = httpclient.execute(httpget);
System.out.println(response.toString());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Here's the error I receive:
org.apache.http.conn.HttpHostConnectException: Connection to http://api.twitter.com refused
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:127)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at Twitter.TwitterAPI.main(TwitterAPI.java:30)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:365)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:227)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:214)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:378)
at java.net.Socket.connect(Socket.java:531)
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:123)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:123)
... 7 more
Surprisingly this also gives a similar exception to the code written for handling HTTP responses manually. I understand that manually handling HTTP responses may be sub-optimal but currently I am not looking at writing optimal code. I would like to get my task done even if it means to be quick & dirty.
Just to let you know, I can successfully call the Facebook Graph API using the first code I posted. I am receiving the same response I would receive if I paste the URL in my browser.
I will also try using the Twitter4J API once again and check if I can get my task done. Will keep you updated.
So, here's the code using Twitter4J :
package Twitter;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
public class TwitterAPI {
/**
* #param args
*/
public static void main(String[] args) {
Twitter unauthenticatedTwitter = new TwitterFactory().getInstance();
try {
User user = unauthenticatedTwitter.showUser("denzil_correa");
System.out.println(user.getLocation());
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Pretty straightforward as expected using the API. However, here's the error I receive:
Jun 23, 2010 7:12:10 PM twitter4j.internal.logging.CommonsLoggingLogger info
INFO: Using class twitter4j.internal.logging.CommonsLoggingLoggerFactory as logging factory.
Jun 23, 2010 7:12:11 PM twitter4j.internal.logging.CommonsLoggingLogger info
INFO: Use twitter4j.internal.http.HttpClientImpl as HttpClient implementation.
TwitterException{statusCode=-1, retryAfter=0, rateLimitStatus=null}
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:316)
at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:68)
at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:90)
at twitter4j.Twitter.showUser(Twitter.java:538)
at Twitter.TwitterAPI.main(TwitterAPI.java:17)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:365)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:227)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:214)
at java.net.Socket.connect(Socket.java:531)
at sun.net.NetworkClient.doConnect(NetworkClient.java:152)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:394)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:529)
at com.ibm.net.ssl.www2.protocol.https.c.(c.java:166)
at com.ibm.net.ssl.www2.protocol.https.c.a(c.java:9)
at com.ibm.net.ssl.www2.protocol.https.d.getNewHttpClient(d.java:55)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:724)
at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:20)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:972)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:385)
at com.ibm.net.ssl.www2.protocol.https.b.getResponseCode(b.java:52)
at twitter4j.internal.http.HttpResponseImpl.(HttpResponseImpl.java:42)
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:279)
... 4 more
Again, I see that the error is essentially the same. So, all options tried! I'm sure there's something I am missing here. It would be great if you could point out the same.
Hank, Unfortunately the same doesn't work in Python too :-(
Traceback (most recent call last):
File "", line 1, in
urllib.urlopen("http://api.twitter.com/1/users/show/denzil_correa.json").read()
File "C:\Python26\lib\urllib.py", line 86, in urlopen
return opener.open(url)
File "C:\Python26\lib\urllib.py", line 205, in open
return getattr(self, name)(url)
File "C:\Python26\lib\urllib.py", line 347, in open_http
errcode, errmsg, headers = h.getreply()
File "C:\Python26\lib\httplib.py", line 1060, in getreply
response = self._conn.getresponse()
File "C:\Python26\lib\httplib.py", line 986, in getresponse
response.begin()
File "C:\Python26\lib\httplib.py", line 391, in begin
version, status, reason = self._read_status()
File "C:\Python26\lib\httplib.py", line 349, in _read_status
line = self.fp.readline()
File "C:\Python26\lib\socket.py", line 397, in readline
data = recv(1)
IOError: [Errno socket error] [Errno 10054] An existing connection was forcibly closed by the remote host
As #splix mentioned in the comments, doing this using just java.net is… suboptimal. I've never yet encountered a situation where HttpClient wasn't a better option. Event better is his suggestion of twitter4j; unless you're trying to create an alternative, it's almost always better to use an API wrapper like that vs. handling the raw HTTP interactions yourself.
UPDATE:
#Denzil it's odd that you're getting this same error even with twitter4j (I can't test the code until I get some free time to grab the lib, etc.) so I begin to suspect a problem on Twitter's end. If you have Python installed, try the following:
>>> import urllib
>>> urllib.urlopen("http://api.twitter.com/1/users/show/denzil_correa.json").read()
This worked for me.
UPDATE 2:
This definitely sounds like Twitter is intentionally refusing your requests. Possible reasons could include: your IP is on their blacklist for some reason, proxy voodoo, or things I haven't thought of. To elaborate on the proxy voodoo: I don't know what exactly it's doing to your requests, but it's possible it's adding a header or something that the Twitter API doesn't like. I'd recommend contacting Twitter support (if there is such a thing for API problems) or posting to the mailing list.
BTW, here's a thread from the mailing list that mentions ways to see if you're blacklisted.
Related
i have an api which receives data from a source and send them to telegram bot.
i receive data in bulk from my source and will send them to telegram bot with that rate but telegram can handle only 1 message per sec so eventually it returning this exception
java.io.IOException: Server returned HTTP response code: 429 for URL:....
is there a way to store messages in list and iterate this list from a thread
am trying to learn java so please don't mind if my code not good.
Sample.java
class Sample{
run(){
while(true){
//some operations
SendMessage.getInstance().sendToTelegram(clientCommand);
//
}
}
}
SendMessage.java
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class SendMessage {
static SendMessage getInstance() {
return instance;
}
public void sendToTelegram(String message) {
String urlString = "https://api.telegram.org/;
String apiToken = obj.getInstance().getTelegramToken();
String chatId = obj.getInstance().getChatId();
String text = message;
urlString = urlString+"/bot"+apiToken+"/sendMessage?parse_mode=HTML&chat_id="+chatId+"&text="+msgToSend;
try {
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
InputStream is = new BufferedInputStream(conn.getInputStream());
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String inputLine = "";
StringBuilder sb = new StringBuilder();
while ((inputLine = br.readLine()) != null) {
sb.append(inputLine);
sb.append('\r');
}
br.close();
} catch (IOException e) {
log.error(e);
}
}
}
if thread concept works can anyone please help me how to add into a list and send them to telegram bot without loosing data
by using sleeping thread am not getting 429 too many responses exception
class Sample{
run(){
while(true){
//some operations
SendMessage.getInstance().sendToTelegram(clientCommand);
Thread.sleep(2000);
}
}
}
but getting new exceptions bad request
java.io.IOException: Server returned HTTP response code: 400 for URL
and this is the demo telegram url
https://api.telegram.org/botid:TELEGRAM_TOKEN/sendMessage?parse_mode=HTML&chat_id=CHAT_ID&text=<b>Alert</b>%0A<b>Alert Name:</b> "REGISTER Violation"%0A<b>Severity:</b> "Medium"%0A<b>TimeStamp:</b> "2022-05-10 22:17:34.31"%0A<b>Event ID:</b> "160"%0A<b>Event Message:</b> "An unregistered User has been detected. This can be a Caller-ID poisoning or Number Harvesting attack. Only a valid registered user can make or receive calls"%0A<b>Source Contact:</b> "192.168.3.31:5077"%0A<b>Destination Contact:</b> "192.168.10.10:5555"%0A<b>Source IP:</b> "192.168.3.31"%0A<b>Destination IP:</b> "192.168.10.10"%0A<b>Source Ext:</b> "4545454545"%0A<b>Destination Ext:</b> "%2B43965272"%0A<b>Source Domain:</b> "n/a"%0A<b>Destination Domain:</b> "n/a"%0A<b>Protocol:</b> "SIP"%0A<b>Comment:</b> "None"%0A<b>Attack Name:</b> "REGISTER Violation"%0A<b>Method:</b> "INVITE"%0A<b>Source Country:</b> "Unknown"%0A<b>Destination Country:</b> "AUSTRIA"%0A<b>CallType:</b> "International"%0A<b>RiskScore:</b> "0"%0A<b>Client Name:</b> "Unknown:Unknown"%0A<b>Network Group Name:</b> "defaultNonVlanGroup"%0A<b>Acknowledged:</b> "No"%0A<b>Alert Category:</b> "External"%0A<b>UCTM Name:</b> "redshift"
and i tried manually by pasting url which shown in exception but its worked fine but in application its throwing this exception
Please help where i am doing wrong
You could just do a simple Thread.sleep(2000) in your loop. Might not scale too good
Or you could store all your messages in a synchronzied list (https://www.techiedelight.com/queue-implementation-in-java/) and make a scheduler that would read a message every x seconds, send it and delete it from the list. If your using Spring Boot this is pretty easy -> https://www.baeldung.com/spring-task-scheduler
I am trying to deploy my Jersey project on openshift. I have implemented this apple class to test the error in the another class since I guess the problem is with the establishing the database connection. in the Tails log I found this error:
Connecting to database…
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Cannot load connection class because of underlying exception: 'java.lang.NumberFormatException: For input string: "OPENSHIFT_MYSQL_DB_PORT"'.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
package org.busTracker.serverSide;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
* Root resource (exposed at "myresource" path)
*/
#Path("myresource")
public class Apple {
//I modified my credients.
String host = "jdbc:mysql://$OPENSHIFT_MYSQL_DB_HOST:OPENSHIFT_MYSQL_DB_PORT/serverside";
String user = "adminBjv5a4k";
String password = "7tvPb1Bx3v8j";
/**
* Method handling HTTP GET requests. The returned object will be sent
* to the client as "text/plain" media type.
*
* #return String that will be returned as a text/plain response.
*/
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getIt() {
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting to database…");
conn = DriverManager.getConnection(host,user,password);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// ignore
}
}
}
return "Hello, from apple class 14.05.15 11:35!";
}
}
Edit: I added the following to the try block after DriverManager.getConnection():
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.format("%s=%s%n",
envName,
env.get(envName));
}
I have tried the following but I am still getting the same error:
This solution: https://forums.openshift.com/mysql-51-jboss-app-numberformatexception-mysql-url And add the following jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/serverside but nothing changed.
"jdbc:mysql://127.10.310.130:3306 /serverside"; This values are from the phpmyadmin of the app.
the problem is because of this line
String host = "jdbc:mysql://$OPENSHIFT_MYSQL_DB_HOST:OPENSHIFT_MYSQL_DB_PORT/serverside";
to get the environment variable, you need to use the method System.getEnv().get("[the variable name]"). So, in your case, the host variable should looks like this
String host = "jdbc:mysql://"
+ System.getenv().get("OPENSHIFT_MYSQL_DB_HOST")
+ ":"
+ System.getenv().get("OPENSHIFT_MYSQL_DB_PORT")
+ "/serverside";
by the way, your edit does not work because the application already throws an exception before it execute the code. so, to make it work, you need to put it before the DriverManager.getConnection() function.
You could replace those variables as below .
<property name="url"
value="jdbc:mysql://$OPENSHIFT_MYSQL_DB_HOST:$OPENSHIFT_MYSQL_DB_PORT/
yourdatabasename" />
can be replaced as below.
<property name="url"
value="jdbc:mysql://127.12.97.2:3306/yourdatabasename"
/>
jdbc:mysql://127.12.97.2:3306/yourdatabasename"The IP address and the portnumber can be obtained from the openshift phpmyadmin page and they are usually displayed on top of the admin page.
I tried all the above solutions but it didn't solve my problem. So anyone still getting that exception, try this.
The value stored in environment variable $OPENSHIFT_MYSQL_DB_HOST is something like
'jdbc:mysql://adminuname:adminpass#127.02.0.1:3306/appname'
. Therefore, using that value to create the url for DriverManager.getConnection() gives us the exception.
Instead try to know the value stored in $OPENSHIFT_MYSQL_DB_HOST and then hard code the url into a String variable without that username and password. Something like this
'jdbc:mysql://127.02.0.1:3306/appname'
For me it started working after making this modification. All other environment variables can be used as it is.
I found this solution here.
This code creates a new connection to the RESTful server for each request rather than just use the existing connection. How do I change the code, so that there is only one connection?
The line "response = oClientCloseable.execute(...)" not only does the task, but creates a connection.
I checked the server daemon log and the only activity generates from the .execute() method.
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
...
String pathPost = "http://someurl";
String pathDelete = "http://someurl2";
String xmlPost = "myxml";
HttpResponse response = null;
BufferedReader rd = null;
String line = null;
CloseableHttpClient oClientCloseable = HttpClientBuilder.create().setDefaultRequestConfig(defaultRequestConfig).build();
for (int iLoop = 0; iLoop < 25; iLoop++)
{
HttpPost hPost = new HttpPost(pathPost);
hPost.setHeader("Content-Type", "application/xml");
StringEntity se = new StringEntity(xmlPost);
hPost.setEntity(se);
line = "";
try
{
response = oClientCloseable.execute(hPost);
rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((line = rd.readLine()) != null)
{
System.out.println(line);
}
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (ConnectionPoolTimeoutException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
HttpClientUtils.closeQuietly(response);
}
HttpDelete hDelete = new HttpDelete(pathDelete);
hDelete.setHeader("Content-Type", "application/xml");
try
{
response = oClientCloseable.execute(hDelete);
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
HttpClientUtils.closeQuietly(response);
}
}
oClientCloseable.close();
The server daemon log emits the following for whatever it is worth, when connecting.
HTTP connection from [192.168.20.86]...ALLOWED
POST [/linx] SIZE 248
LINK-18446744073709551615: 2 SEND-BMQs, 2 RECV-BMQs
THREAD-LINK_CONNECT-000, TID: 7F0F1B7FE700 READY
NODE connecting to [192.168.30.20]:9099...
LINK-0-CONTROL-NODE-0 connected to 192.168.30.20(192.168.30.20 IPv4 address: 192.168.30.20):9099
Auth accepted, protocol compatible
NODE connecting to [192.168.30.20]:9099...
This article seems the most relevant, as it talks about consuming (closing) connections, which ties in the response. That article is also out of date, as consumeContent is deprecated. It seems that response.close() is the proper way, but that closes the connection and a new response creates a new connection.
It seems that I need to somehow create one response to the serer daemon and then change action (get, post, put, or delete).
Thoughts on how the code should change?
Here are some other links that I used:
link 1
link 2
link 3
I implemented the suggestion of Robert Rowntree (sorry not sure to properly reference name) by replacing the beginning code with:
// Increase max total connection to 200 and increase default max connection per route to 20.
// Configure total max or per route limits for persistent connections
// that can be kept in the pool or leased by the connection manager.
PoolingHttpClientConnectionManager oConnectionMgr = new PoolingHttpClientConnectionManager();
oConnectionMgr.setMaxTotal(200);
oConnectionMgr.setDefaultMaxPerRoute(20);
oConnectionMgr.setMaxPerRoute(new HttpRoute(new HttpHost("192.168.20.120", 8080)), 20);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setStaleConnectionCheckEnabled(true)
.build();
//HttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(defaultRequestConfig).build();
CloseableHttpClient oClientCloseable = HttpClientBuilder.create()
.setConnectionManager(oConnectionMgr)
.setDefaultRequestConfig(defaultRequestConfig)
.build();
I still saw the bunch of authenticates.
I contacted the vendor and shared with them the log using the modified version and my code was clean.
My test sample created a connection (to a remote server) followed by deleting the connection and repeating however many times. Their code dumps the authenticate message each time a connection creation request arrives.
I was pointed to what technically I already knew that the line that creates a new RESTful connection to the service is always "XXXXX connection allowed". There was one of those, two if you count my going to the browser based interface afterwards to make sure that all my links were gone.
Sadly, I am not sure that I can use the Apache client, so sad. Apache does not support message bodies inside a GET request. To the simple minded here (me, in this case), Apache does not allow:
GET http://www.example.com/whatevermethod:myport?arg1=data1&arg2=data2
Apache HttpClient --> HttpGet does not have a setEntities command. Research showed that as a POST request, but the service is the way that it is and will not change, so...
You can definitely use query parameters in Apache HttpClient:
URIBuilder builder = new URIBuilder("http://www.example.com/whatevermehtod");
builder.addParameter("arg1", "data1");
URI uri = builder.build();
HttpGet get = new HttpGet(uri);
I'm following this tutorial to establish a WebSocket connection to a server:
http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html
The code (same as the tutorial):
import java.net.URI;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
/**
* Example of a simple Echo Client.
*/
public class SimpleEchoClient {
public static void main(String[] args) {
String destUri = "ws://echo.websocket.org";
if (args.length > 0) {
destUri = args[0];
}
WebSocketClient client = new WebSocketClient();
SimpleEchoClient socket = new SimpleEchoClient();
try {
client.start();
URI echoUri = new URI(destUri);
ClientUpgradeRequest request = new ClientUpgradeRequest();
client.connect(socket, echoUri, request);
System.out.printf("Connecting to : %s%n", echoUri);
// socket.awaitClose(5, TimeUnit.SECONDS);
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
client.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Errors:
2014-08-07 21:49:00.346:INFO::main: Logging initialized #86ms
org.eclipse.jetty.websocket.api.InvalidWebSocketException:
SimpleEchoClient is not a valid WebSocket object.
Object must obey one of the following rules:
(1) class implements org.eclipse.jetty.websocket.api.WebSocketListener or
(2) class is annotated with #org.eclipse.jetty.websocket.api.annotations.WebSocket
at org.eclipse.jetty.websocket.common.events.EventDriverFactory.wrap(EventDriverFactory.java:145)
at org.eclipse.jetty.websocket.client.WebSocketClient.connect(WebSocketClient.java:200)
at org.eclipse.jetty.websocket.client.WebSocketClient.connect(WebSocketClient.java:144)
at SimpleEchoClient.main(SimpleEchoClient.java:31)
I'm not too sure what is wrong with my imported jar file. Maybe it is the wrong one? I'm using this: http://mvnrepository.com/artifact/org.eclipse.jetty.websocket/websocket-client/9.2.2.v20140723
Surely there must be an easier way to establish a connection via Jetty Websocket and start receiving data?
As Kayman explained in the comment, your problem with the socket handler implementation, use the latest release here explained with an example(same you used but correct) http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html
It looks like the documentation is out-of-date with the current version you are using. Try rolling back to a more stable version of 9.2.x like:
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-client</artifactId>
<version>9.2.0.RC0</version>
</dependency>
i am trying to code a small XMPP gtalk client in java. I know there is a lot of libraries that help you that but the RFC is so easy to understand that i decide to write a client by myself.
I know that the gtalk server is talk.google.com:5222 but when i try this small program i get this result :
HTTP/1.1 302 Found
Location: http://www.google.com/talk/
Content-Type: text/html
Content-Length: 151
<HTML><HEAD><TITLE>302 Moved</TITLE></HEAD><BODY><H1>302 Moved</H1>The document has moved here.</BODY></HTML>
I also tried to connect the location specified but it doesn't work. Here is my code in java :
package fr.grosdim.myjabber;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSocketFactory;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) {
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory
.getDefault();
try {
Socket s = new Socket("talk.google.com", 5222);
PrintWriter out = new PrintWriter(s.getOutputStream());
out.println("<?xml version=\\'1.0\\' encoding=\\'utf-8\\' ?>");
out
.println("<stream:stream to='talk.google.com:5222' "
+ "xmlns='jabber:client'"
+ " xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>");
out.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(s
.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
out.println("</stream>");
s.close();
} catch (SSLPeerUnverifiedException e) {
System.out.println(" Erreur d'auth :" + e.getLocalizedMessage());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
How can i connect to the gtalk server?
XMPP isn't a trivial protocol to implement, and I don't think you'll get very far by sending hand-crafted XML strings to the server.
I'd recommend studying some existing source code.
Spark and OpenFire are one example of a nice open source XMPP client and server implementation in java.
You might try getting OpenFire running locally in a debugger (or with verbose logging turned on) so you can get an idea of what it's doing with your packets.
Although not directly related, you may need a server to test against and one for which you can see the source. I suggest that you look at what the Vysper guys are doing http://mina.apache.org/vysper/
You have several problems with your code, not counting the stylistic one of not using a DOM before sending (which is a best practice in the XMPP world).
You need to connect to "talk.l.google.com". See the results of "dig +short _xmpp-client._tcp.gmail.com SRV" on the command line to find out what servers to connect to.
In your XML prolog, you're double escaping the single quotes, which will actually send a backslash.
The to attribute in your stream:stream should be "gmail.com", without the port number.
All of that being said, I'll second the other posters with a plea for you to not start another Java client library, but to pitch in on an existing one.
Why are you writing an XML version before writing the stream stanza? The server is expecting a stream of defined format, and not an XML structure. Remove this line
"out.println("< ? xml version=\\'1.0\\' encoding=\\'utf-8\\' ?>")"
then it will work for sure.