cannot read arabic text from url in java - java

I've a web service that prints the following text.
[{"packid":"p101","title":"صفته 1","description":"شسیب: 1\r\nثق س: 50","linkfuntext":"funtext","linkshortstory":"short","linkfunpic":"pic","linkringtone":"ring","linkfungif":"gif","linkwallpaper":"wall","price":"500","buyid":"pack.fun.1","buyed":""},{"packid":"p102","title":"بسته صدا","description":" متن ها: 50\r\nصداها: 120\r\nتصاویر: 100\r\nتصاویر متحرک: 50\r\nداستان کوتاه: 20","linkfuntext":"","linkshortstory":"","linkfunpic":"","linkringtone":"","linkfungif":"","linkwallpaper":"","price":"1200","buyid":"fun.pack.2","buyed":""}]
When I try to read it in java I receive it in the following format
[{"packid":"p101","title":"صفته 1","description":"شسیب: 1\r\nثق س: 50","linkfuntext":"funtext","linkshortstory":"short","linkfunpic":"pic","linkringtone":"ring","linkfungif":"gif","linkwallpaper":"wall","price":"500","buyid":"pack.fun.1","buyed":""},{"packid":"p102","title":"بسته صدا","description":" متن ها: 50\r\nصداها: 120\r\nتصاویر: 100\r\nتصاویر متحرک: 50\r\nداستان کوتاه: 20","linkfuntext":"","linkshortstory":"","linkfunpic":"","linkringtone":"","linkfungif":"","linkwallpaper":"","price":"1200","buyid":"fun.pack.2","buyed":""}]
I've tried changing the character set to UTF-8 as well as ISO-8859-6 but still no luck. When I print the text on console it is printed correctly which means there is no issue in character set of eclipse or console. Also I've tried changing the character set of string that is storing the text, but same issue.
String serverOutput = new String(TEXT_FROM_SERVER.getBytes(), "UTF-8");
Here is my code that gets output from web service
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
String serverOutput = convertStreamToString(is);
private String convertStreamToString(InputStream is) {
Reader rd = null;
BufferedReader reader = null;
try {
rd = new InputStreamReader(is,"UTF-8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
reader = new BufferedReader(rd);
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append((line + "\n"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
Any kind of help will be greatly appreciated. Thanks

you need to unescape those HTML characters, and you can do so with a method from Apache Commons Lang called unescapeHtml. More info here.
Example:
String afterDecoding = StringEscapeUtils.unescapeHtml(beforeDecoding);

Related

How to write a binary file from a String and retrieve it again to a String?

I have a string and want to persist it into a file and be able to retrieve it again into a String.
Something is wrong with my code because It's supposing that I must write something binary non readable but when i Open the file I can read this:
Original string:
[{"name":"asdasd","etName":"111","members":[]}]
Stored string in binary file:
[ { " n a m e " : " a s d a s d " , " e t N a m e " : " 1 1 1 " , " m e m b e r s " : [ ] } ]
I detect two problems:
Is not stored in binary! I can read it. It's supposed to be a confused binary text unreadable but I can read it.
When i retrieve it it's being retrieved with that strange space between the characters. So it doesn't works.
This is my code for storing the string:
public static void storeStringInBinary(String string, String path) {
DataOutputStream os = null;
try {
os = new DataOutputStream(new FileOutputStream(path));
os.writeChars(string);
os.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
And this is my code for reading it from binary to a String:
public static String retrieveStringFromBinary(String file) {
String string = null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader (file));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
while((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
return stringBuilder.toString();
} catch (Exception e){
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return string;
}
Firstly, there isn't really a distinction between a text file and a binary file. A text file is just a file who's content falls in the range of byte values that correspond to characters.
If you want to encrypt the content of the file so it is unreadable just by catting the file then you will need to choose an appropriate encryption method.
Secondly Mixing Readers/Writers and Streams in Java is never a good idea, pick one style and stick to it.
The problem with your function that saves the string to a file is that you are using the writeChars() method, which from the doc does the following:
Writes a char to the underlying output stream as a 2-byte value, high byte first. If no exception is thrown, the counter written is incremented by 2.
Since your string is made up of single byte characters this is leading to the padding of your string with null bytes, which are being converted to spaces when read back in. If you change this to writeBytes() then you should get output without the extra null byte.
The null byte will also stop your read function working as the readLine() function will return null on it's first call due to the leading 0x00 in the file.
Try this out:
public static void storeStringInBinary(String string, String path) {
try(ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(path))) {
os.writeObject(string);
} catch (IOException e) {
e.printStackTrace();
}
}
public static String retrieveStringFromBinary(String file) {
String string = null;
try (ObjectInputStream reader = new ObjectInputStream(new FileInputStream(file))){
string = (String) reader.readObject();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return string;
}

Convert Clob to String

How can I get String out of Clob. I did google it, but
myClob.getSubString(0, (int) info.length()));
is the only thing I get. Console says:
java.sql.SQLException: Invalid argument(s) in call at
oracle.sql.CLOB.getSubString(CLOB.java:278) at
ru.tenet.es09.dao.CompanyDAOImpl.get(CompanyDAOImpl.java:72) at
ru.tenet.es09.dao.CompanyDAOImpl.getList(CompanyDAOImpl.java:132) at
ru.tenet.es09.dao.AddressDAOImpl.getList(AddressDAOImpl.java:59) at
ru.tenet.es09.Test.main(Test.java:11)
It points on getSubString() method. What is wrong?
Assuming you're using standard JDBC, once you have a ResultSet object you should be able to call ResultSet#getString("clob_field_name") to retrieve your CLOB data.
I know I'm late to this party!. Here is the one liner i used from hibernate library. If hibernate is already integrated to project then we can use annotations to convert clob to java String. In my case i had custom result transformer which read data from multiple tables after costly join. In the resultSetTransformer the below line does the job.
ClobType.INSTANCE.toString((Clob) tuple[2])
// org.hibernate.type.ClobType
this my way (sorry my english)
res = ps.executeQuery();
try {
while (res.next()) {
System.out.println(res.getClob(1));//confirm data
sRet = res.getString(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
ps.close();
}
Converting String to CLOB
SOobject.setLongStringField( new SerialClob(entityString.toCharArray()));//Converting String to CLOB
Convert Clob to String
public String getLongStringField() {
Reader reader = null;
BufferedReader bufferedReader = null;
try {
reader = longStringField.getCharacterStream();
bufferedReader = new BufferedReader(reader);
return IOUtils.toString(bufferedReader);
} catch (Exception e) {
throw new RuntimeException("Error while reading String from CLOB", e);
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(bufferedReader);
}
}
I have created a java method which can create string from a CLOB object:
public String clobToString(Clob data) {
StringBuilder sb = new StringBuilder();
try {
Reader reader = data.getCharacterStream();
BufferedReader br = new BufferedReader(reader);
String line;
while(null != (line = br.readLine())) {
sb.append(line);
}
br.close();
} catch (SQLException e) {
// handle this exception
} catch (IOException e) {
// handle this exception
}
return sb.toString();
}

Bing API error 1002

First of all I'm sorry for my English.
I am developing an application in java and I want to use search Bing API, So I opened user-centered development of Bing (http://www.bing.com/dev/en-us/dev-center) and accept key number then I wrote the following code to get results Bing
String q = "http://api.bing.net/json.aspx?Appid=MyClientId=girls&sources=web&web.count=40&web.offset=41";
URL searchURL;
try {
searchURL = new URL(q);
HttpURLConnection httpURLConnection = (HttpURLConnection) searchURL.openConnection();
if(httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
InputStreamReader inputStreamReader = new InputStreamReader(httpURLConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader, 8192);
String line = null;
String result = "";
while((line = bufferedReader.readLine()) != null){
result += line;
}
bufferedReader.close();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Why do I get the following error 1002?
{"SearchResponse":{
"Version":"2.2",
"Query":{"SearchTerms":"girls"},
"Errors":[
{"Code":1002,
"Message":"Parameter has invalid value.",
"Parameter":"SearchRequest.AppId",
"Value":"MyClientId",
"HelpUrl":"http:\/\/msdn.microsoft.com\/en-us\/library\/dd251042.aspx"}]
}}
It looks like you've got a typo in the address
This looks very suspicious:
Appid=MyClientId=girls
You should see the documentation http://msdn.microsoft.com/en-us/library/dd250882.aspx, but I guess that you need to replace the MyClientId with something and also you haven't spearated the query and the clientId i.e. &q=girls
EDIT: You need to get the AppId somewhere Steps of creating appid for bing search
Here's some question which can help you:
Bing search API and Azure

StringBuilder append cause out of memory

i am getting out of memory error in asynctask which loop to stringbuilder . My target for using this to download image from server and store inside my sd card.My code as below :
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httppost = new HttpPost(severPath);
httppost.setEntity(params[0]);
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = null;
try {
response = httpclient.execute(httppost);
} catch (ClientProtocolException e6) {
// TODO Auto-generated catch block
e6.printStackTrace();
} catch (IOException e6) {
// TODO Auto-generated catch block
e6.printStackTrace();
}
String output;
System.out.println("Output from Server .... \n");
BufferedReader br = null;
try {
br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
} catch (IllegalStateException e5) {
// TODO Auto-generated catch block
e5.printStackTrace();
} catch (IOException e5) {
// TODO Auto-generated catch block
e5.printStackTrace();
}
OutputStreamWriter outputStreamWriter = null;
try {
outputStreamWriter = new OutputStreamWriter(context.openFileOutput("LargeImages.txt", context.MODE_PRIVATE));
} catch (FileNotFoundException e6) {
// TODO Auto-generated catch block
e6.printStackTrace();
}
int i = 0;
StringBuilder builder = new StringBuilder();
String Result = "";
try {
for (String line = null; (line = br.readLine()) != null ; ) {
builder.append(line.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputStreamWriter.close();
i am getting out of memory allocation error. please help. i try many method but also not getting the right.
if you are downloading an image, then you should not use Reader/Writer/StringBuilder to store it's content. Because the file is binary content will be scrambled because of the character encoding used by Reader/Writer classes.
Try using InputStream/OutputStream and store the content directly to sdcard without storing it in memory.
Try out the below code:
InputStream in = response.getEntity().getContent();
OutputStream out = context.openFileOutput("LargeImages.txt", context.MODE_PRIVATE);
byte b[] = new byte[4096];
int i;
while ((i = in.read(b)) >= 0) {
out.write(b, 0, i);
}
There may be two problems.
The first - the cycle for (String line = null; (line = br.readLine()) != null ; ) is not terminated properly. Try to find it out by opening a small file(e.g. with 10 lines total).
The second - it's actually a memory insufficient case. Probably it's not the best idea to get image via strings as images may be very heavy and creating a plenty of Strings causes natural memory error. Try to find another approach.
I don't see code that is actually writing to the output stream. Shouldn't there be a line before the close, that is like outputStreamWriter.print(builder)?
About your question. Instead of collecting the whole data in memory in a StringBuilder and than write it at once, you should write directly each line you get within your for-loop. You don't need the StringBuilder at all. Here's a code snippet:
try {
for (String line = br.readLine(); line != null; line = br.readLine()) {
outputStreamWriter.append(line);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
Three more remarks:
When you get an Exception you should also stop the action, e.g. return from your method. Your code above would print the Stacktrace (which is definitely helpful) but would then continue, which would be not so helpful. Just add return after each printstackTrace.
There's still a chance that one line is too long for memory, but the risk is minimized.
Is the data you download binary image or text? You name it image but you download text. Please be aware that there's a difference between bytes and characters (encoded with character set) and stay within what you actually receive.

OutOfMemoryError while JSON parsing in android

I am using the below code to parse the JSON String fetched from Web, (30,000 records)
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost(params[0]);
httppost.setHeader("Content-type", "application/json");
InputStream inputStream = null;
String result = null;
HttpResponse response = null;
try {
response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
try {
inputStream = entity.getContent();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"),8);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
result = sb.toString();
I am getting the OutofMemory error in the below code
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
How to get rid of this error.This error does occur when the json string is very huge as it contains data of about 30,000 records.
Any help in this regard is highly appreciated..
Android imposes a memory cap limit (of 16 MB in almost all phones, with some newer tablets have more) for each and every application. Application should make sure they maintain their live memory limit below that level.
So we can't hold a big string, say over 1MB, in full sometimes since the total live memory usage of applicaiton may exceed that limit. Remember, the total memory usage includes all objects (including UI elements) we allocated in our app.
So your only solution is to use a Streaming JSON parser, which takes data as it comes. That is you should not hold on full string in a String object. One option is to use Jackson JSON parser.
EDIT : Android now support JSONReader from API level 11. Never used it, but it seems the way to go..
If data file is too large, you cannot read it all to memory.
Read a line and then write it to a native file. Do not use a StringBuilder to hold all data in memory.
Try to import your data in chuncks, like 1000 records each time. Hopefully you will not experince this issue.
I solved this problem with this library.
There is a very good tutorial here.
With this you will bypass converting entity.getContent() to String and that will solve your problem.
InputStream inputStream = entity.getContent();
JsonReader reader = Json.createReader(inputStream);
JsonObject jsonObject = reader.readObject();
return jsonObject;

Categories

Resources