【问题标题】:JSF bean action method return string testJSF bean动作方法返回字符串测试
【发布时间】:2015-03-27 10:41:46
【问题描述】:

我试图从 question 中了解 JSF 动作中返回 null 和 "" 的区别,但无法实际体验。

以下是 OP 的报价单

据我了解,当 JSF 操作返回“”(空字符串)时 用户停留在当前页面,但视图已刷新。然而, 当操作返回 null 时,用户仍然停留在当前页面上 但是旧视图被重用了

我对从 JSF 支持 bean 返回 ""null"viewid?faces-redirect=true" 之间的区别感到困惑。我试图通过一个小例子来理解差异,但我无法体验到实际的差异。下面是我的例子的代码 sn-ps。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>Jsf Questions</display-name>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.jspx</param-value>
  </context-param>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/jsfintroapp/*</url-pattern>
  </servlet-mapping>
</web-app>

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xi="http://www.w3.org/2001/XInclude"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
 <managed-bean>
  <managed-bean-name>userLogin</managed-bean-name>
  <managed-bean-class>com.srk.beans.UserLogin</managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
 </managed-bean>
 <navigation-rule>
  <description>Contains list of all navigation rules here</description>
  <from-view-id>/*</from-view-id>
  <navigation-case>
   <display-name>WELCOME</display-name>
   <from-outcome>welcome</from-outcome>
   <to-view-id>/geek_examples/authorized_user.jspx</to-view-id>
  </navigation-case>
</faces-config>

如上所述,我的托管 bean 是一个请求范围的 bean。

UserLogin.java (Backing bean) 代码 sn-p

public String saveData() {
    //String returnString = "";//Case 1 : works - user stays on the same page
    //String returnString = null;//Case 2: works - user stays on the same page
    // Case 3:
    String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
    LOG.debug("view id = "+ viewId);
    String returnString = "?faces-redirect=true";//viewId+
    LOG.debug("return string = "+ returnString);
    LOG.debug("Username = "+ getName() + " password = "+ getPassword());
    return returnString;
}

login.jspx

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
<f:view>
<head>
<title>JSF Question</title>
</head>
<body>
    <h:form>
        <h3>User Name and Password</h3>
        <table>
            <tr>
              <td><h:outputLabel value="Name"/></td>
              <td><h:inputText value="#{userLogin.name}"/></td>
            </tr>
            <tr>
              <td><h:outputLabel value="Password"/></td>
              <td><h:inputText value="#{userLogin.password}"/></td>
            </tr>
            <tr>
              <td><h:commandButton value="Sign In" action="#{userLogin.saveData}"/></td>
            </tr>
        </table>
    </h:form>
</body>
</f:view>
</html>

本例中使用的库

我尝试访问 login.jspx 页面,在表单字段中输入值并单击登录。我总是可以看到相同的页面,无论我在 saveData() 方法中返回什么并没有表现出任何行为差异,有人可以就这个概念提出一些启示吗?

【问题讨论】:

    标签: jsf navigation jsf-1.2


    【解决方案1】:

    正如该答案中的回答,返回 nullvoid 将重用相同的 JSF 视图,包括附加到它的所有视图范围的 bean。

    然而,JSF 1.2 没有“视图范围 bean”的概念。这是在 JSF 2.0 中引入的。此外,您有一个请求范围的 bean。无论您如何导航,它都会在每次请求时重新创建。因此,通过查看 bean 的行为方式,它并不是很明显。仅当您通过将属性放入 UIViewRoot 中手动模仿 JSF 2.0 视图范围,然后检查请求范围 bean 的构造函数(如果它仍然存在)时,才会注意到这一点。

    如果您使用过 JSF 2.x 视图范围 bean,您会注意到当您使用非null 结果导航时,它会重新创建(即再次调用它的(后)构造函数)。另见 a.o. How to choose the right bean scope?

    而且,?faces-redirect=true 查询字符串也是 JSF 2.x 特有的,JSF 1.x 无法识别。在 JSF 1.x 中,要达到同样的效果,要么在&lt;navigation-case&gt; 中添加&lt;redirect/&gt;,要么使用ExternalContext#redirect()

    public void saveData() throws IOException {
        // ...
    
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        String url = ec.getRequestContextPath() + "/login.jsf";
        ec.redirect(url);
    }
    

    此相关问题详细说明了选择哪种导航方法:How to navigate in JSF? How to make URL reflect current page (and not previous one)。一般来说,从 UX 和 SEO 的角度来看,使用 POST 进行页面到页面导航是不好的做法。始终为此使用 GET 或在 POST 之后执行重定向。

    无论如何,在使用 JSF 1.x 进行开发时,您不应该查看针对 JSF 2.x 的答案/资源。这只会导致混乱,因为在 JSF 2.x 中很多事情都以不同的方式完成(更好!)。 JSF 2.x 已经存在超过 5 年,而 JSF 1.x 的 EOL 时间也差不多。继续研究死技术是没有意义的。 Consider migrating.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-14
      相关资源
      最近更新 更多