Write an array response from servlet to JavaScript? - java

I am trying to write a single Array object using PrintWriter.out.write() as a response to a JavaScript (AJAX) function,
Is this possible? or will I need to convert the array in same manner before sending?
Trying to avoid creation of comma separated String and then parsing in JS
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.write(listDir());
}
private File[] listDir(){
File folder = new File("/home/rob/");
File[] listOfFiles = folder.listFiles();
//System.out.println("Number of files found: " + listOfFiles.length);
return listOfFiles;
}
Would like to then iterate through the files within the calling JavaScript AJAX function:
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
for (var i = 0; i < xmlhttp.responseText.length; i++) {
alert(xmlhttp.responseText[i]);
}
}

Java's array objects don't have an implementation of toString() method. As such, your output from
out.write(listDir());
will look something like
[Ljava.io.File;#5d9d277e
You definitely don't want this. There are many ways to serialize arrays. One of these is to separate the elements by ,
out.write(Arrays.toString(listDir()));
gives you something like
[some.txt, other.png]
Other formats include JSON and XML. Since Javascript comes with a built-in JSON parser, I would suggest you use JSON. You can find a Java JSON library here. Change the content-type if you return something like JSON (ex. application/json).

Related

generating csv file java download on the fly [duplicate]

I am facing a problem in exporting my data to excel sheet, this is because of some code which other developers in my team made. So the main problem is to export the data to Excel or .cvs using JSP page but without using any HTML code.
Any suggestion would also help me to explore in my developing arena. Thanks for your efforts.
Better use a Servlet for this. Raw Java code doesn't belong in a JSP file, that's simply recipe for maintenance trouble.
To start, create a simple Java utility class which takes for example a List<List<T>> or a List<Data> (wherein Data represents one row) representing the CSV contents and an OutputStream as method arguments and write logic which does the data copying task.
Once you get that to work, create a Servlet class which takes some CSV file identifier as request parameter or pathinfo (I recommend using pathinfo as a certain webbrowser developed by a team in Redmond would fail on detection of filename/mimetype otherwise), uses the identifier to get the List<List<T>> or List<Data> from somewhere and writes it to the OutputStream of the HttpServletResponse along a set of correct response headers.
Here's a basic kickoff example:
public static <T> void writeCsv (List<List<T>> csv, char separator, OutputStream output) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
for (List<T> row : csv) {
for (Iterator<T> iter = row.iterator(); iter.hasNext();) {
String field = String.valueOf(iter.next()).replace("\"", "\"\"");
if (field.indexOf(separator) > -1 || field.indexOf('"') > -1) {
field = '"' + field + '"';
}
writer.append(field);
if (iter.hasNext()) {
writer.append(separator);
}
}
writer.newLine();
}
writer.flush();
}
Here's an example how you could use it:
public static void main(String[] args) throws IOException {
List<List<String>> csv = new ArrayList<List<String>>();
csv.add(Arrays.asList("field1", "field2", "field3"));
csv.add(Arrays.asList("field1,", "field2", "fie\"ld3"));
csv.add(Arrays.asList("\"field1\"", ",field2,", ",\",\",\""));
writeCsv(csv, ';', System.out);
}
And inside a Servlet you can basically do:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getPathInfo();
List<List<Object>> csv = someDAO().list();
response.setHeader("content-type", "text/csv");
response.setHeader("content-disposition", "attachment;filename=\"" + filename + "\"");
writeCsv(csv, ',', response.getOutputStream());
}
Map this servlet on something like /csv/* and invoke it as something like http://example.com/context/csv/filename.csv. That's basically all. The filename in the pathinfo is important because a certain webbrowser developed by a team in Redmond ignores the filename part of the Content-Disposition header and uses the last path part of the URL instead.

Generate ImapMessage from Response Object

I've created a custom command to retrieve multiple objects in the same request (in order to solve some performance issues), instead of using the folder method .getMessage(..) which in my case retrieved an ImapMessage object:
Argument args = new Argument();
args.writeString(Integer.toString(start) + ":" + Integer.toString(end));
args.writeString("BODY[]");
FetchResponse fetch;
BODY body;
MimeMessage mm;
ByteArrayInputStream is = null;
Response[] r = protocol.command("FETCH", args);
Response status = r[r.length-1];
if(status.isOK()) {
for (int i = 0; i < r.length - 1; i++) {
...
}
}
Currently I'm validating if the object is a ImapResponse like this:
if (r[i] instanceof IMAPResponse) {
IMAPResponse imr = (IMAPResponse)r[i];
My question is, how can I turn this response into an ImapMessage?
Thank you.
Are you trying to download the entire message content for multiple messages at once? Have you tried using IMAPFolder.FetchProfileItem.MESSAGE? That will cause Folder.fetch to download the entire message content, which you can then access using the Message objects.
I haven't succeeded yet to convert it into a IMAPMessage but I'm now able transform it into a MIME Message. It isn't perfect but I guess it will have to work for now:
FetchResponse fetch = (FetchResponse) r[i];
BODY body = (BODY) fetch.getItem(0);
ByteArrayInputStream is = body.getByteArrayInputStream();
MimeMessage mm = new MimeMessage(session, is);
Then, it can be used to get information like this:
String contentType = mm.getContentType();
Object contentObject = mm.getContent();
There are also other methods to get information like the sender, date, etc.

Unicode strings from Java to Javascript via JSON

In a Java servlet I'm doing:
protected void handleRequests(HttpServletRequest request, HttpServletResponse response)
PrintWriter pw = response.getWriter();
/*...*/
Vector<String> buf = new Vector<>();
for(...) {
ret.add(">žd¿ [?²„·ÜðÈ ‘");
}
/*JSONArray*/ responseArray.put(responseArray.length(), buf);
/*...*/
pw.println(responseArray);
pw.close();
}
In a web page client javascript I'm doing a XMLHttpRequest and the reply is incorrect, looks like: >?d¿ [\u001a?²\u201e·ÜðÈ \u2018
(for the above >žd¿ [?²„·ÜðÈ ‘ input)
Then I tried on the servlet:
ret.add(URLEncoder.encode(">žd¿ [?²„·ÜðÈ ‘", "UTF-8"));
and I get:
%3E%C5%BEd%C2%BF%C2%A0%5B%7F%1A%3F%C2%B2%E2%80%9E%C2%B7%C3%9C%C3%B0%C3%88%C2%A0%E2%80%98
in javascript, then I apply:
unescape(reply.replace(/\+/g,' ') (the replace is because + signs are not converted to spaces)
which nets me:
>žd¿ [?²â??·Ã?ðÃ? â
What do I do wrong?
(Some other questions tells me the servlet should send as utf8. But when do I encode in utf8 - before placing inside a JSON object (I use org.json.) or after (with a .toString on the JSON response array and then convert to utf8 before PrintWriter.println)
P.S. This is not all my code, I've inherited it and some of the theoretical background I'm lacking.
Edit:
doing a decodeURIComponent(reply).replace(/\+/g,' ') in javascript seems to do the trick. But I could not find the difference between URLEncoder.encode and decodeURIComponent. Is the +/space the only mismatch?
decodeURIComponent nets the expected result
decodeURIComponent("%3E%C5%BEd%C2%BF%C2%A0%5B%7F%1A%3F%C2%B2%E2%80%9E%C2%B7%C3%9C%C3%B0%C3%88%C2%A0%E2%80%98");
">žd¿ [?²„·ÜðÈ ‘"

UTF-8 Encoding in java, retrieving data from website

I'm trying to get data from website which is encoded in UTF-8 and insert them into the database (MYSQL). Database is also encoded in UTF-8.
This is the method I use to download data from specific site.
public String download(String url) throws java.io.IOException {
java.io.InputStream s = null;
java.io.InputStreamReader r = null;
StringBuilder content = new StringBuilder();
try {
s = (java.io.InputStream)new URL(url).getContent();
r = new java.io.InputStreamReader(s, "UTF-8");
char[] buffer = new char[4*1024];
int n = 0;
while (n >= 0) {
n = r.read(buffer, 0, buffer.length);
if (n > 0) {
content.append(buffer, 0, n);
}
}
}
finally {
if (r != null) r.close();
if (s != null) s.close();
}
return content.toString();
}
If encoding is set to 'UTF-8' (r = new java.io.InputStreamReader(s, "UTF-8"); ) data inserted into database seems to look OK, but when I try to display it, I am getting something like this: C�te d'Ivoire, instead of Côte d'Ivoire.
All my websites are encoded in UTF-8.
Please help.
If encoding is set to 'windows-1252' (r = new java.io.InputStreamReader(s, "windows-1252"); ) everything works fine and I am getting Côte d'Ivoire on my website (), but in java this title looks like 'C?´te d'Ivoire' what breaks other things, such as for example links. What does it mean ?
I would consider using commons-io, they have a function doing what you want to do:link
That is replace your code with this:
public String download(String url) throws java.io.IOException {
java.io.InputStream s = null;
String content = null;
try {
s = (java.io.InputStream)new URL(url).getContent();
content = IOUtils.toString(s, "UTF-8")
}
finally {
if (s != null) s.close();
}
return content.toString();
}
if that nots doing start looking into if you can store it to file correctly to eliminate the possibility that your db isn't set up correctly.
Java
The problem seems to lie in the HttpServletResponse , if you have a servlet or jsp page. Make sure to set your HttpServletResponse encoding to UTF-8.
In a jsp page or in the doGet or doPost of a servlet, before any content is sent to the response, just do :
response.setCharacterEncoding("UTF-8");
PHP
In PHP, try to use the utf8-encode function after retrieving from the database.
Is your database encoding set to UTF-8 for both server, client, connection and have the tables been created with that encoding? Check 'show variables' and 'show create table <one-of-the-tables>'
If encoding is set to 'UTF-8' (r = new java.io.InputStreamReader(s, "UTF-8"); ) data inserted into database seems to look OK, but when I try to display it, I am getting something like this: C�te d'Ivoire, instead of Côte d'Ivoire.
Thus, the encoding during the display is wrong. How are you displaying it? As per the comments, it's a PHP page? If so, then you need to take two things into account:
Write them to HTTP response output using the same encoding, thus UTF-8.
Set content type to UTF-8 so that the webbrowser knows which encoding to use to display text.
As per the comments, you have apparently already done 2. Left behind 1, in PHP you need to install mb_string and set mbstring.http_output to UTF-8 as well. I have found this cheatsheet very useful.

JSP page without HTML code for exporting data to Excel Sheet

I am facing a problem in exporting my data to excel sheet, this is because of some code which other developers in my team made. So the main problem is to export the data to Excel or .cvs using JSP page but without using any HTML code.
Any suggestion would also help me to explore in my developing arena. Thanks for your efforts.
Better use a Servlet for this. Raw Java code doesn't belong in a JSP file, that's simply recipe for maintenance trouble.
To start, create a simple Java utility class which takes for example a List<List<T>> or a List<Data> (wherein Data represents one row) representing the CSV contents and an OutputStream as method arguments and write logic which does the data copying task.
Once you get that to work, create a Servlet class which takes some CSV file identifier as request parameter or pathinfo (I recommend using pathinfo as a certain webbrowser developed by a team in Redmond would fail on detection of filename/mimetype otherwise), uses the identifier to get the List<List<T>> or List<Data> from somewhere and writes it to the OutputStream of the HttpServletResponse along a set of correct response headers.
Here's a basic kickoff example:
public static <T> void writeCsv (List<List<T>> csv, char separator, OutputStream output) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
for (List<T> row : csv) {
for (Iterator<T> iter = row.iterator(); iter.hasNext();) {
String field = String.valueOf(iter.next()).replace("\"", "\"\"");
if (field.indexOf(separator) > -1 || field.indexOf('"') > -1) {
field = '"' + field + '"';
}
writer.append(field);
if (iter.hasNext()) {
writer.append(separator);
}
}
writer.newLine();
}
writer.flush();
}
Here's an example how you could use it:
public static void main(String[] args) throws IOException {
List<List<String>> csv = new ArrayList<List<String>>();
csv.add(Arrays.asList("field1", "field2", "field3"));
csv.add(Arrays.asList("field1,", "field2", "fie\"ld3"));
csv.add(Arrays.asList("\"field1\"", ",field2,", ",\",\",\""));
writeCsv(csv, ';', System.out);
}
And inside a Servlet you can basically do:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getPathInfo();
List<List<Object>> csv = someDAO().list();
response.setHeader("content-type", "text/csv");
response.setHeader("content-disposition", "attachment;filename=\"" + filename + "\"");
writeCsv(csv, ',', response.getOutputStream());
}
Map this servlet on something like /csv/* and invoke it as something like http://example.com/context/csv/filename.csv. That's basically all. The filename in the pathinfo is important because a certain webbrowser developed by a team in Redmond ignores the filename part of the Content-Disposition header and uses the last path part of the URL instead.

Categories