Tuesday, January 04, 2011

JSF 2.x Forwarding Request to a Servlet

The question of how to forward a JSF Request to a server was something that came up the other day. I have some legacy servlets which will handle some of the information which is being generated from my JSF pages.

So I decided to write an example of how to do it. The example is designed to go from a JSF page to a servlet which will process the headers and display the information. The alternate example passes the request to a servlet which then passes it back to another JSF page for display. The example also demonstrates using a <f:param /> to pass additional information. The project was done using NetBeans and Maven 2.

Note: The project files can be downloaded here: jsf-servlet-forwarding.zip

As you can see from the images, the forms are very simple and used for demonstration only. 
JSF Request Form

INDEX.XHTML


       <h:form id="form1">
            <h:panelGrid id="panelGrid1" columns="1">
                <h:outputLabel id="outputLabel1" for="inputText1" value="Please enter your name:"/>
                <h:inputText id="inputText1" value="#{indexBean.name}" required="true"/>
                <h:message id="message1" for="inputText1"/>
                <h:panelGroup id="panelGroup1">
                    <h:commandButton id="commandButton1" value="Forward" type="submit" action="#{indexBean.forward}"/>
                    <h:commandButton id="commandButton2" value="Process" type="submit" action="#{indexBean.forward}">
                        <f:param id="param1" name="target" value="/results.xhtml"/>
                    </h:commandButton>
                </h:panelGroup>
            </h:panelGrid>
        </h:form>

JSF -Servlet -JSF Response

RESULTS.XHTML


This file has some interesting syntax which a number of people may not be used to seeing, for example #{param['form1:inputText1']} which is using Expression Language (EL) to read the param[] and find the specific form element which is in single quotes.


    <h:body>
        <p>
            <h:outputText id="outputText1" value="TA DA!" style="font-weight: bold; font-size: larger; text-align: center;"/>
        </p>
        <p>
            <h:outputText id="outputText2" value="Hello #{param['form1:inputText1']}!"/>
        </p>
        <p>
            <h:outputText id="outputText3" value="'target' ==> #{param.target}"/>
        </p>
        <p>
            <h:outputText id="outputText4" value="'form1:inputText1' (name) ==> #{param['form1:inputText1']}"/>
        </p>
        <h:form id="form1">
            <h:commandButton id="commandButton1" type="submit" value="Back" action="index.xhtml"/>
        </h:form>
    </h:body>

Servlet Response

PROCESSSERVLET.JAVA



/*
 *  Copyright 2011 Blue Lotus Software, LLC.
 *  Copyright 2011 John Yeary <jyeary@bluelotussoftware.com>.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
/*
 * $Id: ProcessServlet.java 324 2011-01-05 03:02:41Z jyeary $
 */
package com.bluelotussoftware.example.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * An example servlet which reads the {@link javax.servlet.http.HttpServletRequest} and
 * displays the values on an HTML page, or if the parameter 'target' is set, it will
 * forward the {@link javax.servlet.http.HttpServletRequest} and
 * {@link javax.servlet.http.HttpServletResponse}.
 * 
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
public class ProcessServlet extends HttpServlet {

    private static final long serialVersionUID = -380096497389125142L;

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        if (request.getParameter("target") != null) {
            System.out.println("TARGET: " + request.getParameter("target"));
            RequestDispatcher dispatcher = request.getRequestDispatcher(request.getParameter("target"));
            dispatcher.forward(request, response);
        } else {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
            try {

                out.println("<html>");
                out.println("<head>");
                out.println("<title>Servlet ProcessServlet</title>");
                out.println("</head>");
                out.println("<body>");
                out.println("<h1>Servlet ProcessServlet at " + request.getContextPath() + "</h1>");

                out.println("<h2>Headers</h2>");
                Enumeration<String> headers = request.getHeaderNames();

                while (headers.hasMoreElements()) {
                    String s = headers.nextElement();
                    out.println("<p>" + s + " : " + request.getHeader(s) + "</p>");
                }

                out.println("<h2>Attributes</h2>");
                Enumeration<String> attributes = request.getAttributeNames();

                while (attributes.hasMoreElements()) {
                    String s = attributes.nextElement();
                    out.println("<p>" + s + " : " + request.getAttribute(s) + "</p>");
                }

                out.println("<h2>Parameters</h2>");
                Enumeration<String> parameters = request.getParameterNames();

                while (parameters.hasMoreElements()) {
                    String s = parameters.nextElement();
                    out.println("<p>" + s + " : " + request.getParameter(s) + "</p>");
                }

                out.println("</body>");
                out.println("</html>");

            } finally {
                out.close();
            }
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}

INDEXBEAN.JAVA



/*
 *  Copyright 2011 Blue Lotus Software, LLC.
 *  Copyright 2011 John Yeary <jyeary@bluelotussoftware.com>.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
/*
 * $Id: IndexBean.java 324 2011-01-05 03:02:41Z jyeary $
 */
package com.bluelotussoftware.example.jsf.bean;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * {@link javax.faces.bean.ManagedBean} for the {@literal index.xhtml} which is
 * used for demonstration of forwarding {@link javax.servlet.http.HttpServletRequest}
 * and {@link javax.servlet.http.HttpServletResponse} to an external servlet.
 *
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
@ManagedBean
@RequestScoped
public class IndexBean {

    /**
     * Field for name.
     */
    private String name;

    /**
     * Default Constructor
     */
    public IndexBean() {
    }

    /**
     * Getter for name field
     * @return name provided.
     */
    public String getName() {
        return name;
    }

    /**
     * Setter for name field.
     * @param name value provided.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Forwards the {@link javax.servlet.http.HttpServletRequest} and
     * {@link javax.servlet.http.HttpServletResponse} to a servlet URL
     * pattern called {@literal /process}, and sets the {@link javax.faces.context.FacesContext#responseComplete()}.
     */
    public void forward() {
        try {
            FacesContext ctx = FacesContext.getCurrentInstance();
            ExternalContext ectx = ctx.getExternalContext();
            HttpServletRequest request = (HttpServletRequest) ectx.getRequest();
            HttpServletResponse response = (HttpServletResponse) ectx.getResponse();
            RequestDispatcher dispatcher = request.getRequestDispatcher("/process");
            dispatcher.forward(request, response);
            ctx.responseComplete();
        } catch (ServletException ex) {
            Logger.getLogger(IndexBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(IndexBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

1 comments :

Unknown said...

Thank you for posting this. It demonstrates the concept perfectly and saved me heaps of trial and error.

Popular Posts