Java - Append data to a text file kept on webserver - java

I am trying to append some information to a text file kept on webserver using java using:
public class Main {
public static void main(String[] args) {
try {
URL url = new URL("http://www.abcd.com/info.txt");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if (connection != null) {
System.out.println("Established URL connection");
}
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestProperty("Content-Type", "text/html");
System.out.println(connection.getOutputStream().toString());
OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
writer.write("This is a sample text");
writer.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
Neither the text file is not being updated nor getting any error.. The reason for doing this is - I have developed a small software and the updates for this will be kept on web site. If any user updates the data, this code will update the text file. This way I will be able to get the information of user who have updated.

As far as I know, you first need to get the data written in the file, to client, Using a GET call , then append the data, and the finally do a POST call to rewrite the file with appended data

You would have to make the changes at server side to do that. You cannot acheive the same using HttpURLConnection.
You can try using FTP if its feasible for you. In case of FTP you should download the file, append the text and upload the same again.

I'm a bit confused - you're attempting to open an HTTP connection to a file and modify it on the fly?
I feel like I might be missing something - plain HTTP doesn't support this. Can you imagine the nightmare it would be if everybody could go around overwriting everybody else's websites (without authentication, even, as your code seems to suggest)?
What you're doing here is calling PUT on the /info.txt resource with your text as the entity body. I'm fairly sure that never has and never will overwrite the corresponding file.
What you need to do is either go through a protocol that supports file writing (WebDav, FTP...) or write server-side code that accepts a content submission (through, for example, a POST or PUT call with an entity body on a specific resource), analyses that input and modify its local file system.
Again, I might be misunderstanding your question entirely, in which case I apologise if I come off as somewhat patronising.

Related

Sending a zero-length HTTPS PUT?

I'm working with a system that, in order to make a particular service call, requires the following:
Issue an HTTP PUT command
Set the URL to some_url_here
Set the end user certificate.
Ensure that the entity body is empty and set the Content-Length headers to 0.
Here's the method I wrote to build secure connections. I've tested the GETs; they work fine. I know the problem isn't in the certificate.
public HttpsURLConnection getSecureConnection(final URL url, final String method, final int connectTimeout,
final int readTimeout) throws IOException {
Validate.notNull(sslContext);
Validate.notNull(url);
Validate.notNull(method);
Validate.isTrue(connectTimeout > 0);
Validate.isTrue(readTimeout > 0);
HttpsURLConnection connection;
try {
connection = (HttpsURLConnection) url.openConnection();
} catch (final IOException ioe) {
LOGGER.error("[CertificateLoader] Unable to open URL connection!", ioe);
throw new IOException("Unable to open URL connection!", ioe);
}
connection.setSSLSocketFactory(sslContext.getSocketFactory());
connection.setRequestMethod(method);
connection.setConnectTimeout(connectTimeout);
connection.setReadTimeout(readTimeout);
connection.setHostnameVerifier(NoopHostnameVerifier.INSTANCE);
if (method.equals("PUT")) {
connection.setRequestProperty("Content-Length", "0");
}
if (connection.getContentLength() > 0) {
Object foo = connection.getContent();
LOGGER.error("This is what's in here: " + foo.toString());
}
return connection;
}
Now, the reason for that funky if at the bottom is that when I go to make the PUT call, even though I'm not putting a body on the call directly, my logs insist I'm getting a non-zero content length. So, I added that little block to try to figure out what's in there, and lo and behold it reports the following:
This is what's in here: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream#70972170
Now, that sucker's in there by default. I didn't put it in there. I didn't create that object to put in there. I just created the object as is from the URL, which I created from a String elsewhere. What I need is a way to remove that HttpInputStream object, or set it to null, or otherwise tell the code that there should be no body to this PUT request, so that my server won't reject my message as being ill-formatted. Suggestions?
Now, the reason for that funky if at the bottom is that when I go to make the PUT call, even though I'm not putting a body on the call directly, my logs insist I'm getting a non-zero content length.
The way to set a zero Content-length is as follows:
connection.setDoOutput(true); // if it's PUT or POST
connection.setRequestMethod(method);
connection.getOutputStream().close(); // send a zero length request body
It is never necessary to call connection.setRequestProperty("Content-Length", "0"). Java sets it for you. Or possibly it is omitted, in which case you may be able to ensure it via
connection.setFixedLengthStreamingMode(0);
So, I added that little block to try to figure out what's in there, and lo and behold it reports the following:
This is what's in here: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream#70972170
Now, that sucker's in there by default. I didn't put it in there.
Java put it there.
I didn't create that object to put in there.
Java put it there.
I just created the object as is from the URL, which I created from a String elsewhere. What I need is a way to remove that HttpInputStream object, or set it to null, or otherwise tell the code that there should be no body to this PUT request, so that my server won't reject my message as being ill-formatted.
No it isn't. It is an input stream, not a piece of content. And it is an input stream to the content of the response, not of the request. And in any case, the server is perfectly entitled to return you content in response to your request.
Your task is to:
Get the response code and log it.
If it is >=200 and <= 299, get the connection's input stream.
Otherwise get the connection's error stream.
Whichever stream you got, read it till end of stream, and log it.
That will tell you what is really happening.
I will add that a PUT without a body is a really strange thing to do. Are you sure you've understood the requirement? 411 means Length required.

HTTP response code of text file is 460 when file contains 1.0.2?

I'm using an HttpsURLConnection to grab the only line in a text file hosted on Dropbox, as an update checker (for a Minecraft mod). The relevant code is below:
URL url = new URL(linkToVersionFile);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setConnectTimeout(999);
int responseCode = connection.getResponseCode();
Normally, this works fine. Except, however, if the text in the file is "1.0.2". When it's 1.0.2, it returns the 460 response code, which I cant seem to find in any list of response codes. The accompanying response message is "Restricted" though.
If the file contains "1.0.1", "1.0.3", "1.1.2", "1.2.2" or even "2.0.2" it works just fine. Nothing changes but the 5 characters located in the file. The same thing happens if different files are used, and given the text "1.0.2", so it's not a corrupt file.
While I can get around it by either avoiding 1.0.2 and moving straight to 1.0.3, or writing it as "102" instead, it's just such an usual problem that I was wondering if anyone had an explanation :P
If more information or test results is required, let me know.
Thanks in advance :)

calling REST websrevice via Android

I'm currently calling a local .json file in my Android app using the following line
InputStream inputStream = context.getAssets().open("cyclist.json");
I simply want to switch it to pull the .json from a webservice instead. What is the best way to do this?
Please, please, don't reinvent the wheel.
Use existing libraries Volley by Google (video from I/O talk), Retrofit by Square, RoboSpice and countless others are there to serve you. Further, search before posting
Supposing you already set up a server to respond to requests, I would try something like this:
URL url = new URL("http://www.mydomain.com/slug");
URLConnection urlConnection = url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
try {
readStream(in);
} finally {
in.close();
}
See URLConnection for details.
I know Android enforces limitations in downloading stuff from a server. You might have to execute the code in another thread, using the AsyncTask. Again, I'm not sure if this is required for your particular purpose.

Better way to send lots of text to a server?

I have a java application that sends text to a sql database on a server. Currently my java application takes the text, puts it into the url, then sends it to a php page on the server that takes it with GET and puts it in the database. that works fine to an extent, the problem is, that i need to be able to send lots of text, and i keep getting 414, uri to long errors. is there a better way to do this?
ok, i tried what you said, and read the tutorial, but something is not working. here is my code that i tried
public void submitText(String urls,String data) throws IOException{
URL url = new URL(urls);
URLConnection con = url.openConnection();
con.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
con.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
out.write(data);
out.flush();
}
submitText(server + "publicPB.php", "param=" + text);
here is my php code
$param = $_POST['param'];
$sql = "UPDATE table SET cell='{$param}' WHERE 1";
mysql_query($sql);
...
im pretty sure its not a problem with the php as the php worked fine with GET, and thats all i change with it, my problem i think is that im not 100% sure how to send data to it with the java
Use a POST instead of a GET and send the text as the request body. You can only pass so much data to a URL. E.g.:
// Assuming 'input' is a String and contains your text
URL url = new URL("http://hostname/path");
URLConnection con = url.openConnection();
con.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
con.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream(), "UTF-8");
out.write(input);
out.close();
See Reading from and Writing to a URLConnection for more details.
Why don't you use POST to send data across to PHP page? GET does have a smaller limit of content.
Use POST requests, which do not have content length limits.
POST requests do not have length content limits and are much secure than GET requests ;)
If using SQL Server I would look into leveraging BCP. You can write the file and call BCP from within Java, and it will send the information directly to your database.

