Bufferedreaded ready method losing data - java

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) {
// ...
}

Related

Issue with String Buffer in java

I have a servlet in which the from InputStream I am getting the my form data in XML format. I am able to get retrieve the form data in XML format and able to write the same in file. If I open the file I am able to see my form data.
Now the issue is, When i try to append the form data to the string buffer it is not happening. I tried buffer.append(). After that method When I try to print the string buffer value nothing is showing/printing in the console.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("html/text");
PrintWriter out = response.getWriter();
out.println("doPost Method is excecuting");
DataInputStream in = new DataInputStream (request.getInputStream());
StringBuffer buffer = new StringBuffer();
File file = new File("reqOutput.txt");
file.createNewFile();
FileWriter writer = new FileWriter(file);
int value;
while ((value=in.read()) != -1) {
buffer.append(value);
writer.write(value);
}
System.out.println("Value is : "+ buffer.toString()); // Nothing is printing
writer.flush();
writer.close();
}
What's wrong with my code.Any suggestions please.
Here is your code modified to read from a file:
public static void main(final String[] args) throws Exception {
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("test"));
final StringBuilder sb = new StringBuilder();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
}
System.out.println("Value is : " + sb.toString());
} finally {
if (in != null) {
in.close();
}
}
}
I added a BufferedReader around the FileReader to optimize the reading.
I switched from reading one character at a time to reading line by line.
This also gives you the results as String so you don't have to convert the int.
Furthermore I added resource handling (pre-7 style and without exception handling) and switched to StringBuilder.
Output:
hello world! -> Value is : hello world!
I think there is another problem, not in this part of your code.
Additional comments on your code (not related to the question):
StringBuffer is a thread-safe implementation. If you have no need for this (like in your servlet example) you'd better use StringBuilder.
Don't close resources within the code block, use a try-finally (or since Java 7 try-with-resources) to guarantee resources are always closed, even when exceptions occur in the block somewhere.

get empty notification in production server

I develop a google glass app using mirror api. during development I used "Introspected tunnels to localhost" to receive the notification.
Now I uploaded my app on production server. So now I configure my callback URL as my domain name like https://www.mydomain.com:8443/notify. But I get empty notification.
in notify servlet:
BufferedReader notificationReader = new BufferedReader(
new InputStreamReader(request.getInputStream()));
String notificationString = "";
int lines = 0;
while (notificationReader.ready()) {
notificationString += notificationReader.readLine();
lines++;
if (lines > 1000) {
throw new IOException(
"Attempted to parse notification payload that was unexpectedly long.");
}
}
LOG.info("\ngot raw notification : " + notificationString);
in catalina.out
Feb 13, 2014 12:51:48 PM com.google.glassware.NotifyServlet doPost
INFO: got raw notification :
How can I solve it?
StringBuffer stringBuffer = new StringBuffer();
String line = "";
BufferedReader bufferReader = new BufferedReader(
new InputStreamReader(request.getInputStream()));
while ((line = bufferReader.readLine()) != null) {
stringBuffer.append(line);
}
notificationString = stringBuffer.toString();
Hope it will works.
I think you should use readLine() method.One of the answer from stack overflow suggest not using ready() for such requirements.
The ready method tells us if the Stream is ready to be read.
Imagine your stream is reading data from a network socket. In this
case, the stream may not have ended, because the socket has not been
closed, yet it may not be ready for the next chunk of data, because
the other end of the socket has not pushed any more data.
In the above scenario, we cannot read any more data until the remote
end pushes it, so we have to wait for the data to become available, or
for the socket to be closed. The ready() method tells us when the data
is available.
I had this same problem and I changed the code to look like this:
StringBuffer jb = new StringBuffer();
String notificationString = "";
String line = "";
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
jb.append(line);
}
notificationString = jb.toString();
Try This One:
while(notificationReader.ready()) {
notificationString = notificationString.concat(notificationReader.readLine());
lines++;
}

How to print out HTTP response and then exit

I am currently sending a request as shown below and was wanting to print out the response and exit. Is there a robust way of getting the whole response and then exiting, i.e., rather than breaking the loop after x lines or x seconds (which would have problematic cases)? Currently, the program never exits as the Scanner blocks waiting for more input. How else can I print out the response if not with some kind of loop/reader combination that might block?
public class PingHost {
public static void main(String[] args) throws Exception {
Socket s = new Socket("www.google.com", 80);
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeBytes("GET / HTTP/1.1\n\n");
Scanner sc = new Scanner(s.getInputStream());
while (sc.hasNext())
System.out.println(sc.nextLine());
System.out.println("never gets to here");
s.close();
}
}
I am not 100 percent sure what you wanna do here.
But if you wanna just get the html of the answering page and move on afterwards, then give this code sample a try:
/**
* Example call:<br>
* sendHTTPRequestAndSysoutData("http://www.google.com");
* #param target
*/
public static void sendHTTPRequestAndSysoutData(String target){
try{
URL my_url = new URL(target);
BufferedReader br = new BufferedReader(new InputStreamReader(my_url.openStream()));
String strTemp = "";
while (null != (strTemp = br.readLine())){
System.out.println(strTemp);
}
}
catch(IOException e){
e.printStackTrace();
}
}

"StringBuffer sb = new StringBuffer()" get a null value in Android

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

Building Java server and I can't get my page to stop loading (using PrintWriter and Buffered Reader)

I'm building a Java server and everything has been working as expected until now. I can serve up a static html page using two methods I wrote: body and header. Now, I am trying to write a new method called "bodywithQueryString".
Problem:
It almost works, but after the page is loaded, the loading won't stop. It just loads and loads. This is not happening with my static pages.
The only difference between the old method and new bodyWithQueryString() method is that in the new method I am using a buffered reader and print writer. These are new-ish functions for me so I'm guessing I'm not doing it right.
Here's how my new method is supposed to function:
I want to pass my route and querystring (queryarray) to bodyWithQueryString method. I want the method to read the file (from the route) to a byte output stream, do a replaceall on the key/value pair of the querystring while reading and, lastly, return the bytes. The getResponse() main method would then send the html to the browser.
Here's my code:
public void getResponse() throws Exception {
String[] routeParts = parseRoute(route); //break apart route and querystring
File theFile = new File(routeParts[0]);
if (theFile.canRead()) {
out.write(header( twoHundredStatusCode, routeParts[0], contentType(routeParts[0]) ) );
if (routeParts.length > 1) { //there must be a querystring
String[] queryStringArray = parseQueryString(routeParts[1]); //break apart querystring
out.write(bodyWithQueryString(routeParts[0], queryStringArray)); //use new body method
}
else out.write(body(routeParts[0])); //use original body method
out.flush();
private byte[] bodyWithQueryString(String route, String[] queryArray)
throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(route));
ByteArrayOutputStream fileOut = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(fileOut);
String line;
while ((line = reader.readLine()) != null) writer.println(line.replaceAll(queryArray[0] ,queryArray[1]));
writer.flush();
writer.close();
reader.close();
return fileOut.toByteArray();
}
It seems to me that you are not returning Content-Length header. This makes it hard for browser know when to stop loading the response.

Categories

Resources