HttpUrlConnection setting Range in Android is ignored - java

I'm trying get a 206 response from my server using Android.
Here's the code.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL("http://aviddapp.com/10mb.file");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("Range", "bytes=1-2");
urlConnection.connect();
System.out.println("Response Code: " + urlConnection.getResponseCode());
System.out.println("Content-Length: " + urlConnection.getContentLength());
Map<String, List<String>> map = urlConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() +
" ,Value : " + entry.getValue());
}
InputStream inputStream = urlConnection.getInputStream();
long size = 0;
while(inputStream.read() != -1 )
size++;
System.out.println("Downloaded Size: " + size);
}catch(MalformedURLException mue) {
mue.printStackTrace();
}catch(IOException ioe) {
ioe.printStackTrace();
}
return null;
}
}.execute();
}
Here's the output:
I/System.out: Respnse Code: 200
I/System.out: Content-Length: -1
I/System.out: Key : null ,Value : [HTTP/1.1 200 OK]
I/System.out: Key : Accept-Ranges ,Value : [bytes]
I/System.out: Key : Cache-Control ,Value : [max-age=604800, public]
I/System.out: Key : Connection ,Value : [Keep-Alive]
I/System.out: Key : Date ,Value : [Tue, 04 Oct 2016 07:45:22 GMT]
I/System.out: Key : ETag ,Value : ["a00000-53e051f279680-gzip"]
I/System.out: Key : Expires ,Value : [Tue, 11 Oct 2016 07:45:22 GMT]
I/System.out: Key : Keep-Alive ,Value : [timeout=5, max=100]
I/System.out: Key : Last-Modified ,Value : [Tue, 04 Oct 2016 07:36:42 GMT]
I/System.out: Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4]
I/System.out: Key : Transfer-Encoding ,Value : [chunked]
I/System.out: Key : Vary ,Value : [Accept-Encoding,User-Agent]
I/System.out: Key : X-Android-Received-Millis ,Value : [1475567127403]
I/System.out: Key : X-Android-Response-Source ,Value : [NETWORK 200]
I/System.out: Key : X-Android-Sent-Millis ,Value : [1475567127183]
I/System.out: Downloaded Size: 10485760
Now I'm doing the same thing is pure java.
public static void main(String... args) {
try {
URL url = new URL("http://aviddapp.com/10mb.file");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("Range", "bytes=1-2");
urlConnection.connect();
System.out.println("Respnse Code: " + urlConnection.getResponseCode());
System.out.println("Content-Length: " + urlConnection.getContentLength());
Map<String, List<String>> map = urlConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() +
" ,Value : " + entry.getValue());
}
InputStream inputStream = urlConnection.getInputStream();
long size = 0;
while(inputStream.read() != -1 )
size++;
System.out.println("Downloaded Size: " + size);
}catch(MalformedURLException mue) {
mue.printStackTrace();
}catch(IOException ioe) {
ioe.printStackTrace();
}
}
Here's the output
Respnse Code: 206
Content-Length: 2
Key : Keep-Alive ,Value : [timeout=5, max=100]
Key : null ,Value : [HTTP/1.1 206 Partial Content]
Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4]
Key : Content-Range ,Value : [bytes 1-2/10485760]
Key : Connection ,Value : [Keep-Alive]
Key : Last-Modified ,Value : [Tue, 04 Oct 2016 07:36:42 GMT]
Key : Date ,Value : [Tue, 04 Oct 2016 07:42:17 GMT]
Key : Accept-Ranges ,Value : [bytes]
Key : Cache-Control ,Value : [max-age=604800, public]
Key : ETag ,Value : ["a00000-53e051f279680"]
Key : Vary ,Value : [Accept-Encoding,User-Agent]
Key : Expires ,Value : [Tue, 11 Oct 2016 07:42:17 GMT]
Key : Content-Length ,Value : [2]
Downloaded Size: 2
As you can see I'm getting diffrent response codes in both cases. It seems like Android is not passing Range to the server maybe? What's happening here?
PS: I'm getting a 206 if the file size is 1mb.

