2009-06-10 13 views
10

Pracuję nad aplikacją z jsp, jstl i jsf dla mojego projektu w college'u, który jest powiedziany, jestem również bardzo nowy w jsf.przekierowanie z jsf?

Wszystko idzie jak dotąd świetnie. Jednak wydaje mi się, że mam problem z ustaleniem sposobu przekierowania z zarządzanego komponentu bean na stronę z parametrami dinamyc. Na przykład article.jsp?article_id=2

Czy ktoś może mi powiedzieć, jak to się robi?

I próbuje użyć somethinng jak

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

Ale się błąd:

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 próbuje użyć

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

Ale znowu otrzymuję błąd.

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

Czy ktoś może mi powiedzieć, w jaki sposób mogę przekierować z zarządzanego komponentu Java bean podczas pracy z jsf?

Osłona to mój kod (może coś nie tak z tym i dlatego przekierowanie nie działa).

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

Z góry dziękuję.

Odpowiedz

1

Zasadniczo coś już wysyła dane wyjściowe do klienta przed wywołaniem metody response.sendRedirect(). Po wysłaniu czegoś do przeglądarki nie można przekierować ani przesłać ich w inne miejsce.

Ogólnie, wszelkie scenariusze, które mogą skutkować przekierowaniem lub przekazywaniem, powinny być traktowane tak wcześnie, jak to możliwe w kontekście żądania, aby zapewnić przekierowanie, zanim wyślesz jakiekolwiek dane do klienta. Czy robisz coś w rodzaju wywoływania tego kodu przez znacznik w widoku?

2

Dlaczego używasz wysyłki w jednym miejscu i przekierowujesz w drugim? To nie jest źródło problemu - nie powraca jednak po wysłaniu odpowiedzi. Inne następnie, że jeśli to nie przeszkadza, mam kilka przyjaznych propozycje:

  • Można użyć dateformat wrócić datę komentarz, jak chcesz go (będzie znacznie odkurzacz).
  • Jeśli błędy ArrayList zawierają tylko ciągi, użyj generics (ArrayList<String>).
  • Co robisz z błędami?
  • Twoja sanitacja komentarza to: bardzo niebezpieczna. Zamiast czarnej listy powinieneś używać białej listy - zdefiniuj, co chcesz zaakceptować w komentarzu i zablokuj wszystko inne. Teraz ktoś mógł wstawić znacznik <img> z src wskazującym na stronę kradzieży plików cookie, która spowodowałaby porwanie sesji.
  • Po zmianie wysyłki na przekierowanie, dodaj poniższy zwrot (zawsze powinieneś to zrobić.Niewykonanie tej czynności może doprowadzić do tego, co właśnie widzisz, a mianowicie, że już wysłałeś odpowiedź w innym miejscu, ale ponieważ nie powróciłeś, dotarłeś do miejsca, w którym próbujesz wysłać kolejną).
+0

Ty wymieniono kilka bardzo ciekawych propozycji. Wielkie dzięki, zdecydowanie na nie spojrzę. – Dmitris

+0

Nie ma za co: P – laginimaineb

23

Jeśli ktoś napotka na ten sam problem.

To właśnie rozwiązać mój problem:

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

Objaśnienie: domyślnie wywołuje funkcję 'FacesContext # responseComplete()' po 'HttpServletResponse # sendRedirect()', aby polecić JSF, że nie musi renderować odpowiedzi. Innymi słowy, innym (bardziej niezgrabnym) rozwiązaniem byłoby wywołanie 'FacesContext.getCurrentInstance(). ResponseComplete()' po linii 'response.sendRedirect()'. – BalusC

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

René

+4

Cześć, to już odpowiedział OP sam :) – BalusC