So we are working on this app in Android Studio where we want to make a get request to a website, and when we run this piece of code, we keep getting an error of "null" which I believe to be so because one of the variables in this piece of code is null. Can someone look it over and see any places where you may detect some variable is not being used correctly and therefore providing a null error?
public class SpotAlgo {
String vidLink;
int linkLoc;
String testString = "<title>";
String result;
public String gettheResult(String v) throws Exception{
String sname = " ";
vidLink = "https://open.spotify.com/track/43PuMrRfbyyuz4QpZ3oAwN";
URL obj = new URL(vidLink);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine = "";
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
result = response.toString();
linkLoc = result.indexOf(testString) + testString.length();
for (int i = linkLoc; i < result.indexOf("on Spotify"); i++) {
sname += result.charAt(i) + "";
}
return obj.toString();
}
}
Nothing, it works fine!
I believe that if you have a null pointer exception, it is related to another part of your code.
However, here are some suggestions to improve it
In this snippet you add text to the sname variable in a loop. When you do that kind of operation a StringBuilder will be more efficient.
for (int i = linkLoc; i < result.indexOf("on Spotify"); i++) {
sname += result.charAt(i) + "";
}
//Could be replaced b
for (int i = linkLoc; i < result.indexOf("on Spotify"); i++) {
sb.append(result.charAt(i));
}
You can later use sb.toString() to get the result of the operation.
Also, more importantly, when you do network operation you never know what the result will be. There can be many variables that will inpact the result you will get, and often exceptions will be thrown. It is important that you wrap the network code in a try { } finally {}, and that you close the ressources you open in the finally block (a finally block always execute).
edit
Fixed a typo
edit 2
Some people are saying it is throwing a 404 exception, I did not get one when I ran it on my machine, and a 404 would throw an IOException when you do con.getInputStream(), so you would likely see that instead
You missed actually connecting
con.setRequestMethod("GET");
con.connect();
Your con.getInputStream(); is null since the connection is not made and nothing is returned to con.
Related
I'm trying to make a program to check for announcements via a web API - This connects to a remote server and reads the JSON on the page - I cannot test my code as the server is not live yet. Would this work & be the correct way to go about this?
public class AnnouncementChecker implements Runnable{
private final String announcementsURL = "REDACTED";
private String lastAnnouncement = "";
#Override
public void run(){
try {
URL url = new URL(announcementsURL);
HttpURLConnection http = (HttpURLConnection) url.openConnection();
http.setRequestMethod("conditional GET");
http.setRequestProperty("Connection", "keep-alive");
http.setUseCaches(true);
http.setAllowUserInteraction(false);
if (lastAnnouncement != ""){
http.setRequestProperty("If-Modified-Since", lastAnnouncement);
}
http.setConnectTimeout(10);
http.connect();
int status = http.getResponseCode();
if (status == 304 || (status == 200 && lastAnnouncement == "")){
lastAnnouncement = http.getHeaderField("Last-Modified");
BufferedReader br = new BufferedReader(new InputStreamReader(http.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
String json = sb.toString();
JSONParser parser = new JSONParser();
JSONObject jsonResponse = (JSONObject) parser.parse(json);
//String announcement = (String) jsonResponse.get("message");
//TODO What to do with announcement...
}
http.getInputStream().close();
http.disconnect();
} catch (IOException | ParseException e) {
e.printStackTrace();
}
}
}
I would recommend setting up a test of some kind, despite the server not being available. This would give you the answer to your question and the test would be there forever going forward to protect you when you make changes to the code and the business requirements change.
To help you with that I would recommend splitting up the code that returns the response and the code that does the parsing. That way you can test the parsing independent of the part that makes the HTTP connection.
If you have no idea how to do that then I'd be happy to post an example for you.
Hi I am trying to set jsp variable into a javascript array. I tried, but I am not able to achieve this when I run my code. I do not get my output, I only see a blank screen.
Here is my code:
value.jsp
<script>
<%
URL url;
ArrayList<String> list1 = new ArrayList<String>();
ArrayList<String> list2 = new ArrayList<String>();
List commodity = null;
List pric = null;
int c = 0;
int p = 0;
try {
// get URL content
String a = "http://122.160.81.37:8080/mandic/commoditywise?c=paddy";
url = new URL(a);
URLConnection conn = url.openConnection();
// open the stream and put it into BufferedReader
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
StringBuffer sb = new StringBuffer();
String inputLine;
while ((inputLine = br.readLine()) != null)
{
System.out.println(inputLine);
// sb.append(inputLine);
String s=inputLine.replace("|", "\n");
s = s.replace("~"," ");
StringTokenizer str = new StringTokenizer(s);
while(str.hasMoreTokens())
{
String mandi = str.nextElement().toString();
String price = str.nextElement().toString();
list1.add(mandi);
list2.add(price);
}
}
commodity = list1.subList(0,10);
pric = list2.subList(0,10);
for (c = 0,p = 0; c < commodity.size()&& p<pric.size(); c++,p++)
{
String x = (String)commodity.get(c);
String y = (String)pric.get(p);
//out.println(y);
//out.println(x);}
%>
jQuery(function ($) {
var roles = [];
roles.push(<%= x%>)
roles.push(<%= y%>)
<%
}
%>
var counter = 0;
var $role = $('#role')
//repeat the passed function at the specified interval - it is in milliseconds
setInterval(function () {
//display the role and increment the counter to point to next role
$role.text(roles[counter++]);
//if it is the last role in the array point back to the first item
if (counter >= roles.length) {
counter = 0;
}
}, 400)
});
</script>
<%
br.close();
//System.out.println(sb);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
%>
How can I achieve my desired output?
When you output to JS from JSP, you have to make sure your output is valid JS.
Your current output will output a string with no quotes, which the JS interpreter will treat as JS code and not strings or arrays as you want.
In addition, you are producing 10 copies of the JS
jQuery(function ($) {
var roles = [];
roles.push(<%= x%>)
roles.push(<%= y%>)
and that function is never closed.
I would look for a decent JSON output library. That would simplify your life quite a bit here.
It looks like you are clearing the roles variable var roles = []; with each pass of the loop.
You might want to consider not posting the entire file, but pairing the example down to just the part you need help with.
You could also put the array into a JSON object and parse that in your javascript. That might be a cleaner implementation.
try enclosing the scriptlets with quotes like roles.push("<%= x%>") and also check the array initialization.
I use the code below which in my http get request,but what I get from return is a null.I don't know why.
public static String getResponseFromGetUrl(String url) throws Exception {
StringBuffer sb = new StringBuffer();
try {
HttpResponse httpResponse = httpclient.execute(httpRequest);
String inputLine = "";
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
InputStreamReader is = new InputStreamReader(httpResponse
.getEntity().getContent());
BufferedReader in = new BufferedReader(is);
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
in.close();
}
} catch (Exception e) {
e.printStackTrace();
return "net_error";
} finally {
httpclient.getConnectionManager().shutdown();
}
return sb.toString();
}
And what I have use the function is
String json_str = HttpUtils.getResponseFromGetUrl("www.xxx.com/start");
if ((json_str == null)) Log.d("Chen", "lastestTimestap----" + "json_str == null");
And sometimes the Log will be printed.Not always,in fact like 1%.But I don't know why it caused.
This code will not produce a "null". There must be more code you are not showing.
If this is all the code you have I suggest you remove the StringBuffer and replace it with
return "";
More likely you have forgetten to mention some code which is doing something like
Object o = null;
sb.append(o); // appears as "null"
EDIT: Based on your update, I would have to assume you are reading a line like "null"
It is highly unlikely you want to discard the newline between each line. I suggest either you append("\n") as well or just record all the text you get without regard for new lines.
BTW Please don't use StringBuffer as its replacement StringBuilder has been around for almost ten years. There is a common misconception that using StringBuffer helps with multi-threading but more often it results in incorrect code because it is very harder, if not impossible to use StringBuffer correctly in a multi-threaded context
The following method doesn't capture the data sometimes. I believe it is because of the .ready() function.
We have hacked our way through it by doing a sleep, but I don't think it's full proof and seems like a bad hack.
Can you make suggestions on how to fix this method so it works when the request is fully read?
Thanks in advance
/**
* Parses a client request and calls the appropriate handler
* #throws Exception
*/
private void processClientRequest() throws Exception{
Socket connectedClient = null;
BufferedReader clientRequest = new BufferedReader(new InputStreamReader(connectedClient.getInputStream()));
System.out.println(clientRequest);
String requestString = clientRequest.readLine();
String header = requestString;
//Break up request
StringTokenizer tokenizer = new StringTokenizer(header);
//Different request parts
String httpMethod = tokenizer.nextToken();
String httpQueryString = tokenizer.nextToken();
//Print client request
StringBuffer responseBuffer = new StringBuffer();
//Sleep to bypass weird clientRequest.ready() error
if (httpMethod.equals("POST")) {
Thread.sleep(100);
}
while (clientRequest.ready()) {
responseBuffer.append(requestString + " ");
System.out.println(requestString);
requestString = clientRequest.readLine();
}
//Process GET request
if (httpMethod.equals("GET")) {
processGETRequests(httpQueryString, requestString);
}else if (httpMethod.equals("POST")) {
processPOSTRequests(responseBuffer, httpQueryString);
}
}
When you work with strings you have to always agree on encoding and never use defaults. In your
// use wathever charset encoding you know is pressent on the socket stream like UTF-8
new InputStreamReader(socket.getInputStream(), "US-ASCII")
You don't need to call the ready method, the method readLine() will block untill there is a new line to be read. Your while should be
while ((requestString = clientRequest.readLine()) != null) {
// ...
}
I am doing my first Android app and I have to take the code of a html page.
Actually I am doing this:
private class NetworkOperation extends AsyncTask<Void, Void, String > {
protected String doInBackground(Void... params) {
try {
URL oracle = new URL("http://www.nationalleague.ch/NL/fr/");
URLConnection yc = oracle.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
String s1 = "";
while ((inputLine = in.readLine()) != null)
s1 = s1 + inputLine;
in.close();
//return
return s1;
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
but the problem is it takes too much time. How to take for exemple the HTML from the line 200 to the line 300 ?
Sorry for my bad english :$
Best case use instead of readLine() use read(char[] cbuf, int off, int len). Another dirty way
int i =0;
while(while ((inputLine = in.readLine()) != null)
i++;
if(i>200 || i<300 )
DO SOMETHING
in.close();)
You get the HTML document through HTTP. HTTP usually relies on TCP. So... you can't just "skip lines"! The server will always try to send you all data preceding the portion of your interest, and your side of communication must acknowledge the reception of such data.
Do not read line by line [use read(char[] cbuf, int off, int len)]
Do not concat Strings [use a StringBuilder]
Open The buffered reader (much like you already do):
URL oracle = new URL("http://www.nationalleague.ch/NL/fr/");
BufferedReader in = new BufferedReader(new InputStreamReader(oracle.openStream()));
Instead of reading line by line, read in a char[] (I would use one of size about 8192)
and than use a StringBuilder to append all the read chars.
Reading secific lines of HTML-source seams a little risky because formatting of the source code of the HTML page may change.