I am relatively certain the error is not in the Android code.
It looks like the server might be delivering spurious results.
You can check with a third party tool (such as Postman) to determine the headers that web service is delivering.
My results using Postman. As you can see, it is delivering HTTP 200 (not 206). It is also not wending a capped Content-Length. If the server is yours, perhaps check that it is configured correctly. Also check your code with other servers.

Hi Can u try this piece of code, it seems i am getting HTTP 206 here.
new Thread() {
#Override
public void run() {
try {
URL url = new URL("http://aviddapp.com/10mb.file");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
// urlConnection.setRequestMethod("HEAD");
urlConnection.setRequestProperty("Accept-Encoding", "");
urlConnection.setRequestProperty("Range", "bytes=1-2");
urlConnection.connect();
System.out.println("Response Code: " + urlConnection.getResponseCode());
System.out.println("Content-Length: " + urlConnection.getContentLength());
Map<String, List<String>> map = urlConnection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() +
" ,Value : " + entry.getValue());
}
InputStream inputStream = urlConnection.getInputStream();
long size = 0;
while (inputStream.read() != -1)
size++;
System.out.println("Downloaded Size: " + size);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}.start();
You just have to add this in async task.
Check this result commenting on/off this line.
urlConnection.setRequestProperty("Accept-Encoding", "");

I am not sure if this is related to Content-Length being cleared by android implementation by default. Look at the below snippet from the source code where it says it does gzip compression by default.
https://android.googlesource.com/platform/libcore/+/2e317a02b5a8f9b319488ab9311521e8b4f87a0a/luni/src/main/java/java/net/HttpURLConnection.java
By default, this implementation of HttpURLConnection
requests that servers use gzip compression and it automatically
decompresses the data for callers of getInputStream(). The
Content-Encoding and Content-Length response headers are cleared in
this case.
Can you try disabling the default caching using below code to check if that works?
urlConnection.setRequestProperty("Accept-Encoding", "identity");
PS: Sorry for bad formattings. Using the mobile version of SO.

Have you tried like that:
urlConnection.setRequestProperty("Range", "bytes=1000-");

Related

Not able to receive Set-Cookie field using RestTemplate

I am trying two ways to POST on a url and everything is working fine except in one field.
If i am using HttpConnection i am receiving Set-Cookie field as output.
JSONObject json = new JSONObject();
json.put("username", "1010101010");
json.put("password", "11two33");
String loginContent = json.toString();
int timeOut = 100000;
String authLoginUrl = "http://localhost:8080/api/login";
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json");
HttpExternalService httpService = new HttpExternalService();
HttpExResponseDetails exResponse = httpService.sendRequest(authLoginUrl, loginContent, HttpMethod.POST, timeOut,
headers, null, null, true, true, true, false, null);
Map<String, List<String>> rsHeaders = exResponse.getResponseHeaderMap();
for(Entry<String, List<String>> e: rsHeaders.entrySet()){
System.out.println("Key: "+e.getKey());
List<String> valueList = e.getValue();
for(String str: valueList){
System.out.println("Value: "+str);
}
}
That is one field that is coming in the output:
OUTPUT:
Key: Transfer-Encoding
Value: chunked
Key: null
Value: HTTP/1.1 200 OK
Key: Server
Value: Jetty(9.2.16.v20160414)
Key: X-Content-Type-Options
Value: nosniff
Key: Pragma
Value: no-cache
Key: X-Application-Context
Value: gateway:8080
Key: Date
Value: Wed, 13 Jul 2016 14:08:55 GMT
Key: Via
Value: 1.1 d.eze.cc
Key: X-Frame-Options
Value: DENY
Key: Cache-Control
Value: no-cache, no-store, max-age=0, must-revalidate
Key: Vary
Value: Accept-Encoding
Key: Set-Cookie
Value: jsessionid=c5bcc245-e18e-4320-8ac2-08b3e51dcae7;Path=/api/;HttpOnly
Key: Expires
Value: Thu, 01 Jan 1970 00:00:00 GMT
Key: X-XSS-Protection
Value: 1; mode=block
Key: Content-Type
Value: application/json; charset=UTF-8
But if i am using RestTemplate for hitting the same url i am not receiving any Set-Cookie field which is a strange behaviour.
Map<String, String> json = new HashMap<String, String>();
json.put("username", "1010101010");
json.put("password", "11two33");
Map<String, String> headers = new HashMap<String, String>();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json");
ResponseEntity<ApiOutput> out = WebServiceCaller.postServiceCall(url, ApiOutput.class, json, null);
// HttpExResponseDetails exResponse =
// httpService.sendRequest(authLoginUrl, loginContent, HttpMethod.POST,
// timeOut,
// getHeaders(), null, null, true, false, false, false, null);
System.out.println("Status code: " + out.getStatusCode());
MultiValueMap<String, String> rsHeaders = out.getHeaders();
for (Entry<String, List<String>> e : rsHeaders.entrySet()) {
System.out.println("Key: " + e.getKey());
List<String> valueList = e.getValue();
for (String str : valueList) {
System.out.println("Value: " + str);
}
}
Response:
Status code: 200
Key: Date
Value: Wed, 13 Jul 2016 14:06:43 GMT
Key: Server
Value: Jetty(9.2.16.v20160414)
Key: X-Application-Context
Value: gateway:8080
Key: X-Content-Type-Options
Value: nosniff
Key: X-XSS-Protection
Value: 1; mode=block
Key: Cache-Control
Value: no-cache, no-store, max-age=0, must-revalidate
Key: Pragma
Value: no-cache
Key: Expires
Value: 0
Key: X-Frame-Options
Value: DENY
Key: Content-Type
Value: application/json; charset=UTF-8
Key: Via
Value: 1.1 localhost:8080
Key: Vary
Value: Accept-Encoding
Key: Transfer-Encoding
Value: chunked
The RestTemplate code that i am using to get this:
public static <T> ResponseEntity<T> postServiceCall(String url, Class<T> responseType,
Object postBody,MultiValueMap<String, String> headers) {
HttpEntity<Object> request = new HttpEntity<Object>(postBody, headers);
ResponseEntity<T> response=restTemplate.exchange(url, HttpMethod.POST, request,responseType);
return response;
}
I am not sure what's WebServiceCaller does, however RestTemplate#exchange should return all the headers.

