My code reads from http connection and puts the data into an ByteArrayOutputStream.
The http data content has the first row with the update date/time and then the other data.
Example of data received from http url:
2012-03-02 03:06:34
text1
text2
text3
I have found this:
InputStream content = response.getEntity().getContent();
byte[] buffer = new byte[1024];
int numRead = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((numRead=content.read(buffer))!=-1){
baos.write(buffer, 0, numRead);
}
content.close();
String result = new String(baos.toByteArray());
How can I use the first row ("2012-03-02 03:06:34") and then the others row?
I'll think to use an array of strings and get the first row with baos[0] and the others with
for (int i=1;i<baos.length;i++) {...}
How I can?
Thanks.
my english is very ugly :-o
What you have works more on a byte-at-a-time level.
Try this for a line at a time:
InputStream is = response.getEntity().getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while((line = br.readLine()) != null)
{
//Do something with each line
}
Related
How to read an InputStream twice if I am using ReadableByteChannel and BufferedReader?
Here is my code:
ReadableByteChannel inputChannel = Channels.newChannel(input);
WritableByteChannel outputChannel = Channels.newChannel(output);
InputStream ind = Channels.newInputStream(inputChannel);
ReadableByteChannel inputChannel1 = Channels.newChannel(ind);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
org.apache.commons.io.IOUtils.copy(ind, baos);
ByteBuffer buffer = ByteBuffer.allocateDirect(10240);
long size = 0;
while (inputChannel1.read(buffer) != -1) {
buffer.flip();
size += outputChannel.write(buffer);
buffer.clear();
}
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
BufferedReader in = new BufferedReader(new InputStreamReader(bais));
String inputLine;
StringBuffer bufferResponse = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
bufferResponse.append(inputLine);
}
JSONObject jsonResponse = new JSONObject(bufferResponse.toString());
You've written a lot of code to copy input to two destinations: output and jsonResponse. As you have made an in-memory copy of input => bytes there is no need to scan input twice, and you don't need to use IOUtils for a simple copy to byte[] which you can re-use to send to the two destinations:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
input.transferTo(baos);
byte[] bytes = baos.toByteArray();
output.write(bytes);
Then do as #g00se suggests - if the char encoding is platform default:
String s = new String(bytes /*, or insert another charset here */);
JSONObject jsonResponse = new JSONObject(s);
You should also deal with closing the input/output streams, best done with try-with-resources block.
There is client and server components, the client is sending the data in more secure way by converting the data in blob using POST method to the server.
Can any suggest me how to convert that blob data to string object in server side(Java).i have tried some code below
Way 1):
==============================
String streamLength = request.getHeader("Content-Length");
int streamIntLength = Integer.parseInt(streamLength);
byte[] bytes = new byte[streamIntLength];
request.getInputStream().read(bytes, 0, bytes.length);
String content = DatatypeConverter.printBase64Binary(bytes);
System.out.println(content);
Output for above code is : some junk data is displaying.
dABlAG0AcABsAGEAdABlAD0AMgAzADUAUgBfAFAAcgBvAHYAaQBkAGUAcgBfA
Way 2) :
======
BufferedReader reader = new BufferedReader(new InputStreamReader(
request.getInputStream()));
StringBuilder sb = new StringBuilder();
for (String line; (line = reader.readLine()) != null;) {
String str = new String(line.getBytes());
System.out.println(str);
}
Please suggest me any one, above both ways are not worked out.
Below code works for me.
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
String streamLength = request.getHeader("Content-Length");
int streamIntLength = Integer.parseInt(streamLength);
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(
inputStream));
char[] charBuffer = new char[streamIntLength];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
}
String body = stringBuilder.toString();
//System.out.println(body);
byte[] bytes = body.getBytes();
System.out.println(StringUtils.newStringUtf16Le(bytes));
From the first approach, it looks like the data is encoded (possibly in Base64 format). After decoding it, what is the problem you are facing ? If the data is String and then encoded to Base64, you should get the actual string after decoding it. (Assuming platform locales on client and server side are same).
If its a binary data, better you keep it inside a byte stream only. If you anyhow want it to convert to a string, then the first approach looks okay.
If this binary data represents some kind of file, you can get the related information using the HTTP headers and write it to temp location for further use.
I'm trying to read an XML file and send to the local server using HttpPost. When reading the data at the server side and writing into a file always last few lines are missing.
Client code :
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://xxx.xxx.xxx.xxx:yyyy/FirstServlet/HelloWorldServlet");
InputStreamEntity reqEntity = new InputStreamEntity(
new FileInputStream(dataFile), -1);
reqEntity.setContentType("binary/octet-stream");
// Send in multiple parts if needed
reqEntity.setChunked(true);
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
int respcode = response.getStatusLine().getStatusCode();
Server code :
response.setContentType("binary/octet-stream");
InputStream is = request.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Files\\copyFile.xml")));
byte[] buf = new byte[4096];
for (int nChunk = is.read(buf); nChunk!=-1; nChunk = is.read(buf))
{
bos.write(buf, 0, nChunk);
}
I tried using BufferedReader as well, but same issue.
BufferedReader in = new BufferedReader(
new InputStreamReader(request.getInputStream()));
response.setContentType("binary/octet-stream");
String line = null;
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Files\\copyFile.xml")));
while((line = in.readLine()) != null) {
line = in.readLine();
bos.write((line + "\n").getBytes());
}
I tried using scanner as well. In this case it's working fine only when I use StringBuilder and passing the value again to the BufferedOutputStream.
response.setContentType("binary/octet-stream");
StringBuilder stringBuilder = new StringBuilder(2000);
Scanner scanner = new Scanner(request.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Files\\copyFile.xml")));
while (scanner.hasNextLine()) {
stringBuilder.append(scanner.nextLine() + "\n");
}
String tempStr = stringBuilder.toString();
bos.write(tempStr.getBytes());
I can't use the above logic for processing very large XML's since converting to string value will throw Java heap space error.
Kindly let me know what is the issue with the code?
Thanks in advance!
flush() and close() your output streams. what happens is that youre not flushing and the last few lines remain in some internal buffer and are not written out.
so in your server code:
response.setContentType("binary/octet-stream");
InputStream is = request.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Files\\copyFile.xml")));
byte[] buf = new byte[4096];
for (int nChunk = is.read(buf); nChunk!=-1; nChunk = is.read(buf)) {
bos.write(buf, 0, nChunk);
}
bos.flush();
bos.close();
servelt code
System.out.println(" ================servlet==================");
InputStream in = request.getInputStream();
int a = in.available();
byte[] b = new byte[a];
in.read(b);
String stringValue = new String(b,"utf-8");
System.out.println("receive data==="+stringValue);
OutputStream dataOut = response.getOutputStream();
String responseData = "<test>test</test>";
System.out.println("response datea==="+responseData);
dataOut.write(responseData.getBytes("utf-8"));
dataOut.flush();
dataOut.close();
client code
System.out.println("================client======================");
java.net.URL url = new java.net.URL("test address");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setUseCaches(false);
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestMethod("POST");
String sendData = "<data>send</data>";
System.out.println("send data="+sendData);
OutputStream dataOut = con.getOutputStream();
dataOut.write(sendData.getBytes("utf-8"));
dataOut.flush();
dataOut.close();
InputStream in = con.getInputStream();
int a = in.available();
byte[] b = new byte[a];
in.read(b);
String stringValue = new String(b,"utf-8");
in.close();
System.out.println("receive data="+stringValue);
I get the print results
servlet console
================servlet==================
receive data===
response datea===test
client console
================client======================
send data=<data>send</data>
receive data=<test>test</test>
My question is that servlet can't receive the data from the client
who can help me?
My question is that servlet can't receive the data from the client
It may not be the only problem, but this code is completely broken:
int a = in.available();
byte[] b = new byte[a];
in.read(b);
You're assuming that all the data is available right at the start. You should instead be reading from the stream until it runs out of data. Given that you want the result as text, I'd wrap the stream in an InputStreamReader and read from there. For example:
BufferdReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Servlet read line: " + line);
}
If you actually want to read it as XML, you should be able to pass the InputStream (or Reader) to an XML parser library to create a DOM.
You should be doing the same thing in the client code too, by the way. Basically:
Never ignore the return value of InputStream.read
Avoid using available(); it's rarely appropriate
Use an InputStreamReader to read text from a stream, rather than constructing it yourself from the bytes
Use an XML API to read XML rather than handling it as raw text
As of now I can see that the value of int b is 0 so it is not reading any data from the input stream.
According to this documentation
available
will always return 0 for InputStream which has been extended byt the
ServletInputStream.
As told by Jon or
Edit:
InputStream is=request.getInputStream();
OutputStream os=response.getOutputStream();
byte[] buf = new byte[1024];
int chunk = is.read(buf);
In PHP we can use file_get_contents() like this:
<?php
$data = file_get_contents('php://input');
echo file_put_contents("image.jpg", $data);
?>
How can I implement this in Java (JSP)?
Here's a function I created in Java a while back that returns a String of the file contents. Hope it helps.
There might be some issues with \n and \r but it should get you started at least.
// Converts a file to a string
private String fileToString(String filename) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(filename));
StringBuilder builder = new StringBuilder();
String line;
// For every line in the file, append it to the string builder
while((line = reader.readLine()) != null)
{
builder.append(line);
}
reader.close();
return builder.toString();
}
This will read a file from an URL and write it to a local file. Just add try/catch and imports as needed.
byte buf[] = new byte[4096];
URL url = new URL("http://path.to.file");
BufferedInputStream bis = new BufferedInputStream(url.openStream());
FileOutputStream fos = new FileOutputStream(target_filename);
int bytesRead = 0;
while((bytesRead = bis.read(buf)) != -1) {
fos.write(buf, 0, bytesRead);
}
fos.flush();
fos.close();
bis.close();