how do I search a word in a webpage

how do I search for existence of a word in a webpage given its url say "www.microsoft.com". Do I need to download this webpage to perform this search ?
You just need to make http request on web page and grab all its content after that you can search necessary words in it, below code might help you to do so.
public static void main(String[] args) {
try {
URL url;
URLConnection urlConnection;
DataOutputStream outStream;
DataInputStream inStream;
// Build request body
String body =
"fName=" + URLEncoder.encode("Atli", "UTF-8") +
"&lName=" + URLEncoder.encode("Þór", "UTF-8");
// Create connection
url = new URL("http://www.example.com");
urlConnection = url.openConnection();
((HttpURLConnection)urlConnection).setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.setRequestProperty("Content-Length", ""+ body.length());
// Create I/O streams
outStream = new DataOutputStream(urlConnection.getOutputStream());
inStream = new DataInputStream(urlConnection.getInputStream());
// Send request
outStream.writeBytes(body);
outStream.flush();
outStream.close();
// Get Response
// - For debugging purposes only!
String buffer;
while((buffer = inStream.readLine()) != null) {
System.out.println(buffer);
}
// Close I/O streams
inStream.close();
outStream.close();
}
catch(Exception ex) {
System.out.println("Exception cought:\n"+ ex.toString());
}
}
i know how i would do this in theory - use cURL or some application to download it, store the contents into a variable, then parse it for whatever you need
Yes, you need to download page content and search inside it for what you want. And if it happens that you want to search the whole microsoft.com website then you should either write your own web crawler, use an existing crawler or use some search engine API like Google's.
Yes, you'll have to download the page, and, to make sure to get the complete content, you'll want to execute scripts and include dynamic content - just like a browser.
We can't "search" something on a remote resource, that is not controlled by us and no webservers offers a "scan my content" method by default.
Most probably you'll want to load the page with a browser engine (webkit or something else) and perform the search on the internal DOM structure of that engine.
If you want to do the search yourself, then obviously you have to download the page.
If you're planning on this approach, i recommend Lucene (unless you want a simple substring search)
Or you could have a webservice that does it for you. You could request the webservice to grep the url and post back its results.
You could use a search engine's API. I believe Google and Bing (http://msdn.microsoft.com/en-us/library/dd251056.aspx) have ones you can use.

Categories