Перенаправить из jsf?

Я работаю над приложением с jsp, jstl и jsf для своего проекта в колледже, и, как говорится, я также очень плохо знаком с jsf.

Пока все идет отлично. Тем не менее, мне кажется, что я не могу понять, как сделать перенаправление с управляемого компонента на страницу с параметрами dinamyc. Например article.jsp?article_id=2

Может кто-нибудь сказать мне, как это делается?

Я пытался использовать что-то вроде

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

Но получите ошибку:

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)

Я пытался использовать

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

Но опять получаю ошибку.

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

Может кто-нибудь сказать, пожалуйста, как мне перенаправить с управляемого Java-бина при работе с JSF?

Ниже приведен мой код (может быть, что-то не так с этим и поэтому не работает перенаправление).

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;
        }

Заранее спасибо.

4 ответа

В случае, если кто-то столкнется с той же проблемой.

Вот что решило мою проблему:

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

Почему вы используете диспетчеризацию в одном месте и перенаправление в другом? Это не источник проблемы - однако, не возвращение после отправки ответов. Кроме того, если вы не возражаете, у меня есть несколько дружественных предложений:

  • Вы можете использовать DateFormat, чтобы вернуть дату комментария, как вы хотите (это будет намного чище).
  • Если ошибки ArrayList содержат только строки, используйте обобщенные значения (ArrayList<String>).
  • Что вы делаете с ошибками?
  • Ваша санация commentName очень опасна. Вы должны использовать белый список вместо черного - определите, что вы хотите принять в комментарии, и заблокируйте все остальное. Прямо сейчас кто-то может вставить <img> пометьте тегом src, указывающим на страницу кражи файлов cookie, что приведет к перехвату сеанса.
  • После изменения отправки на перенаправление добавьте возврат под ним (вы всегда должны делать это. Если вы этого не сделаете, это может привести к тому, что вы видите прямо сейчас, то есть вы уже отправили ответ куда-то еще, но так как Вы вернулись, вы достигли места, куда вы пытаетесь отправить другое).
FacesContext.getCurrentInstance().getExternalContext().redirect("http://www.myUrl.com");

Рене

По сути, что-то уже отправляет вывод клиенту, прежде чем вы вызовите response.sendRedirect(). После того, как что-то было отправлено в браузер, вы не можете перенаправить или переслать его в другое место.

В целом, любые сценарии, которые могут привести к перенаправлению или пересылке, должны обрабатываться как можно раньше в контексте запроса, чтобы гарантировать, что перенаправление произойдет до того, как вы отправите какие-либо данные клиенту. Вы делаете что-то вроде вызова этого кода с помощью тега в представлении?

Другие вопросы по тегам