I'm trying to read the text from https://mtgjson.com/api/v5/AllPrintings.json. I have tried with this code:
url = new URL("https://mtgjson.com/api/v5/AllPrintings.json");
conn = (HttpsURLConnection) url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); // error here
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
System.out.println(content);
I keep getting IOException with the BufferedReader (conn.getInputStream()). The text from the url does not contain a new line character. How can I read this data?
(Edit)
I'm using Java 1.8 with Apache NetBeans 16. I'm sticking with 1.8 so I can also use Eclipse Neon3.
Error:
java.io.IOException: Server returned HTTP response code: 403 for URL: https://mtgjson.com/api/v5/AllPrintings.json
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1894)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:263)
at tests.MtgJson.main(MtgJson.java:44)
I've also been trying ProcessBuilder with curl and it's giving better results but curl stops after about a minute. Curl continues if I terminate the program inside Netbeans but doesn't always finish creating the file contents. I shouldn't have to stop my program for curl to continue. Is there something I'm missing for curl to work?
String command = "curl --keepalive-time 5 https://mtgjson.com/api/v5/AllPrintings.json";
ProcessBuilder pb = new ProcessBuilder(command.split(" "));
pb.redirectOutput(new File("AllPrintings.json"));
Process process = pb.start();
// use while() or process.waitfor();
while(process.isAlive())
Thread.sleep(1000);
process.destroy();
Answer (since I can't post one):
String command = "curl https://mtgjson.com/api/v5/AllPrintings.json";
ProcessBuilder pb = new ProcessBuilder(command.split(" "));
pb.inheritIO(); // keep the program from hanging
pb.redirectOutput(new File("AllPrintings.json"));
Process process = pb.start();
process.waitFor(); // waiting for the process to terminate.
The complete file is created without hanging then the program will close. Curl outputs info to the console and must be consumed (found here).
There is no need to use byte->character conversion with BufferedReader just to make a copy. Instead copy the content directly to a file using Java NIO Files.copy, and then use the output file for any further processing:
Path file = Path.of("big.json");
// Older JDK use Paths.get("filename")
Files.copy(conn.getInputStream(), file);
System.out.println("Saved "+Files.size(file)+" bytes to "+file);
Which should print:
Saved 313144388 bytes to big.json
Related
I struggled to get this working but eventually got the script to execute a command (executing a sh script) on a remote unix server. I am trying to execute a second command and keep getting an error either with creating a new channel or using the same.
try {
((ChannelExec) channel).setCommand(command);
PrintStream out= new PrintStream(channel.getOutputStream());
InputStream in = channel.getInputStream();
channel.connect();
BufferedReader scriptReader= new BufferedReader(new InputStreamReader(in));
scriptOutput = scriptReader.readLine();
sb = new StringBuilder();
while ((scriptOutput = scriptReader.readLine())!= null) {
sb.append(scriptOutput + "\n");
This is the first snippet of the channel execute which works fine. Now the next method snippet is called immediately after consuming the above inputstream:
try {
StringBuilder sb = new StringBuilder();
command = new_command;
((ChannelExec) channel).setCommand(command);
InputStream in = channel.getInputStream();
channel.connect();
BufferedReader scriptReader= new BufferedReader(new InputStreamReader(in));
scriptOutput = scriptReader.readLine();
//StringBuilder sb = new StringBuilder();
for(int c=0; c < consumerList.size(); c++){
....
Now this returns the following error:
com.jcraft.jsch.JSchException: channel is not opened.
Now if I create a new channel with the same session I get a null response from returned stream. I did test the command in the remote shell and it works fine:
int counter = 0;
Channel channelII = session.openChannel("exec");
try {
StringBuilder sb = new StringBuilder();
command = new_command;
((ChannelExec) channelII).setCommand(command);
InputStream in = channelII.getInputStream();
channelII.connect();
BufferedReader scriptReader= new BufferedReader(
new InputStreamReader(in));
scriptOutput = scriptReader.readLine();
the second command is the following and I want to be able to repeatedly execute it for different consumer groups:
/usr/kafka/bin/kafka-consumer-groups.sh --bootstrap-server
192.xxx.xx.xxx:9092 --describe -group consumergroup1
EDIT:
response of second command:
TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET
LAG CONSUMER-ID HOST
CLIENT-ID
output.influxDB 1 94919 2781796
2686877 - -
-
output.influxDB 0 94919 2781798
2686879 - -
-
output.influxDB 2 94918 2781795
2686877 - -
-
Thank you to Nicholas and Martin for their responses. I figured out what was wrong and wanted to post an answer as I do realize that little things like this do crop up for us 'dumb' programmers out there who ask ridiculous questions that incur negative votes. The output for the second command was returning a warning / error response in the first line and by not including the following I was not seeing that and reading the next line was empty. I know it's stupid and should have figured this out before posting because that is the point of this site: post questions that are beyond the knowledge of others. But since I should have innately known this:
Anyway ensure the following line is included:
((ChannelExec)channelII).setErrStream(System.err);
and also read the stream with a loop and not just test with reading the first line.
while ((scriptOutput = scriptReader.readLine())!= null) {
sb.append(scriptOutput + "\n");
}
I hope this can at least be a lesson to some if not a solution.
I am sending setup commands to a TP-LINK wireless router through a telnet connection:
Trying 1.2.3.4...
Connected to 1.2.3.4.
Escape character is '^]'.
*HELLO*$$$
CMD
factory RESET
factory RESET
Set Factory Defaults
<4.00> set sys autoconn 0
set sys autoconn 0
AOK
<4.00>
...
I have a PHP code that performs the sending of commands and gets the response using sockets:
socket_write($socket, "factory RESET\r"); // send command
$response = socket_read($socket, 256); // get response
PHP works fine. The $response variable contains:
factory RESET
Set Factory Defaults
But using the Java I have problems. Using a BufferedReader object to read response, I can get the first line content. but I can not get the following lines:
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// ...
bw.write("factory RESET");
bw.newLine();
bw.flush();
// ...
StringBuilder sb = new StringBuilder();
String s;
while ((s = br.readLine()) != null) {
sb.append(s);
}
I can get the first line content, but the second reading don't proceed and don't raise exception...
If I use the read function, only the first row is returned:
char[] buffer = new char[256];
br.read(buffer, 0, 256);
String response = new String(buffer); // response is "factory RESET"
What is the problem?
Your PHP code execute two reads. Your Java code attempts to read until end of stream, which only happens when the peer closes the connection. Do a single read.
The line separator in the Telnet protocol is defined as \r\n, unless you're using binary mode, which you aren't. Not as\r or whatever BufferedWriter may do on your platform.
I have been trying to retrieve XML data from a URL and write to file on disk http://dbpedia.org/data/Berlin.rdf using the following code snippet.
URL urlObj = new URL("http://dbpedia.org/data/Berlin.rdf");
java.net.HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection();
InputStream reader = new BufferedInputStream(connection.getInputStream());
BufferedReader breader = new BufferedReader(new InputStreamReader(reader));
String line;
BufferedWriter writer = new BufferedWriter(new eWriter("resource.xml"));
while ((line = breader.readLine()) != null) {
// writes the line to the output file
writer.write(line);
System.out.println(line);
}
writer.close();
connection.disconnect();
But I get this error: Exception in thread "main" java.io.IOException: Server returned HTTP response code: 502 for URL: http://dbpedia.org/data/Berlin.rdf
What is wrong ? How to fix this ? Thanks in advance.
A 502 HTTP Error is a Server Error.
If you go to the site (http://dbpedia.org/data/Berlin.rdf), you will see that dbpedia is currently undergoing maintenance. Go back in a couple of hours and try again and your code should work fine.
Update: It's working fine now.
I am developing an Android application. I am calling a Perl file on a server. This Perl file has different print statements.
I want to make the collective text available to a variable in android Java file of mine.
I have tried this :
URL url= new URL("http://myserver.com/cgi-bin/myfile.pl?var=97320");
here goes my request to the server file. But how can i get the data from the Perl file available there?
In your perl service:
use CGI qw(param header);
use JSON;
my $var = param('var');
my $json = &fetch_return_data($var);
print header('application/json');
print to_json($json); # or encode_json($json) for utf-8
to return data as a JSON object. Then use one of many JSON libraries for Java to read the data. For instance http://json.org/java/:
Integer var = 97320;
InputStream inputStream = new URL("http://myserver.com/cgi-bin/myfile.pl?var=" + var).openStream();
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
// Or this if you returned utf-8 from your service
//BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
JSONObject json = new JSONObject(readAll(bufferedReader));
} catch (Exception e) {
}
I used url.openConnection() to get text from a webpage
but i got time delay in execution while i tried it in loops
i also tried httpUrl.disconnect().
but the change is not that much...
can anyone give me a better option for this
i used the following code for this
for(int i=0;i<10;i++){
URL google = new URL(array[i]);//array of links
HttpURLConnection yc =(HttpURLConnection)google.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
source=source.concat(inputLine);
}
in.close();
yc.disconnect();
}
A couple of issues I can see.
in.readLine() doesn't retain the newline so when you use concat, all the newlines have been removed.
Using concat in a loop like this builds a longer and longer String. This will get slower and slower with each line you add.
Instead you might find IOUtils useful.
URL google = new URL("123newyear.com/2011/calendars/");
String text = IOUtils.toString(google.openConnection().getInputStream());
See Reading Directly from a URL for details on how to to get a stream from which you can read the contents of the URL.
Basically, you
Create a url URL url = new URL("123newyear.com/2011/calendars/";
Call openstream() on the URL object
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
Read from the stream (like you did).