2013-01-14 98 views
1

編輯: 好了,所以我嘗試設置幾個console.writes檢查發生了什麼......看來我註銷腳本在導航調用。但我不任何地方調用它,除非我的註銷按鈕。SessionScoped控制器不工作

這裏是我的模板代碼:

<div class="navbar"> 
    <div class="navbar-inner"> 
     <ul class="nav"> 
      <li class="active"><a href="#{root}index.xhtml">Home</a></li> 
      <li><a href="#{root}races/list.xhtml">Races</a></li> 
      <li><a href="#{root}horses/list.xhtml">Horses</a></li> 
      <h:panelGroup rendered="#{memberController.logged == true}"> 
       <li><a href="#{root}profile/history.xhtml">History</a></li> 
       <li><a href="#" onclick="#{memberController.logout()}">Logout</a></li> 
      </h:panelGroup> 
      <h:panelGroup rendered="#{memberController.logged == false}"> 
       <li><a href="#{root}users/login.xhtml">Login</a></li> 
       <li><a href="#{root}users/register.xhtml">Create Account</a></li> 
      </h:panelGroup> 
     </ul> 
    </div> 
</div> 

原始郵件:

我創造了我的學校項目(Java EE的)網站......這是我們的第一年,這樣做。 現在,因爲這是夜校,只有一個學期學習它,你可能會看到我的做事方式不是最好的:)

所以要開始,我試圖創建一個登錄功能,但我們可能會使用簡單會話作用域成員對象而不是那些被篡改的安全代碼行。

所以在這裏你有我的幾個類:

會員等級:

@Entity 
@Table(name = "members") 
public class Member implements Serializable { 
    //+ Getters, setters, HashCode and equals 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    private long id; 
    private double money; 

    @NotNull(message = "Username cannot be null") 
    @Size(min = 4, message = "Username should be of minimum 4 characters") 
    private String userName; 

    @NotNull(message = "Password cannot be null") 
    @Size(min = 4, message = "Password should be of minimum 4 characters") 
    private String password; 

    @PostPersist 
    private void initDefault() { 
     this.money = 500; 
    } 
} 

MemberBean類:

@Stateless 
public class MemberBean { 

    @PersistenceContext(unitName="HorseRacingPU") 
    private EntityManager em; 

    public Member getMember(long id){ 
     return em.find(Member.class, id); 
    } 

    public Member getMember(String username, String password){ 
     TypedQuery<Member> q = em.createQuery("SELECT u FROM Member u WHERE u.userName=?1 AND u.password=?2", Member.class); 
     q.setParameter(1, username); 
     q.setParameter(2, password); 
     return q.getSingleResult(); 
    } 

    public List<Member> getAllMembers(){ 
     TypedQuery<Member> q = em.createQuery("SELECT u FROM Member u", Member.class); 
     return q.getResultList(); 
    } 

    public Member addOrUpdateMember(Member u){ 
     Member original = em.find(Member.class, u.getId()); 
     if(original == null){ 
      em.persist(u); 
      return u; 
     }else{ 
      return em.merge(u); 
     } 
    } 

    public Member deleteMember(long id){ 
     Member original = em.find(Member.class, id); 
     if(original != null){ 
      em.remove(original); 
     } 
     return original; 
    } 
} 

MemberController類:

@SessionScoped 
public class MemberController implements Serializable { 

    @EJB 
    private MemberBean bean; 
    private String username; 
    private String password; 
    private Member member; 
    private boolean logged = false; 
// + their getters and setters 

    public List<Member> getAllMembers() { 
     return bean.getAllMembers(); 
    } 

    public String login() { 
     member = bean.getMember(username, password); 
     if (member != null) { 
      logged = true; 
      return "/races/list.xhtml?faces-redirect=true"; 
     } 
     return "https://stackoverflow.com/users/login.xhtml?faces-redirect=true"; 
    } 

    public String logout() { 
     FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); 
     return "/index.xhtml?faces-redirect=true"; 
    } 

    public void checkLogin(ComponentSystemEvent e) { 
     if (!logged) { 
      FacesContext context = FacesContext.getCurrentInstance(); 
      ConfigurableNavigationHandler handler = (ConfigurableNavigationHandler) context.getApplication().getNavigationHandler(); 
      handler.performNavigation("https://stackoverflow.com/users/login.xhtml?faces-redirect=true"); 
     } 
    } 

    public Member getMember() { 
     return member; 
    } 

    public void submit() { 
     bean.addOrUpdateMember(member); 
    } 
} 

主要誤差我得到如下:

信息:異常處理錯誤嘗試重置響應時。

更詳細錯誤可以在這裏找到:http://pastebin.com/h5nTNnes

那麼會發生什麼情況是,當我登錄時,一切都很正常。當我導航到另一個網址(被轉發到/比賽/列表後)我得到註銷。錯誤本身就說明了,當我使用checkLogin():

<f:event type="preRenderView" listener="#{memberController.checkLogin}" /> 

我不知道這是否是相關的,但是當我登錄沒有任何演示數據(或錯誤的憑據),我得到一個評價異常和沒有實體可以檢索。 這裏更多的細節:http://pastebin.com/Tv9mQ1K9

這是什麼?我搔了搔腦袋三天,似乎無法在任何地方發現問題。

+0

歡迎來到StackOverflow。請閱讀常見問題解答中的[如何提問](http://stackoverflow.com/faq#howtoask)部分,並重新編寫問題,否則將被關閉(也可能會被降低)。 –

+0

我讀過它,但似乎無法看到我的問題存在什麼問題。我知道有兩個以上的鏈接,但它是爲了確保文本不會長時間閱讀,並且人們實際上可以組織其標籤以查看代碼,而不是多次上下滾動。 – VercauterenP

+0

這就是問題所在:你必須在問題中編寫所有相關代碼,而不是指向顯示代碼的外部鏈接。嘗試將代碼最小化到[SSCCE](http://sscce.org),以便我們理解它併爲您提供幫助。請記住,這個網站是爲**免費**建議,而不是一個Java EE支持團隊,他們會不惜一切代價爲您提供滿足您需求的一切。 –

回答

1

<li><a href="#" onclick="#{memberController.logout()}">Logout</a></li> 

是不對的。

onclick屬性應引用JavaScript處理程序。例如。 alert('peek-a-boo');。 JSF/EL將它視爲普通的香草字符串,並且期望logout()方法返回一些JavaScript代碼,如String,然後應將其內聯在HTML結果中。試想一下,該方法實際返回alert('peek-a-boo');,那麼最終的結果(如你在通過右擊瀏覽器中看到,查看源)會是這樣:

<li><a href="#" onclick="alert('peek-a-boo');">Logout</a></li> 

然而,在特定情況下,你實際上執行註銷並返回一個字符串值/index.xhtml?faces-redirect=true。所以生成的HTML結果爲:

<li><a href="#" onclick="/index.xhtml?faces-redirect=true">Logout</a></li> 

這是無效的JS代碼。但是這不是主要問題:用戶已經註銷而沒有點擊鏈接!

您需要一個完整的JSF命令組件。例如。 <h:commandLink>

<li><h:form><h:commandLink value="Logout" action="#{memberController.logout()}"/></h:form></li> 

該方法僅在實際點擊鏈接時調用,這正是您所需要的。

+0

瓦解一百萬感謝解決方案和解釋爲什麼發生這種情況!它工作得很好! – VercauterenP

+0

不客氣。 – BalusC