18

I have created a page where I want to get the JSON response from a JSF page, but when i try to get page it shows me whole html page.

<html xmlns="http://www.w3.org/1999/xhtml"><head>
        <title>Facelet Title</title></head><body>
[{"value": "21", "name": "Mick Jagger"},{"value": "43", "name": "Johnny Storm"},{"value": "46", "name": "Richard Hatch"},{"value": "54", "name": "Kelly Slater"},{"value": "55", "name": "Rudy Hamilton"},{"value": "79", "name": "Michael Jordan"}]

</body></html>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Jitendra
  • 1,107
  • 2
  • 12
  • 22
  • If using Spring you can return JSON directly from the controller endpoints through Jackson. If not using Spring, the same approach can be taken. – maksimov Jun 11 '12 at 15:32

4 Answers4

42

JSF is a MVC framework generating HTML, not some kind of a REST web service framework. You're essentially abusing JSF as a web service. Your concrete problem is simply caused by placing <html> tags and so on in the view file yourself.

If you really insist, then you can always achieve this by using <ui:composition> instead of <html>. You also need to make sure that the right content type of application/json is been used, this defaults in JSF namely to text/html.

<ui:composition
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets">
    <f:event type="preRenderView" listener="#{bean.renderJson}" />
</ui:composition>

with

public void renderJson() throws IOException {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    externalContext.setResponseContentType("application/json");
    externalContext.setResponseCharacterEncoding("UTF-8");
    externalContext.getResponseOutputWriter().write(someJsonString);
    facesContext.responseComplete();
}

But I strongly recommend to look at JAX-RS or JAX-WS instead of abusing JSF as a JSON web service. Use the right tool for the job.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • thank you, your solution saved me.In real i wanted to serve some complex data as json which was not easily possible without managedBean. I tried servlet but it became complex to use webservice with it. – Jitendra Jun 11 '12 at 16:33
  • 2
    A servlet is easier if you just use a JSON library instead of fiddling/building it yourself. See also http://stackoverflow.com/questions/4112686/how-to-use-servlets-and-ajax – BalusC Jun 11 '12 at 16:39
  • As always, @BalusC, stacks of thanks for sharing your knowledge on Java, JSF, Servlets and general best practices. Informative, concise and ultra informative, you get a gold star (and an up vote) today! – fusion27 Jun 17 '13 at 16:19
  • @Jitendra, If this is the desired answer, please accept it. – agrawalankur Mar 20 '14 at 18:23
  • @BalusC Please tell me how can I gzip this response, I also need to check accept-encoding request header to ensure compatibility. – Pradip Borde Jun 29 '16 at 09:20
  • _I tried servlet but it became complex to use webservice with it_. It is not complex. You must define another `servlet` tag in web.xml and configure it for JAX-RS. –  Oct 01 '22 at 09:27
4

I'm even using contentType="text/xhtml" with JSF 2.2 and it works great. No needs in renderJson() from the BalusC's answer above

<f:view encoding="UTF-8" contentType="text/html"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core">
 <h:outputText value="#{stationView.getClosestStationen(param.longitude, param.latitude)}" escape="false"/>
</f:view>

Ajax call:

        $.ajax({
            url: requestContextPath + '/rest/stationen.xhtml',
            type: "GET",
            data: {
               "longitude": x,
               "latitude": y
            },
            dataType: "json",
            success: function (data) {
              $.each(data, function (i, station) {
                 ...
              });
            },
            error: function () {
                ...
            }
        })
Oleg
  • 244
  • 1
  • 7
3

Why are you using jsf for that? Use a servlet for serving your JSON. My suggestion would be to use a jaxrs implementation, like cxf.

Joeri Hendrickx
  • 16,947
  • 4
  • 41
  • 53
3

I used just a facelet for the output (but JSF 1.2)

<f:view contentType="application/json" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html">
<h:outputText value="#{someBean.getJson()}" escape="false"/>
</f:view>
webstrap
  • 1,004
  • 1
  • 10
  • 24