When I make a call to the method CloseableHttpClient.execute it takes so much time to finish the first time I call it. For example, if I call an API call 10 times in a for bucle, the first call takes much more time than the rest of the call and I don't know the reason.
I would appreciate if someone can help.
Regards.
public static void main(String[] args) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, Exception
{
AcanoAPICallsTest2 test = new AcanoAPICallsTest2();
AcanoAPIHandler clientHandler = test.getClientHandler();
if (clientHandler.getConnectCode() == HttpStatus.SC_OK) {
int statusCode = clientHandler.executeMethod(CommonSettings.GET, "/api/xxx);
}
}
clientHandler.shutDownClient();
}
public class AcanoAPIHandler extends ClientHandler
{
protected Logger logger = Logger.getLogger(this.getClass());
private final String LOCATION = "Location";
private String location;
// private int connectCode = HttpStatus.SC_SERVICE_UNAVAILABLE;
/**
* Returns the "Location" field of the response header (if exists)
*
* #return
*/
public String getLocationHeaderResponse()
{
return location;
}
// default constructor
public AcanoAPIHandler()
{
super();
}
public AcanoAPIHandler(String protocol, String host, Integer port, String username, String password)
{
super(protocol, host, port, username, password);
}
#Override
public int executeMethod(String type, String path, List<BasicNameValuePair>... nvps)
{
int statusCode = super.executeMethod(type, path, nvps);
this.location = null;
if (type.equalsIgnoreCase(CommonSettings.POST) || type.equalsIgnoreCase(CommonSettings.PUT))
{
// if statusCode is 200, set the location header
if (statusCode == HttpStatus.SC_OK)
{
Header[] h = this.getResponse().getAllHeaders();
for (int i = 0; i < h.length; i++)
{
if (h[i].getName().equalsIgnoreCase(LOCATION))
{
String locationStr = h[i].getValue();
String[] split = locationStr.split("/");
if (split.length > 0)
{
this.location = split[split.length - 1];
break;
}
}
}
}
}
return statusCode;
}
}
ClientHandler.executeMethod
public int executeMethod(String type, String path, List<BasicNameValuePair>... nvps)
{
int statusCode = -1;
HttpUriRequest request = createUriRequest(type, path);
this.responseContent = null;
this.response = null;
try
{
if (nvps.length > 0)
{
if (type.equalsIgnoreCase(CommonSettings.POST))
{
((HttpPost) request).setEntity(new UrlEncodedFormEntity(nvps[0], "UTF-8"));
}
else if (type.equalsIgnoreCase(CommonSettings.PUT))
{
((HttpPut) request).setEntity(new UrlEncodedFormEntity(nvps[0], "UTF-8"));
}
else
{
logger.warn("Can only set entity on POST/PUT operation, ignoring nvps");
}
}
}
catch (UnsupportedEncodingException ex)
{
java.util.logging.Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
}
if (this.httpclient != null)
{
try
{
long start = System.currentTimeMillis();
this.response = this.httpclient.execute(request);
long end = System.currentTimeMillis();
long res = end - start;
System.out.println("httpclient.execute " + " seconds: "+res/1000);
statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
if (entity != null)
{
InputStream fis = entity.getContent();
this.responseContent = convertStreamToString(fis);
EntityUtils.consume(entity);
fis.close();
}
}
catch (IOException ex)
{
java.util.logging.Logger.getLogger(ClientHandler.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
return SERVER_ERROR;
}
finally
{
// release connection
if (type.equalsIgnoreCase(CommonSettings.GET))
{
((HttpGet) request).releaseConnection();
}
else if (type.equalsIgnoreCase(CommonSettings.POST))
{
((HttpPost) request).releaseConnection();
}
else if (type.equalsIgnoreCase(CommonSettings.PUT))
{
((HttpPut) request).releaseConnection();
}
else if (type.equalsIgnoreCase(CommonSettings.DELETE))
{
((HttpDelete) request).releaseConnection();
}
// close the response
try
{
if (this.response != null)
{
this.response.close();
}
}
catch (IOException ex)
{
java.util.logging.Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
return SERVER_ERROR;
}
}
}
return statusCode;
}
I don't see how this.httpclient is initialized in ClientHandler class, but usually this happens when you are executing request to a host which is far away from you and uses reusable http connections (this is why the first request is noticeably slower than others).
When you open TCP connection to a host, TCP three way handshake is made. This means that you have to wait before connection is established and only after that actual HTTP request is sent. Establishing connection from Europe to somewhere in North America would take ~90ms and more. Ping time from London to other cities
Using TCP connection multiple times is a good practice. Because after TCP connection is established and the first request is done you can send new requests without extra waiting time. You can read more about HTTP persistent connection
Seems that you are connecting to Acano servers, I don't know exactly where their Data Center(-s) is/are, cause they can have couple of them across the world, but the company is located in USA. So seems legit in case you are not very close to the Arcano's Data Center.
Related
I write my own Java FTP server. Until recently I used PUttY to debug my control telnet connection and everything seemed fine - I had successful two-way communication. Now I try to debug my server with FileZilla, but it does not seem to read my text, nor to send some to server, so it just hangs and wait for something.
Control connection class
public class ControlConnection extends Thread {
private enum OperationMode {
ACTIVE, PASSIVE
}
private final Map<String, Supplier<String>> COMMANDS;
private String[] userTokens;
private User user;
private String userLogin;
private boolean authenticated;
private boolean dataConnected;
private boolean userExists;
private final Socket socket;
private DataInputStream inputStream;
private DataOutputStream outputStream;
private DataConnection ftpSession;
private OperationMode operationMode;
private String errorMessage;
public ControlConnection(Socket socket) {
super(ControlConnection.class.toString());
this.socket = socket;
// constants initialization
authenticated = false;
dataConnected = false;
// commands initialization
COMMANDS = new HashMap<>();
// commands init
}
#Override
public void run() {
try {
inputStream = new DataInputStream(socket.getInputStream());
outputStream = new DataOutputStream(socket.getOutputStream());
sendGreetings();
IOProcessing.writeBytes(outputStream, pasvCommand());;
boolean running = true;
while (running) {
sendGreetings();
String input = IOProcessing.readBytes(inputStream);
if (!(input.equals("")))
System.out.println(input);
if (!checkInput(input))
continue;
userTokens = input.split(" ");
String command = userTokens[0].toUpperCase();
String answer = COMMANDS.get(command).get();
outputStream.writeBytes(answer);
}
}
catch (IOException e) {
System.err.println(e);
System.exit(-1);
}
}
private boolean commonCheck() {
// some checks
return true;
}
private String getErrorMessage() {
return errorMessage;
}
public void sendGreetings() {
String greetings = String.format("220 Control connection established: %s", getConnectionInfo());
IOProcessing.writeBytes(outputStream, greetings);
}
public String getConnectionInfo() {
String info = String.format("%s: %d %s",
socket.getInetAddress().toString(), socket.getPort(), user != null ? user.getUsername(): "");
return info;
}
// input/output proccessing functions
public boolean checkInput(String input) {
// checks
return true;
}
// commands functions
private String pasvCommand() {
if (operationMode == OperationMode.PASSIVE) {
errorMessage = "Already in passive mode.%n";
return errorMessage;
}
String answer;
new ListenToSocket().start();
answer = String.format("227 Entering Passive Mode (%s, %d)",
"127.0.0.1", DataConnection.PORT);
operationMode = OperationMode.PASSIVE;
return answer;
}
private class ListenToSocket extends Thread {
public ListenToSocket() {
}
#Override
public void run() {
try {
ServerSocket ftpSocket =
new ServerSocket(DataConnection.PORT);
ftpSession =
DataConnection.getDataConnection(ftpSocket.accept());
if (ftpSession != null) {
ftpSession.start();
dataConnected = true;
String greetings = "Data connection established: " + ftpSession.getConnectionInfo();
IOProcessing.writeBytes(outputStream, greetings);
} else {
dataConnected = false;
}
} catch (IOException e) {
System.out.print(e);
}
}
}
also, server does not get user credentials, entered in FileZilla - input from server is always empty
IOProcessing class
public class IOProcessing {
private static final Charset UTF8_CHARSET;
static {
UTF8_CHARSET = Charset.forName("UTF-8");
}
public static String readBytes(DataInputStream inputStream) {
String result = "";
try {
int len = inputStream.available();
if (len == 0) {
return result;
}
byte[] byteInput = new byte[len];
inputStream.readFully(byteInput, 0, len);
result = new String(byteInput, "UTF-8").trim();
} catch (IOException e) {
System.err.println(e);
}
return result;
}
output FileZlla log
Status: Resolving address of localhost
Status: Connecting to [::1]:21...
Status: Connection established, waiting for welcome message.
You didn't show us the writeBytes. So I can only guess that you are not sending \r\n after the messages sent to the client. Particularly after the welcome message. So FileZilla keeps waiting forever for it, as any FTP client would do.
I am writing a simple Java wrapper around ElasticSearch's admin client. To test it I have a main method that first checks if an index exists (IndicesExistsRequest), if so deletes it (DeleteIndexRequest), and creates the index again. See code below. Yet I consistently get an IndexAlreadyExistsException.
By the way I am trying to get a client for the node that you start from the command prompt (by simply typing "elastic search"). I have tried every combination of methods on nodeBuilder's fluent interface, but I can't seem to get one.
public static void main(String[] args) {
ElasticSearchJavaClient esjc = new ElasticSearchJavaClient("nda");
if (esjc.indexExists()) {
esjc.deleteIndex();
}
esjc.createIndex();
URL url = SchemaCreator.class.getResource("/elasticsearch/specimen.type.json");
String mappings = FileUtil.getContents(url);
esjc.createType("specimen", mappings);
}
final Client esClient;
final IndicesAdminClient adminClient;
final String indexName;
public ElasticSearchJavaClient(String indexName) {
this.indexName = indexName;
esClient = nodeBuilder().clusterName("elasticsearch").client(true).node().client();
adminClient = esClient.admin().indices();
}
public boolean deleteIndex() {
logger.info("Deleting index " + indexName);
DeleteIndexRequest request = new DeleteIndexRequest(indexName);
try {
DeleteIndexResponse response = adminClient.delete(request).actionGet();
if (!response.isAcknowledged()) {
throw new Exception("Failed to delete index " + indexName);
}
logger.info("Index deleted");
return true;
} catch (IndexMissingException e) {
logger.info("No such index: " + indexName);
return false;
}
}
public boolean indexExists() {
logger.info(String.format("Verifying existence of index \"%s\"", indexName));
IndicesExistsRequest request = new IndicesExistsRequest(indexName);
IndicesExistsResponse response = adminClient.exists(request).actionGet();
if (response.isExists()) {
logger.info("Index exists");
return true;
}
logger.info("No such index");
return false;
}
public void createIndex() {
logger.info("Creating index " + indexName);
CreateIndexRequest request = new CreateIndexRequest(indexName);
IndicesAdminClient iac = esClient.admin().indices();
CreateIndexResponse response = iac.create(request).actionGet();
if (!response.isAcknowledged()) {
throw new Exception("Failed to create index " + indexName);
}
logger.info("Index created");
}
You can also execute a synchronous request like this:
boolean exists = client.admin().indices()
.prepareExists(INDEX_NAME)
.execute().actionGet().isExists();
Here is my solution when using RestHighLevelClient client;
Here a code-snippet: :
public boolean checkIfIndexExists(String indexName) throws IOException {
Response response = client.getLowLevelClient().performRequest("HEAD", "/" + indexName);
int statusCode = response.getStatusLine().getStatusCode();
return (statusCode != 404);
}
A contribution for someone else !
The skgemini's answer is ok if you want to check if index is available by the actual index name or any of its aliases.
If you however want to check only by the index name, here is how.
public boolean checkIfIndexExists(String index) {
IndexMetaData indexMetaData = client.admin().cluster()
.state(Requests.clusterStateRequest())
.actionGet()
.getState()
.getMetaData()
.index(index);
return (indexMetaData != null);
}
OK, I figured out a solution. Since the java client's calls are done asynchronously you have to use the variant which takes an action listener. The solution still gets a bit contrived though:
// Inner class because it's just used to be thrown out of
// the action listener implementation to signal that the
// index exists
private class ExistsException extends RuntimeException {
}
public boolean exists() {
logger.info(String.format("Verifying existence of index \"%s\"", indexName));
IndicesExistsRequest request = new IndicesExistsRequest(indexName);
try {
adminClient.exists(request, new ActionListener<IndicesExistsResponse>() {
public void onResponse(IndicesExistsResponse response) {
if (response.isExists()) {
throw new ExistsException();
}
}
public void onFailure(Throwable e) {
ExceptionUtil.smash(e);
}
});
}
catch (ExistsException e) {
return true;
}
return false;
}
I had the same issue but i didn't like the solution which uses an ActionListener. ElasticSearch also offers a Future variant (at least at version 6.1.0).
Here a code-snippet:
public boolean doesIndexExists(String indexName, TransportClient client) {
IndicesExistsRequest request = new IndicesExistsRequest(indexName);
ActionFuture<IndicesExistsResponse> future = client.admin().indices().exists(request);
try {
IndicesExistsResponse response = future.get();
boolean result = response.isExists();
logger.info("Existence of index '" + indexName + "' result is " + result);
return result;
} catch (InterruptedException | ExecutionException e) {
logger.error("Exception at waiting for IndicesExistsResponse", e);
return false;//do some clever exception handling
}
}
May be this helps someone else too. Cheers!
This works on Elasticsearch 7.x:
public boolean indexExists(String indexName) throws IOException {
return client.indices().exists(new org.elasticsearch.client.indices.GetIndexRequest(indexName), RequestOptions.DEFAULT);
}
My program is laid out so that the main app can send commands to any node connected to it. When a node receives a request, it returns a response and continues to wait for more requests.
When the app is run the node successfully replies to one request, and when a second request is sent the node sees it as a null or does not see it at all. Why does this keep happening?
P.S. I want the connection to the node to stay open, so that it can receive more requests.
Request sending code:
public java.lang.String getTime(server.Node node){
protocol.Message ms = new protocol.Message("<time>","");
node.sendRequestToClient(ms);
node.dos.flush();
java.lang.System.out.println("Sent time request to " + node.ip);
java.lang.String time = null;
try {
time = node.dis.readLine();
} catch (java.io.IOException ex) {
System.out.println("Could not read response.");
}
protocol.Message response = protocol.Message.parseDataToMessage(time);
java.lang.String systime = response.getActionData();
return systime;
}
Response sending code:
public class Client {
public Client(NetworkConnection connection){
this.connectionToServer = connection;
try{
connectionToServer.connect();
responseOutStream = connectionToServer.getPrintWriter();
requestInStream = connectionToServer.getBufferedReader();
}catch(IOException ex){
System.out.println("Could not connect to server." + ex.getMessage() + ex.toString());
}
}
public void beginRequestListener(){
String request;
try {
while((request = requestInStream.readLine())!=""){
System.out.println("Recieved request: " + request + request.length());
Message response = Message.parseDataToMessage(request);
sendResponseToServer(response);
}
} catch (java.io.IOException ex) {
System.out.println("Could not read request stream.");
} catch(NullPointerException e){
e.printStackTrace();
e.getClass();
}
}
public void sendResponseToServer(Message ms){
protocol.Message response = MessageParser.compileResponse(ms);
java.lang.System.out.println("Response to send: "+response);
response.send(responseOutStream);
}
public BufferedReader requestInStream;
public PrintWriter responseOutStream;
public NetworkConnection connectionToServer;
}
MessageParser class:
public class MessageParser {
static public Message compileResponse(Message ms){
Message response = null;
switch(ms.getAction()){
case "<time>":
response = new Message("<time>", String.valueOf(System.currentTimeMillis()));
break;
case "<date>":
SimpleDateFormat sd = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
Date date = new Date();
sd.setTimeZone(TimeZone.getTimeZone("IST"));
response = new Message("<date>", date.toString());
break;
default:
break;
}
return response;
}
}
The stack trace and output:
Recieved request: <action><time><action><actionData><actionData>
Response to send: <action><time><action><actionData>1370380854566<actionData>
Recieved request:
java.lang.NullPointerException
at protocol.MessageParser.compileResponse(MessageParser.java:23)
at client.Client.sendResponseToServer(Client.java:67)
at client.Client.beginRequestListener(Client.java:52)
at client.ClientInterface.main(ClientInterface.java:107)
Message class:
public class Message {
public Message(String data){
}
public Message(String action, String actionData){
this.action = action;
this.actionData = actionData;
}
public void send(PrintWriter connection){
try{
connection.println(this.toString());
connection.flush();
//System.out.println(this.toString());
}catch(Exception ex){
System.out.println("Could not send Message.");
}
}
#java.lang.Override
public String toString(){
return
action_marker + action + action_marker +
actionData_marker + actionData + actionData_marker +
eof_marker;
}
public static Message parseDataToMessage(String data){
Message ms = null;
if(data.isEmpty() == false){
int begin_action_marker = data.indexOf("<action>")+8;
int end_action_marker = data.lastIndexOf("<action>");
String action = data.substring(begin_action_marker, end_action_marker);
int begin_actionData_marker = data.indexOf("<actionData>")+12;
int end_actionData_marker = data.lastIndexOf("<actionData>");
String actionData = data.substring(begin_actionData_marker, end_actionData_marker);
ms = new Message(action, actionData);
}
return ms;
}
public void setAction(String action){
this.action = action;
}
public String getActionData(){
return actionData;
}
public String getAction(){
return action;
}
public void setActionData(String action){
this.actionData = action;
}
public String eof_marker = "\r\n";
public String action;
public String action_marker = "<action>";
public String actionData;
public String actionData_marker = "<actionData>";
}
My guess:
you receive an empty request in (request = requestInStream.readLine())
this goes to Message.parseDataToMessage(request); which returns null for empty requests
that generates a NullPointerException in compileResponse
The (likely) solution: change this
while((request = requestInStream.readLine())!=""){
into this:
while(!(request = requestInStream.readLine()).isEmpty())
Why your code does not work: How do I compare strings in Java?
while((request = requestInStream.readLine())!=""){
What's this test for? Are you expecting empty requests? You shouldn't be. If you get one it's a bug at the sender.
However you must test the result of readLine() for null before doing anything else with it. The line should read:
while((request = requestInStream.readLine())!= null){
I am trying to send a json string , from my BlackBerry OS < 7.X application to my Server. I am trying to use an HTTP Post request. What i have done so far is :
String httpURL = "http://ip_of_my_server/phpServer/receiver2.php/" + jsonString;
try {
HttpConnection httpConn;
httpConn = (HttpConnection) Connector.open(httpURL + getConnectionString());
httpConn.setRequestMethod(HttpConnection.POST);
httpConn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
DataOutputStream _outStream = new DataOutputStream(httpConn.openDataOutputStream());
byte[] request_body = httpURL.getBytes();
for (int i = 0; i < request_body.length; i++) {
_outStream.writeByte(request_body[i]);
}
DataInputStream _inputStream = new DataInputStream(httpConn.openInputStream());
StringBuffer _responseMessage = new StringBuffer();
int ch;
while ((ch = _inputStream.read()) != -1) {
_responseMessage.append((char) ch);
}
String res = (_responseMessage.toString());
String response = res.trim();
System.out.println("!!!!!!!!!!!!!! Response is: " + response);
httpConn.close();
} catch (Exception e) {
Dialog.alert("Error - " + e.toString());
}
The code works in a way that i dont fully understand. The author of the above code suggested to use as an httpURL the URL of the server + my json string. The final result is that on my server instead of arriving the json string , is arriving a string like that :
http://ip_of_my_server/phpServer/receiver2.php/ + jsonString
I am not familiar with java. I have previously done this for WP7 and iOS and in the httpUrl i put my servers URL and then with a command i was "appending" my json string to the http request and everything worked as expected.
How can i append the json string to the above HttpRequest , instead of adding it to the URL so that in the server arrives the JSON String only?
EDIT (providing the rest of the code that was used)
//used to specify connection type ( wifi - 3g - etc )
public static String getConnectionString() {
String connectionString = null;
// Wifi is the preferred transmission method
if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
connectionString = ";interface=wifi";
}
// Is the carrier network the only way to connect?
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT) {
String carrierUid = getCarrierBIBSUid();
if (carrierUid == null) {
// Has carrier coverage, but not BIBS. So use the carrier's TCP network
connectionString = ";deviceside=true";
} else {
// otherwise, use the Uid to construct a valid carrier BIBS request
connectionString = ";deviceside=false;connectionUID="+carrierUid + ";ConnectionType=mds-public";
}
}
// Check for an MDS connection instead (BlackBerry Enterprise Server)
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS) {
connectionString = ";deviceside=false";
}
// If there is no connection available abort to avoid hassling the user unnecessarily
else if (CoverageInfo.getCoverageStatus() == CoverageInfo.COVERAGE_NONE) {
connectionString = "none";
}
// In theory, all bases are covered by now so this shouldn't be reachable.But hey, just in case ...
else {
connectionString = ";deviceside=true";
}
System.out.println("!!!!!!!!!!!!!! Connection type is: " + connectionString);
return connectionString;
}
/**
* Looks through the phone's service book for a carrier provided BIBS
* network
*
* #return The uid used to connect to that network.
*/
private synchronized static String getCarrierBIBSUid() {
ServiceRecord[] records = ServiceBook.getSB().getRecords();
int currentRecord;
for (currentRecord = 0; currentRecord < records.length; currentRecord++) {
if (records[currentRecord].getCid().toLowerCase().equals("ippp")) {
if (records[currentRecord].getName().toLowerCase()
.indexOf("bibs") >= 0) {
return records[currentRecord].getUid();
}
}
}
return null;
}
The the first line should be simply your URL
String httpURL = "http://ip_of_my_server/phpServer/receiver2.php";
And you should only send the json string to the server as request.
instead of byte[] request_body = httpURL.getBytes();
use byte[] request_body = jsonString.getBytes();
Here is the method for OS 5.0 and above
public static HttpConnection getHttpConnection(String url, byte[] postData) {
HttpConnection conn = null;
OutputStream out = null;
try {
conn = (HttpConnection) new ConnectionFactory().getConnection(url).getConnection();
if (conn != null) {
if (postData == null) {
conn.setRequestMethod(HttpConnection.GET);
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0");
} else {
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty("Content-Length", String.valueOf(postData.length));
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0");
out = conn.openOutputStream();
out.write(postData);
out.flush();
}
if (conn.getResponseCode() != 0) {
return conn;
}
}
} catch (Exception e) {
} finally {
try {
out.close();
} catch (Exception e2) {
}
}
//Only if exception occurs, we close the connection.
//Otherwise the caller should close the connection himself.
try {
conn.close();
} catch (Exception e1) {
}
return null;
}
Here is the complete class if you want it to work with OS 4.2 and above. You may need to replace the constant COVERAGE_DIRECT by its value 1, if you want to compile it with < 4.5.
public class ConnectionHelper {
/**
* Returns the working connection type. The connection types can be BIS, BES, TCP, WAP2, TCPIP
*/
public static HttpConnection getHttpConnection(String url, byte[] postData) {
int[] preferredOrder = new int[] { CONNECTION_WIFI, CONNECTION_BIS, CONNECTION_BES, CONNECTION_UNITE, CONNECTION_WAP2, CONNECTION_TCPIP, };
for (int i = 0; i < preferredOrder.length; i++) {
int type = preferredOrder[i];
if (isPresent(type)) {
HttpConnection conn = null;
OutputStream out = null;
try {
conn = (HttpConnection) Connector.open(convertURL(type, url));
if (conn != null) {
if (postData == null) {
conn.setRequestMethod(HttpConnection.GET);
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0");
} else {
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH, String.valueOf(postData.length));
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0");
out = conn.openOutputStream();
out.write(postData);
out.flush();
}
if (conn.getResponseCode() != 0) {
return conn;
}
}
} catch (Exception e) {
} finally {
try {
out.close();
} catch (Exception e2) {
}
}
}
}
// Only if exception occurs, we close the connection.
// Otherwise the caller should close the connection himself.
try {
conn.close();
} catch (Exception e1) {
}
return null;
}
/** Stores transport ServiceBooks if found. Otherwise, null */
private static ServiceRecord srMDS, srWiFi, srBIS, srWAP2, srUnite;
private static final int CONNECTION_DEFAULT = 0;
private static final int CONNECTION_BIS = 1;
private static final int CONNECTION_BES = 2;
private static final int CONNECTION_TCPIP = 3;
private static final int CONNECTION_WIFI = 4;
private static final int CONNECTION_WAP2 = 5;
private static final int CONNECTION_UNITE = 6;
private static final int CONFIG_TYPE_BES = 1;
private static final String UNITE_NAME = "Unite";
private static void checkTransportAvailability() {
initializeTransportAvailability();
}
/**
* Initializes the ServiceRecord instances for each transport (if available). Otherwise leaves it null. Also determines if sufficient coverage is available for each transport
* and sets coverage* flags.
*/
private static void initializeTransportAvailability() {
ServiceBook sb = ServiceBook.getSB();
ServiceRecord[] records = sb.getRecords();
for (int i = 0; i < records.length; i++) {
ServiceRecord myRecord = records[i];
String cid, uid;
if (myRecord.isValid() && !myRecord.isDisabled()) {
cid = myRecord.getCid().toLowerCase();
uid = myRecord.getUid().toLowerCase();
// BIS
if (cid.indexOf("ippp") != -1 && uid.indexOf("gpmds") != -1) {
srBIS = myRecord;
}
// BES
if (cid.indexOf("ippp") != -1 && uid.indexOf("gpmds") == -1) {
srMDS = myRecord;
}
// WiFi
if (cid.indexOf("wptcp") != -1 && uid.indexOf("wifi") != -1) {
srWiFi = myRecord;
}
// Wap2.0
if (cid.indexOf("wptcp") != -1 && uid.indexOf("wifi") == -1 && uid.indexOf("mms") == -1) {
srWAP2 = myRecord;
}
// Unite
if (getConfigType(myRecord) == CONFIG_TYPE_BES && myRecord.getName().equals(UNITE_NAME)) {
srUnite = myRecord;
}
}
}
}
/**
* Gets the config type of a ServiceRecord using getDataInt below
*
* #param record
* A ServiceRecord
* #return configType of the ServiceRecord
*/
private static int getConfigType(ServiceRecord record) {
return getDataInt(record, 12);
}
/**
* Gets the config type of a ServiceRecord. Passing 12 as type returns the configType.
*
* #param record
* A ServiceRecord
* #param type
* dataType
* #return configType
*/
private static int getDataInt(ServiceRecord record, int type) {
DataBuffer buffer = null;
buffer = getDataBuffer(record, type);
if (buffer != null) {
try {
return ConverterUtilities.readInt(buffer);
} catch (EOFException e) {
return -1;
}
}
return -1;
}
/**
* Utility Method for getDataInt()
*/
private static DataBuffer getDataBuffer(ServiceRecord record, int type) {
byte[] data = record.getApplicationData();
if (data != null) {
DataBuffer buffer = new DataBuffer(data, 0, data.length, true);
try {
buffer.readByte();
} catch (EOFException e1) {
return null;
}
if (ConverterUtilities.findType(buffer, type)) {
return buffer;
}
}
return null;
}
private static String convertURL(int connectionType, String url) {
switch (connectionType) {
case CONNECTION_BES:
url += ";deviceside=false";
break;
case CONNECTION_BIS:
url += ";deviceside=false" + ";ConnectionType=mds-public";
break;
case CONNECTION_TCPIP:
url += ";deviceside=true";
break;
case CONNECTION_WIFI:
url += ";interface=wifi";
break;
case CONNECTION_WAP2:
url += ";deviceside=true;ConnectionUID=" + srWAP2.getUid();
break;
case CONNECTION_UNITE:
url += ";deviceside=false;ConnectionUID=" + srUnite.getUid();
break;
}
return url;
}
private static boolean isPresent(int connectionType) {
checkTransportAvailability();
switch (connectionType) {
case CONNECTION_BIS:
return (srBIS != null && CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_BIS_B));
case CONNECTION_BES:
return (srMDS != null && CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_MDS));
case CONNECTION_WIFI:
return (srWiFi != null && CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT, RadioInfo.WAF_WLAN, false));
case CONNECTION_TCPIP:
return (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT));
case CONNECTION_WAP2:
return (srWAP2 != null && CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_DIRECT));
case CONNECTION_UNITE:
return (srUnite != null && CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_MDS));
case CONNECTION_DEFAULT:
return true;
}
return false;
}
}
And finally post your data.
public void sendJson(String jsonString) {
String httpURL = "http://ip_of_my_server/phpServer/receiver2.php";
HttpConnection httpConn = null;
try {
httpConn = getHttpConnection(httpURL, jsonString.getBytes());
if(httpConn.getResponseCode() == 200) {
//If you need the output, then read it. Otherwise comment it.
byte[] data = IOUtilities.streamToBytes(httpConn.openInputStream());
String response = new String(data);
System.out.println("!!!!!!!!!!!!!! Response is: " + response);
}
} catch (Exception e) {
}
finally {
try {
httpConn.close();
} catch (Exception e2) {
}
}
}
Does anyone know where to find a little how to on using dbpedia spotlight in java or scala? Or could anyone explain how it's done? I can't find any information on this...
The DBpedia Spotlight wiki pages would be a good place to start.
And I believe the installation page has listed the most popular ways (using a jar, or set up a web service) to use the application.
It includes instructions on using the Java/Scala API with your own installation, or calling the Web Service.
There are some additional data needed to be downloaded to run your own server for full service, good time to make a coffee for yourself.
you need download dbpedia spotlight (jar file) after that u can use next two classes ( author pablomendes ) i only make some change .
public class db extends AnnotationClient {
//private final static String API_URL = "http://jodaiber.dyndns.org:2222/";
private static String API_URL = "http://spotlight.dbpedia.org:80/";
private static double CONFIDENCE = 0.0;
private static int SUPPORT = 0;
private static String powered_by ="non";
private static String spotter ="CoOccurrenceBasedSelector";//"LingPipeSpotter"=Annotate all spots
//AtLeastOneNounSelector"=No verbs and adjs.
//"CoOccurrenceBasedSelector" =No 'common words'
//"NESpotter"=Only Per.,Org.,Loc.
private static String disambiguator ="Default";//Default ;Occurrences=Occurrence-centric;Document=Document-centric
private static String showScores ="yes";
#SuppressWarnings("static-access")
public void configiration(double CONFIDENCE,int SUPPORT,
String powered_by,String spotter,String disambiguator,String showScores){
this.CONFIDENCE=CONFIDENCE;
this.SUPPORT=SUPPORT;
this.powered_by=powered_by;
this.spotter=spotter;
this.disambiguator=disambiguator;
this.showScores=showScores;
}
public List<DBpediaResource> extract(Text text) throws AnnotationException {
LOG.info("Querying API.");
String spotlightResponse;
try {
String Query=API_URL + "rest/annotate/?" +
"confidence=" + CONFIDENCE
+ "&support=" + SUPPORT
+ "&spotter=" + spotter
+ "&disambiguator=" + disambiguator
+ "&showScores=" + showScores
+ "&powered_by=" + powered_by
+ "&text=" + URLEncoder.encode(text.text(), "utf-8");
LOG.info(Query);
GetMethod getMethod = new GetMethod(Query);
getMethod.addRequestHeader(new Header("Accept", "application/json"));
spotlightResponse = request(getMethod);
} catch (UnsupportedEncodingException e) {
throw new AnnotationException("Could not encode text.", e);
}
assert spotlightResponse != null;
JSONObject resultJSON = null;
JSONArray entities = null;
try {
resultJSON = new JSONObject(spotlightResponse);
entities = resultJSON.getJSONArray("Resources");
} catch (JSONException e) {
//throw new AnnotationException("Received invalid response from DBpedia Spotlight API.");
}
LinkedList<DBpediaResource> resources = new LinkedList<DBpediaResource>();
if(entities!=null)
for(int i = 0; i < entities.length(); i++) {
try {
JSONObject entity = entities.getJSONObject(i);
resources.add(
new DBpediaResource(entity.getString("#URI"),
Integer.parseInt(entity.getString("#support"))));
} catch (JSONException e) {
LOG.error("JSON exception "+e);
}
}
return resources;
}
}
second class
/**
* #author pablomendes
*/
public abstract class AnnotationClient {
public Logger LOG = Logger.getLogger(this.getClass());
private List<String> RES = new ArrayList<String>();
// Create an instance of HttpClient.
private static HttpClient client = new HttpClient();
public List<String> getResu(){
return RES;
}
public String request(HttpMethod method) throws AnnotationException {
String response = null;
// Provide custom retry handler is necessary
method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler(3, false));
try {
// Execute the method.
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
LOG.error("Method failed: " + method.getStatusLine());
}
// Read the response body.
byte[] responseBody = method.getResponseBody(); //TODO Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
response = new String(responseBody);
} catch (HttpException e) {
LOG.error("Fatal protocol violation: " + e.getMessage());
throw new AnnotationException("Protocol error executing HTTP request.",e);
} catch (IOException e) {
LOG.error("Fatal transport error: " + e.getMessage());
LOG.error(method.getQueryString());
throw new AnnotationException("Transport error executing HTTP request.",e);
} finally {
// Release the connection.
method.releaseConnection();
}
return response;
}
protected static String readFileAsString(String filePath) throws java.io.IOException{
return readFileAsString(new File(filePath));
}
protected static String readFileAsString(File file) throws IOException {
byte[] buffer = new byte[(int) file.length()];
#SuppressWarnings("resource")
BufferedInputStream f = new BufferedInputStream(new FileInputStream(file));
f.read(buffer);
return new String(buffer);
}
static abstract class LineParser {
public abstract String parse(String s) throws ParseException;
static class ManualDatasetLineParser extends LineParser {
public String parse(String s) throws ParseException {
return s.trim();
}
}
static class OccTSVLineParser extends LineParser {
public String parse(String s) throws ParseException {
String result = s;
try {
result = s.trim().split("\t")[3];
} catch (ArrayIndexOutOfBoundsException e) {
throw new ParseException(e.getMessage(), 3);
}
return result;
}
}
}
public void saveExtractedEntitiesSet(String Question, LineParser parser, int restartFrom) throws Exception {
String text = Question;
int i=0;
//int correct =0 ; int error = 0;int sum = 0;
for (String snippet: text.split("\n")) {
String s = parser.parse(snippet);
if (s!= null && !s.equals("")) {
i++;
if (i<restartFrom) continue;
List<DBpediaResource> entities = new ArrayList<DBpediaResource>();
try {
entities = extract(new Text(snippet.replaceAll("\\s+"," ")));
System.out.println(entities.get(0).getFullUri());
} catch (AnnotationException e) {
// error++;
LOG.error(e);
e.printStackTrace();
}
for (DBpediaResource e: entities) {
RES.add(e.uri());
}
}
}
}
public abstract List<DBpediaResource> extract(Text text) throws AnnotationException;
public void evaluate(String Question) throws Exception {
evaluateManual(Question,0);
}
public void evaluateManual(String Question, int restartFrom) throws Exception {
saveExtractedEntitiesSet(Question,new LineParser.ManualDatasetLineParser(), restartFrom);
}
}
main()
public static void main(String[] args) throws Exception {
String Question ="Is the Amazon river longer than the Nile River?";
db c = new db ();
c.configiration(0.0, 0, "non", "CoOccurrenceBasedSelector", "Default", "yes");
System.out.println("resource : "+c.getResu());
}
I just add one little fix for your answer.
Your code is running, if you add the evaluate method call:
public static void main(String[] args) throws Exception {
String question = "Is the Amazon river longer than the Nile River?";
db c = new db ();
c.configiration(0.0, 0, "non", "CoOccurrenceBasedSelector", "Default", "yes");
c.evaluate(question);
System.out.println("resource : "+c.getResu());
}
Lamine
In the request method of the second class (AnnotationClient) in Adel's answer, the author Pablo Mendes hasn't finished
TODO Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.
which is an annoying warning that needs to be removed by replacing
byte[] responseBody = method.getResponseBody(); //TODO Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.
// Deal with the response.
// Use caution: ensure correct character encoding and is not binary data
response = new String(responseBody);
with
Reader in = new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8");
StringWriter writer = new StringWriter();
org.apache.commons.io.IOUtils.copy(in, writer);
response = writer.toString();