JSF bean动作方法返回字符串测试

srk*_*srk 1 navigation jsf jsf-1.2

我试图从这个问题中理解在JSF动作中返回null和""之间的区别,但是无法实际体验.

以下是OP的报价

据我所知,当JSF操作返回""(空字符串)时,用户会保留在当前页面上,但视图会刷新.但是,当操作返回null时,用户仍然停留在当前页面上,但旧视图将被重用

我在理解返回的区别混淆"",null"viewid?faces-redirect=true"从JSF支持bean.我试图通过一个小例子来理解差异,但我无法体验到实际的差异.以下是我的示例的代码片段.

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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

UserLogin.java(Backing bean)代码片段

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;
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

本例中使用的库

在此输入图像描述

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

Bal*_*usC 7

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

但是,JSF 1.2没有"视图范围bean"的概念.这是在JSF 2.0中引入的.而且,你有一个请求范围的bean.无论您如何导航,它都会在每个请求中重新创建.因此,通过查看bean的行为方式,这并不是很明显.如果您手动模仿JSF 2.0视图范围,只需在其中放置一个属性UIViewRoot,然后检查请求范围bean的构造函数(如果它仍然存在),那么这一点才会引人注意.

如果您使用了JSF 2.x视图范围的bean,那么当您使用非null结果导航时,您已经注意到它已重新创建(即,它(post)构造函数再次被调用).另请参阅ao 如何选择合适的bean范围?

并且,?faces-redirect=true查询字符串也是JSF 2.x特定的,JSF 1.x无法识别.在JSF 1.x中,要达到同样的效果,无论是添加<redirect/><navigation-case>,或使用ExternalContext#redirect().

public void saveData() throws IOException {
    // ...

    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    String url = ec.getRequestContextPath() + "/login.jsf";
    ec.redirect(url);
}
Run Code Online (Sandbox Code Playgroud)

在这个相关问题中详细阐述了哪种导航方法:如何在JSF中导航?如何使URL反映当前页面(而不是之前的页面).通常,在UX和SEO的角度来看,使用POST进行页面到页面导航是不好的做法.始终使用GET或POST后执行重定向.

无论如何,在使用JSF 1.x进行开发时,您不应该关注JSF 2.x目标答案/资源.它只会导致混乱,因为JSF 2.x中的许多事情都有所不同(更好!).JSF 2.x已经存在了5年多,JSF 1.x几乎和EOL一样长.继续研究死技术是没有意义的.考虑迁移.