views:

3918

answers:

4

Hello everybody,

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.

A: 

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?

SystemOut
+1  A: 

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).
laginimaineb
You listed some very nice suggestions.Thanks a lot, will definitely look into it.
Dmitris
you're welcome :P
laginimaineb
+2  A: 

In case some one will run into same problem.

That's what solved my problem:

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