docx and xlsx files not being downloaded using HttpUrlConnection.getInputStream and FileUtils.copyInputStreamToFile

I'm trying to download a some files via webdav. I have some code which seems to work for all files except for Microsoft files. (e.g., docx, xlsx) By "work", I mean to say that I run the program, and I can find the file in the place that I directed it to be saved.
Here is the code:
String[] folderPaths = path.split("/");
String fileName = folderPaths[folderPaths.length - 1];
String webdavURL = "https://" + WEB_HOST + "/webdav/";
if(path.startsWith("/"))
path = path.replaceFirst("/","");
//System.out.println(webdavURL + folder + fileName);
java.net.URL url = new java.net.URL(webdavURL + path);
java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url.openConnection();
//conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestMethod("GET");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestProperty("Authorization", "Basic " + new String(new org.apache.commons.codec.binary.Base64().encode("un:pw".getBytes())));
conn.setRequestProperty("User-Agent","curl/7.37.0");
conn.setRequestProperty("Host", WEB_HOST);
conn.setRequestProperty("Accept", "*/*");
//conn.setRequestProperty("Content-Length", String.valueOf(fileContents.length));
//conn.setRequestProperty("Expect", "100-continue");
org.apache.commons.io.FileUtils.copyInputStreamToFile(conn.getInputStream(), file);
//org.apache.commons.io.FileUtils.writeByteArrayToFile(file, org.apache.commons.io.IOUtils.toByteArray(conn.getInputStream()));
Integer returnCode = conn.getResponseCode();
java.io.InputStream errorStream = conn.getErrorStream();
if(errorStream != null)
System.out.println(org.apache.commons.io.IOUtils.toString(conn.getErrorStream()));
java.util.Map<String, java.util.List<String>> map = conn.getHeaderFields();
for (java.util.Map.Entry<String, java.util.List<String>> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() +
" ,Value : " + entry.getValue());
}
conn.disconnect();
return returnCode;
As you can see, I am printing some lines for debugging purposes.
Here are the response headers for a successful download:
Key : null ,Value : [HTTP/1.1 200 OK]
Key : ETag ,Value : ["179614-BA45C8F60456A672E003A875E469D0EB"]
Key : Content-Length ,Value : [845941]
Key : Expires ,Value : [-1]
Key : Last-Modified ,Value : [Fri, 04 Apr 2014 14:13:54 GMT]
Key : Set-Cookie ,Value : [stuff]
Key : X-Powered-By ,Value : [ARR/2.5]
Key : Server ,Value : [Microsoft-IIS/7.5]
Key : Cache-Control ,Value : [private]
Key : Pragma ,Value : [private]
Key : Date ,Value : [Wed, 23 Dec 2015 19:01:39 GMT]
Key : P3P ,Value : [CP="CAO PSA OUR"]
Key : Content-Type ,Value : [image/jpeg]
Key : Accept-Ranges ,Value : [bytes]
And here are the response headers for an xlsx file:
Key : null ,Value : [HTTP/1.1 200 OK]
Key : ETag ,Value : ["205147-70BDF9AF17A2F13756A21AE50EB88DFF"]
Key : Content-Length ,Value : [48002]
Key : Expires ,Value : [-1]
Key : Last-Modified ,Value : [Fri, 29 Aug 2014 20:27:51 GMT]
Key : Set-Cookie ,Value : [stuff]
Key : X-Powered-By ,Value : [ARR/2.5]
Key : Server ,Value : [Microsoft-IIS/7.5]
Key : Cache-Control ,Value : [private]
Key : Pragma ,Value : [private]
Key : Date ,Value : [Wed, 23 Dec 2015 19:01:38 GMT]
Key : P3P ,Value : [CP="CAO PSA OUR"]
Key : Content-Type ,Value : [application/x-www-form-urlencoded]
Key : Accept-Ranges ,Value : [bytes]
I really have no idea what might be going wrong here. I get a 200 response from the server, and there are no reported errors or exceptions.
The only thing that stands out to me is that, when trying to download an xlsx file, the Content-Type is application/x-www-form-urlencoded while with anything else, the content-type actually lists the type of file that it is. I would not have thought that that would make a difference.
Any ideas at all would be greatly appreciated!
it was conn.setDoInput and conn.setDoOutput. Commenting those out made it work. I didn't really know what they did; I just copied this code from a previous project.

