Hamza Toussi Hamza Toussi - 7 months ago 30
Java Question

GSON response return the whole page code including json data

i'm working on an android application that communicate with a jsf application to get the data from database, when i run the android application it shows an error

com.google.gson.stream.malformedjsonexception : Use jsonReader.setLenient(true) to accept malformed json


the full error :

05-02 16:03:51.772: E/(837): [{"description":"CAISSES","nomCat":"CAISSES","photo":"R.JPEG","idCat":1},{"description":"CAISSEDETAIL","nomCat":"CAISSEDETAIL","photo":"P.JPEG","idCat":2}]<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><link type="text/css" rel="stylesheet" href="/pime/faces/javax.faces.resource/theme.css?ln=primefaces-hot-sneaks" /><link type="text/css" rel="stylesheet" href="/pime/faces/javax.faces.resource/fa/font-awesome.css?ln=primefaces&amp;v=5.2.RC3" /><link type="text/css" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" /><!--[if lt IE 9]><script src="/pime/faces/javax.faces.resource/js/html5shiv.js?ln=bsf"></script><script src="/pime/faces/javax.faces.resource/js/respond.js?ln=bsf"></script><![endif]--><script type="text/javascript">if(window.PrimeFaces){}</script></head></html>


as it shows from the error it load the whole page code including the json data.

ANDROID

class myTask extends AsyncTask<String, Integer, StringBuffer> {

@Override
protected StringBuffer doInBackground(String... args) {
String url = args[0];
StringBuffer stringBuffer = getHttpResponse(url);
return stringBuffer;
}

@Override
protected void onPostExecute(StringBuffer result) {
Log.e("", result.toString());
Gson gson = new Gson();

Categorie[] categories = gson.fromJson(result.toString(), Categorie[].class);
for(Categorie c : categories){

Log.e("", c.getNomCategorie());
cats.add(c);
}
listCatModel.notifyDataSetChanged();
super.onPostExecute(result);
}

}


the xhtml that i call from android :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">

<h:head></h:head>
<f:metadata>

<f:event type="preRenderView" listener="#{loginBean.authentifier}" />
</f:metadata>
</html>


Method from backing bean :

public @ResponseBody void authentifier() throws IOException {

FacesContext context = FacesContext.getCurrentInstance();
ExternalContext ext = context.getExternalContext();
HttpServletResponse response = (HttpServletResponse) ext.getResponse();


PrintWriter writer=response.getWriter();
JSONArray jArray = new JSONArray();
JSONObject jsonObject=null;

List<Categories> listCategories = iCategorieManager.listCategories();


for (Categories cats : listCategories) {
jsonObject=new JSONObject(cats);
jArray.put(jsonObject);
}

writer.println(jArray);


}


WEB.XML

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/Beans.xml</param-value>
</context-param>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>

hot-sneaks


</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Production</param-value>
</context-param>
<context-param>
<param-name>primefaces.FONT_AWESOME</param-name>
<param-value>true</param-value>
</context-param>
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.xhtml</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers, Last-Modified</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>

Answer

What is happening here is that you are calling the JSF view, it is calling the managed bean, which is writing the json to the response and then the JSF view is also rendering its html to the response. This of course results in an invalid json response.

One option would be to call the REST service directly, not through the JSF view. But this would require you to setup spring-mvc DispatcherServlet.

A quicker fix would be to instruct JSF that you are done with writing the response and it shouldn't render anything else. For that you can use the responseComplete method of FacesContext in the end of your authentifier method.

context.responseComplete();
Comments