redirect from jsf?

46,712

Solution 1

In case some one will run into same problem.

That's what solved my problem:

FacesContext.getCurrentInstance().getExternalContext().redirect("article.jsp?article_id=" + articleId);

Solution 2

Why are you using dispatch in one place and redirect in the other? This isn't the source of the problem - not returning after sending responses, however, is. Other then that, if you don't mind, I have a few friendly suggestions:

  • You can use DateFormat to return the comment date as you want it (it will be much cleaner).
  • If the errors ArrayList only contains Strings, use generics (ArrayList<String>).
  • What are you doing with the errors?
  • Your sanitation of the commentName is very dangerous. You should use whitelisting instead of blacklisting - define what you wish to accept in a comment and block everything else. Right now someone could insert an <img> tag with a src pointing to a cookie stealing page which would result in a session hijack.
  • After changing the dispatch to a redirect add a return below it (you should always do this. Not doing this could result in what you're seeing right now, which is that you've already sent a response somewhere else, but since you haven't returned you've reached a place where you're trying to send another).

Solution 3

Basically, something is already sending output to the client before you make the call to response.sendRedirect(). Once something has been sent to the browser you can't redirect or forward them to a different place.

In general, any scenarios that might result in a redirect or a forward should be handled as early as possible in the request context to insure the redirect happens before you send any data to the client. Are you doing something like calling this code via a tag in the view?

Solution 4

FacesContext.getCurrentInstance().getExternalContext().redirect("http://www.myUrl.com");

René

Share:
46,712
Dmitris
Author by

Dmitris

Updated on March 23, 2020

Comments

  • Dmitris
    Dmitris about 4 years

    I am working on application with jsp, jstl and jsf for my college project, thats being said, I am as well very new to jsf.

    Everything is going great so far. However, I seems to have a problem figuring out how to do redirect from managed bean to page with dinamyc parameters. For example article.jsp?article_id=2

    Can somebody tell me how it is done ?

    I been trying to use somethinng like

    FacesContext.getCurrentInstance().getExternalContext().dispatch("faces/article.jsp2?article_id=" + articleId);
    

    But get error:

    javax.servlet.ServletException: #{postComment.postClick}: javax.faces.FacesException: javax.servlet.ServletException: javax.faces.component.UIViewRoot cannot be cast to com.sun.faces.application.StateManagerImpl$TreeNode
        javax.faces.webapp.FacesServlet.service(FacesServlet.java:256)
    

    I been trying to use

    response.sendRedirect("faces/article.jsp2?article_id=" + articleId);
                return;
    

    But again getting an error.

    javax.servlet.ServletException: Cannot forward after response has been committed
        javax.faces.webapp.FacesServlet.service(FacesServlet.java:256)
    

    Can somebody please tell me how do i redirect from managed java bean when working with jsf ?

    Bellow is my code (maybe something wrong with that and thats why redirect not working).

    HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
            HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
    
            String articleId = request.getSession().getAttribute("article_id").toString();
            //String articleId  = request.getParameter("article_id");
            String authorName = request.getSession().getAttribute("user_name").toString();
    
            java.util.Calendar calendar = java.util.Calendar.getInstance();
            String commentDate = String.valueOf(calendar.get(java.util.Calendar.DAY_OF_MONTH)) + ".";
            commentDate += String.valueOf(calendar.get(java.util.Calendar.MONTH)) + ".";
            commentDate += String.valueOf(calendar.get(java.util.Calendar.YEAR));
    
             ArrayList error = new ArrayList();
    
            if(commentName.contains("<"))
            {
                error.add("Comment name contains illegal characters");
            }
    
            if(commentBody.isEmpty() && commentBody.contains("<script"))
            {
                error.add("Your message body contains illegal characters");
            }
    
            if(error.size() > 0)
            {
                request.getSession().setAttribute("error", error);
                error.clear();
                FacesContext.getCurrentInstance().getExternalContext().dispatch("article.jsp2?article_id=" + articleId);
            }
            else
            {
                Comment comment = new Comment();
                comment.setCommentAuthor(authorName);
                comment.setCommentBody(commentBody);
                comment.setCommentDate(commentDate);
                comment.setCommentName(commentName);
                comment.setArticleId(articleId);
    
                DisplayArticleIO addComment = new DisplayArticleIO();
                addComment.postComment(comment);
    //            FacesContext.getCurrentInstance().getExternalContext().dispatch("faces/article.jsp2?article_id=" + articleId);
                response.sendRedirect("faces/article.jsp2?article_id=" + articleId);
                return;
            }
    

    Thank you in advance.

  • Dmitris
    Dmitris almost 15 years
    You listed some very nice suggestions. Thanks a lot, will definitely look into it.
  • BalusC
    BalusC over 13 years
    Explanation: it implicitly calls FacesContext#responseComplete() after HttpServletResponse#sendRedirect() to instruct JSF that it doesn't need to render the response. In other words, another (more clumsy) solution would have been to call FacesContext.getCurrentInstance().responseComplete() after the response.sendRedirect() line yourself.