HttpUrlConnection.getContentLength() returns -1 but the header field exists

I'm experiencing a strange behavior of my Java application which download files from a Web server. I download APK files or bash scripts. Both are served the same way by the server but when I download a bash script, the getContentLength() method returns the right content length and when I download an APK file, the method returns -1...
Here is the PHP function I use to serve the files :
function send_file($file) {
header('Content-Type: application/force-download; name="' . basename($file) . '"');
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Expires: 0');
header('Cache-Control: no-cache, must-revalidate');
header('Pragma: no-cache');
readfile($file);
exit();
}
And the Java code to download the files :
URL requestUrl = new URL("http://download.myesmart.net/api.php?id=" + Tablet.ID + "&type=" + type);
// Start the connection to the server
if ((connection = (HttpURLConnection) requestUrl.openConnection()) == null) {
Log.d("TAG", "Impossible to contact the server.");
return null;
}
connection.connect();
// Check the HTTP code
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
Log.d("TAG", "Bad server response : " + connection.getResponseMessage());
return null;
}
// Return -1 sometimes...
Log.d("TAG", "Content-Length : " + connection.getContentLength());
If I check the HTTP header fields this Web tool : http://www.webconfs.com/http-header-check.php, I get the same response type but the first works and the second doesn't.
HTTP/1.1 200 OK =>
Set-Cookie => mailplan=R243416773; path=/; expires=Thu, 13-Nov-2014 09:19:48 GMT
Content-Type => application/force-download; name="configure-keyboard.sh"
Server => Apache
Content-Transfer-Encoding => binary
Content-Disposition => attachment; filename="configure-keyboard.sh"
Expires => 0
Cache-Control => no-cache, must-revalidate
Pragma => no-cache
Vary => Accept-Encoding
Accept-Ranges => bytes
Date => Thu, 13 Nov 2014 08:19:39 GMT
Connection => close
X-Geo => varn16.rbx5
X-Geo-Port => 1015
X-Cacheable => Not cacheable: no-cache
Content-Length => 1118
HTTP/1.1 200 OK =>
Set-Cookie => mailplan=R1918955109; path=/; expires=Thu, 13-Nov-2014 08:59:12 GMT
Content-Type => application/force-download; name="InfoConfort_20141102_ec_v1dev.apk"
Server => Apache
Content-Transfer-Encoding => binary
Content-Disposition => attachment; filename="InfoConfort_20141102_ec_v1dev.apk"
Expires => 0
Cache-Control => no-cache, must-revalidate
Pragma => no-cache
Vary => Accept-Encoding
Accept-Ranges => bytes
Date => Thu, 13 Nov 2014 07:53:43 GMT
Connection => close
X-Geo => varn16.rbx5
X-Geo-Port => 1015
X-Cacheable => Not cacheable: no-cache
Content-Length => 5149910
Any idea ???
According to JavaDocs getContentLength method returns -1, if content length is not known yet.
Would you mind to try this:
URL requestUrl = new URL("http://download.myesmart.net/api.php?id=" + Tablet.ID + "&type=" + type);
//Start the connection to the server
if ((connection = (HttpURLConnection) requestUrl.openConnection()) == null) {
Log.d("TAG", "Impossible to contact the server.");
return null;
}
connection.setRequestProperty("Accept-Encoding", "identity")
Log.d("TAG", "Content-Length : " + connection.getContentLength());
edited.

