2009-06-10 93 views
10

我正在为我的大学项目开发​​jsp,jstl和jsf的应用程序,这就是说,我对jsf也很新。从jsf重定向?

到目前为止,一切都很顺利。然而,我似乎有一个问题,搞清楚如何从托管bean重定向到dinamyc参数的页面。 例如article.jsp?article_id=2

有人能告诉我它是怎么做的?

我一直试图用somethinng像

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) 

有人能告诉我如何使用jsf工作时从托管java bean重定向?

贝娄是我的代码(也许有什么错,那就是为什么重定向不工作)。

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

在此先感谢您。

回答

1

基本上,在您调用response.sendRedirect()之前,已经有一些东西已经将输出发送到客户端。一旦有东西被发送到浏览器,你不能重定向或转发他们到不同的地方。

一般来说,任何可能导致重定向或转发的场景都应尽早在请求上下文中处理,以确保在将任何数据发送到客户端之前发生重定向。你是否正在通过视图中的标记调用此代码?

2

你为什么在一个地方使用调度并在另一个地方重定向?这不是问题的根源 - 然而,在发送回复之后不会返回。其他然后,如果你不介意,我有几个友好的建议:

  • 您可以使用日期格式返回你想要的评论日期(这将是清洁)。
  • 如果错误ArrayList只包含字符串,请使用泛型(ArrayList<String>)。
  • 你在做什么错误?
  • 您对commentName的卫生设施是危险。您应该使用白名单而不是黑名单 - 在评论中定义您想要接受的内容并阻止其他内容。现在有人可以插入一个<img>标签,其中src指向cookie窃取页面,这会导致会话劫持。
  • 将调度更改为重定向后,在其下方添加一个返回(您应该始终执行此操作。不这样做可能会导致你现在看到的情况,这是你已经在其他地方发送了回复,但是由于你没有回复,你已经到达了你想要发送另一个回复的地方)。
+0

您列举了一些非常好的建议。 非常感谢,一定会研究它。 – Dmitris 2009-06-10 06:00:28

+0

不用客气:P – laginimaineb 2009-06-10 06:02:53

23

万一有人会遇到同样的问题。

这就是解决我的问题:

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

解释:它隐式地在`HttpServletResponse#sendRedirect()`之后调用`FacesContext#responseComplete()`来指示JSF它不需要呈现响应。换句话说,另一个(更笨拙的)解决方案本来就是在`response.sendRedirect()`行后面调用`FacesContext.getCurrentInstance()。responseComplete()`。 – BalusC 2010-11-08 01:47:16

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