Can't get Set-Cookie header from http response

I am developing a small web content scraper . Part of the code is to send a http request and get the cookie from the response header, so it can be set in the subsequent request.
The code to get the cookies is like this:
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(url);
request.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
request.setHeader("Accept-Encoding","gzip,deflate,sdch");
if(cookie!=null)
{
request.setHeader("Cookie", cookie);
}
request.setHeader("Accept-Language","en-US,en;q=0.8,zh-CN;q=0.6");
request.setHeader("Cache-Control", "max-age=0");
request.setHeader("Connetion", "keep-alive");
request.setHeader("Host", "www.booking.com");
request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/32.0.1700.76 Safari/537.36");
try {
HttpResponse response = client.execute(request);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println(statusCode);
//get all headers
Header[] headers = response.getAllHeaders();
for (Header header : headers) {
System.out.println("Key : " + header.getName()
+ " ,Value : " + header.getValue());
}
System.out.println("----------------------------------------------------------");
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The url I used to test is http://www.booking.com/hotel/il/herods-hotels-spa.html#tab-reviews
The result printed is like this:
200
Key : Server ,Value : nginx
Key : Date ,Value : Mon, 03 Feb 2014 05:15:41 GMT
Key : Content-Type ,Value : text/html; charset=UTF-8
Key : Connection ,Value : keep-alive
Key : Cache-Control ,Value : private
Key : Vary ,Value : User-Agent, Accept-Encoding
Key : Set-Cookie ,Value : bkng=11UmFuZG9tSVYkc2RlIyh9YdMHS7ByVcpJ6zdHwCKMHsY37i1DyVPCutMoSY%2F9OR7ixF74JFUj1%2BJ3pF8ntbVX55kLQJvNnfE6Qco2NDwnHPzomws7z40vIxLRgwBTWU9CTbAN3zZqJGksaPN3GqHpSWJ%2BMIKlI5hQN6ZcJnKsU3rR9KXmRVS4plyPQf4gqmsjR131%2BtuuBiULzmDsKzejJZg%2BFgWWUOWS71bCxUGvJbeBBo1HRmUVmigKDEyHylYplnhKkriMof25dYccWyLQoBjIyUL4QZWr58O5D7fKPHDYWSY9y7k%2Bxfk7irIsyKdu%2B0owjpGp2%2BncNdphtqPZqdpeCyky1ReSjWVQ4QuZemceNGmfZGwxm%2BQxu0%2BkBEsJA5zY%2BoqulR8MJIBKZpFqsuvbeDZ9r5UJzl5c%2Fqk7Vw5YU1I%2FQunbw7PHra7IaGp6%2BmHnH2%2BeyiMDhAjWL769ebuwG2DhrgfB6eI0AGZE%2F6T0uA4j7bxA%2FwUdhog6yOu%2FSeTkPl%2FTAiIetVyKLfT1949ggWKfk1kGzmjnowOlZzPbxr1L%2FAifBjInWZ6DreY1Mr2A3%2BfjFYaHJYnS8VpB%2BZappBpGXBUVfHe%2FQ7lbDwNd6TCCzigpsb17LtvFYsb3JiZ%2BQFF82ILNwWFKz6B1xxEEbCRVoq8N%2FcXXPStyGSwApHZz%2Bew6LNI7Hkd2rjB1w3HenUXprZWR3XiWIWYyhMAbkaFbiQV2LThkl2Dkl%2FA%3D; domain=.booking.com; path=/; expires=Sat, 02-Feb-2019 05:15:41 GMT; HTTPOnly
Key : X-Recruiting ,Value : Like HTTP headers? Come write ours: booking.com/jobs
However when I uploaded this small program to my server, and ran it, the result became:
200
Key : Server ,Value : nginx
Key : Date ,Value : Mon, 03 Feb 2014 05:14:14 GMT
Key : Content-Type ,Value : text/html; charset=UTF-8
Key : Connection ,Value : keep-alive
Key : Cache-Control ,Value : private
Key : Vary ,Value : User-Agent, Accept-Encoding
Key : X-Recruiting ,Value : Like HTTP headers? Come write ours: booking.com/jobs
The Set-Cookie header disappeared and my subsequent requests to other content pages within the same site(which are supposed to be loaded by a javascript in the first page I requested) all returned 400 error which I guess is because the cookie missing.
I can't figure out why, and the differences between my pc and the server that I know are:
My pc is running Windows 7 and actually has a Chrome browser, while the server is running Linux and doesn't have any actual browser.
The ip addresses are different.
Other than these, I can't think of any yet.
Any suggestion or advice to solve this problem will be appreciated. Thank you.
set-cookie is a forbidden response header name, you can't read it using browser-side JavaScript
developer.mozilla.org
Browsers block frontend JavaScript code from accessing the Set Cookie header, as required by the Fetch spec, which defines Set-Cookie as a forbidden response-header name that must be filtered out from any response exposed to frontend code.

Error JSON object SyntaxError: JSON Parse error: Unterminated string withSpring MVC

Help me Please.
JSON object SyntaxError: JSON Parse error: Unterminated string
JAVA code
#RequestMapping(value = "getMessage.htm")
public #ResponseBody String getStatusServer(ModelMap model, HttpSession session,#RequestParam("key") String key)
throws InterruptedException, ExecutionException {
BufferData bufferData = DataMap.dataMap.get(key);
StringBuilder content = new StringBuilder();
content.append("{\"status\":").append(bufferData.getStatus()).append(",").append(" \"messages\": \"").append(bufferData.getMess()).append("\"}");
System.out.println(content.toString());
return content.toString();
}
JQuery code
function getMessage() {
$.ajax({
type : 'GET',
url : "<c:url value="/"/>" + "getMessage.htm",
data : 'key=' + 'job1',
dataType : "json",
success : function(data) {
alert("test");
alert(JSON.stringify(data));
},
error : function(data, status, er) {
alert("error: " + data + " status: " + status + " er:" + er);
}
});
}
Error code
SyntaxError: JSON Parse error: Unterminated string
Help me Please.
and json output
{"status":1, "messages":"Welcome to Ubuntu 12.04.2 LTS (GNU/Linux 3.5.0-23-generic x86_64) * Documentation: https://help.ubuntu.com/ System information as of Fri Jun 21 17:13:41 ICT 2013 System load: 0.08 Processes: 265 Usage of /: 13.9% of 38.02GB Users logged in: 2 Memory usage: 51% IP address for eth0: 10.216.92.20 Swap usage: 31% => There are 2 zombie processes. Graph this data and manage this system at https://landscape.canonical.com/ Last login: Fri Jun 21 16:30:33 2013 from wachirawat.local vos1#icenaja:~$ hostname icenaja vos1#icenaja:~$ pwd /home/vos1 vos1#icenaja:~$ exit logout "}
This does not look like valid json, try the below to see if it then will send.
data = {
"key": "job1"
}
I am not sure, what do you want to do with line.
url : "<c:url value="/"/>" + "getMessage.htm",
If this is nexted string value, try this single codes instead of double.
url : "<c:url value='/'/>" + "getMessage.htm"

Categories