13. 渲染视图
本章介绍如何使用view-state
元素来渲染流中的视图。
13.1. 定义视图状态
这view-state
元素定义呈现视图并等待 User 事件恢复的流的一个步骤,如下所示:
<view-state id="enterBookingDetails">
<transition on="submit" to="reviewBooking" />
</view-state>
按照惯例,view-state
将其 ID 映射到流程所在目录中的视图模板。
例如,前面示例中的状态可能会呈现/WEB-INF/hotels/booking/enterBookingDetails.xhtml
如果流本身位于/WEB-INF/hotels/booking
目录。
下图显示了一个示例目录结构,其中包含视图和其他资源,例如与其流定义位于同一位置的消息包:

13.2. 指定视图标识符
您可以使用view
属性来显式指定要渲染的视图的 ID。
13.2.1. 流相对视图 ID
视图 ID 可以是流程工作目录中查看资源的相对路径,如下所示:
<view-state id="enterBookingDetails" view="bookingDetails.xhtml">
13.3. 视图范围
一个view-state
分配一个新的viewScope
当它进入时。
您可以在view-state
来分配应在 state 持续时间内存在的变量。
此范围对于从同一视图(通常是 Ajax 请求)的一系列请求中作对象非常有用。
一个view-state
销毁其viewScope
当它退出时。
13.3.1. 分配视图变量
您可以使用var
标记来声明视图变量。
与流变量一样,任何@Autowired
当视图状态恢复时,引用会自动恢复。
下面的清单声明了一个 view 变量:
<var name="searchCriteria" class="com.mycompany.myapp.hotels.SearchCriteria" />
13.3.2. 分配viewScope
变量
您可以使用on-render
标记在视图呈现之前从作结果中分配一个变量,如下所示:
<on-render>
<evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" />
</on-render>
13.3.3. 在 View Scope 中作对象
视图范围内的对象通常是通过来自同一视图的一系列请求进行作的。 在每次渲染之前,该列表都会在视图范围内更新。 异步事件处理程序修改当前数据页,然后请求重新呈现搜索结果片段。 以下示例浏览搜索结果列表:
<view-state id="searchResults">
<on-render>
<evaluate expression="bookingService.findHotels(searchCriteria)"
result="viewScope.hotels" />
</on-render>
<transition on="next">
<evaluate expression="searchCriteria.nextPage()" />
<render fragments="searchResultsFragment" />
</transition>
<transition on="previous">
<evaluate expression="searchCriteria.previousPage()" />
<render fragments="searchResultsFragment" />
</transition>
</view-state>
13.4. 运行 Render Actions
这on-render
元素在视图呈现之前运行一个或多个作。
渲染作在初始渲染以及任何后续刷新(包括视图的任何部分重新渲染)上运行。
下面的清单定义了一个on-render
元素:
<on-render>
<evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" />
</on-render>
13.5. 绑定到模型
您可以使用model
attribute 来声明视图绑定到的对象。
此属性通常与呈现数据控件的视图 (如窗体) 结合使用。
它允许从模型对象上的元数据驱动表单数据绑定和验证行为。
以下示例声明了enterBookingDetails
state作booking
型:
<view-state id="enterBookingDetails" model="booking">
模型可以是任何可访问范围中的对象,例如flowScope
或viewScope
.
指定model
发生 View 事件时触发以下行为:
-
视图到模型绑定。在查看回发时,用户输入值将绑定到您的模型对象属性。
-
模型验证。绑定后,如果模型对象需要验证,则调用该验证逻辑。
对于可以驱动生成视图状态转换的流程事件,模型绑定必须成功完成。 如果模型绑定失败,将重新渲染视图以允许用户修改其编辑。
13.6. 执行类型转换
当使用请求参数填充模型(通常称为数据绑定)时,在设置目标模型属性之前,需要进行类型转换来解析基于字符串的请求参数值。 默认类型转换可用于许多常见的 Java 类型,例如数字、基元、枚举和日期。 用户还可以为用户定义的类型注册自己的类型转换逻辑,并覆盖默认转换器。
13.6.2. 升级到 Spring 3 类型转换和格式化
实际上,这对现有应用程序意味着什么?现有应用程序可能会注册自己的 Converter 类型org.springframework.binding.convert.converters.Converter
通过DefaultConversionService
在 Spring Binding 中可用。
这些转换器可以继续像以前一样注册。
他们被改编为SpringGenericConverter
类型并注册到 Springorg.springframework.core.convert.ConversionService
实例。
换句话说,现有的转换器是通过 Spring 的类型转换服务调用的。
此规则的唯一例外是命名转换器,您可以从binding
元素中view-state
如下:
public class ApplicationConversionService extends DefaultConversionService {
public ApplicationConversionService() {
addDefaultConverters();
addDefaultAliases();
addConverter("customConverter", new CustomConverter());
}
}
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" required="true" converter="customConverter" />
</binder>
</view-state>
命名转换器不受支持,也不能与 Spring 中提供的类型转换服务一起使用。 因此,此类转换器没有适应并继续像以前一样工作。 也就是说,它们不涉及 Spring 类型转换。 但是,此机制已被弃用,并且鼓励应用程序支持 Spring 类型转换和格式化功能。
另请注意,现有的 Spring BindingDefaultConversionService
不再注册任何默认转换器。
相反,Web Flow 现在依赖于 Spring 中的默认类型转换器和格式化程序。
总之,Spring 类型转换和格式化现在几乎只用于 Web Flow。 尽管现有的应用程序应该可以在没有任何更改的情况下工作,但我们鼓励朝着统一应用程序的 Spring MVC 和 Spring Web Flow 部分的类型转换需求的方向发展。
13.6.3. 配置类型转换和格式化
在 Spring MVC 中,一个FormattingConversionService
通过自定义 MVC 命名空间自动创建,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<mvc:annotation-driven/>
在内部,这是在FormattingConversionServiceFactoryBean
,它注册一组默认的转换器和格式化程序。
您可以通过conversion-service
属性,如下所示:
<mvc:annotation-driven conversion-service="applicationConversionService" />
在 Web Flow 中,Spring Binding 的实例DefaultConversionService
,它不会注册任何转换器。
相反,它会委托给FormattingConversionService
实例满足所有类型转换需求。
默认情况下,这是不一样的FormattingConversionService
实例作为 Spring 中使用的实例。
但是,在您开始注册自己的格式化程序之前,这不会产生实际区别。
您可以自定义DefaultConversionService
在 Web 流中通过 flow-builder-services 元素使用,如下所示:
<webflow:flow-builder-services id="flowBuilderServices" conversion-service="defaultConversionService" />
您可以执行以下作来注册自己的格式化程序,以便在 Spring MVC 和 Spring Web Flow 中使用:
-
创建一个类来注册您的自定义格式化程序:
public class ApplicationConversionServiceFactoryBean extends FormattingConversionServiceFactoryBean { @Override protected void installFormatters(FormatterRegistry registry) { // ... } }
-
配置类以在 Spring MVC 中使用:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <mvc:annotation-driven conversion-service="applicationConversionService" /> <!-- Alternatively if you prefer annotations for DI: 1. Add @Component to the factory bean. 2. Add a component-scan element (from the context custom namespace) here. 3. Remove XML bean declaration below. --> <bean id="applicationConversionService" class="somepackage.ApplicationConversionServiceFactoryBean">
-
连接 Web 流
DefaultConversionService
到相同的applicationConversionService
Spring MVC 中使用的 bean:<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices" ... /> <webflow:flow-builder-services id="flowBuilderServices" conversion-service="defaultConversionService" ... /> <bean id="defaultConversionService" class="org.springframework.binding.convert.service.DefaultConversionService"> <constructor-arg ref="applicationConversionSevice"/> </bean>
您也可以混合搭配。
您可以注册新的 SpringFormatter
类型通过applicationConversionService
.
您可以注册现有的 Spring BindingConverter
类型通过defaultConversionService
.
13.6.4. 使用 Spring 类型转换和格式化
`` 需要了解的一个重要概念是类型转换器和格式化程序之间的区别。
Spring 中的类型转换器,在org.springframework.core
用于任意两个对象类型之间的通用类型转换。
除了最简单的Converter
type 中,其他两个接口是ConverterFactory
和GenericConverter
.
Spring 中的格式化程序,由org.springframework.context
,具有更专业的目的,即表示Object
实例设置为String
实例。
这Formatter
interface 扩展了Printer
和Parser
用于将Object
更改为String
并转动String
转换为Object
.
Web 开发人员可能会发现Formatter
interface 是最相关的,因为它符合 Web 应用程序对类型转换的需求。
对象到对象转换是更具体的对象到字符串转换的泛化。
事实上Formatters 注册为GenericConverter 类型与 Spring 的GenericConversionService ,使它们等于任何其他转换器。 |
13.7. 抑制绑定
您可以使用bind
属性来禁止特定视图事件的模型绑定和验证。
以下示例在cancel
事件发生:
<view-state id="enterBookingDetails" model="booking">
<transition on="proceed" to="reviewBooking">
<transition on="cancel" to="bookingCancelled" bind="false" />
</view-state>
13.8. 显式指定绑定
您可以使用binder
元素来配置要应用数据绑定的确切模型属性集。
这允许您限制每个视图的 “allowed fields” 集。
如果不这样做可能会导致安全问题,具体取决于应用程序域和实际用户,因为默认情况下,如果未指定 Binder 元素,则模型的所有公共属性都有资格由视图进行数据绑定。
相比之下,当binder
元素,则只允许显式配置的绑定。
以下示例使用binder
元素:
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="creditCard" />
<binding property="creditCardName" />
<binding property="creditCardExpiryMonth" />
<binding property="creditCardExpiryYear" />
</binder>
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
每个绑定还可以应用转换器来格式化模型属性值,以便以自定义方式显示。
如果未指定转换器,则使用 model 属性类型的默认转换器。
以下示例显示了两个binding
元素替换为converter
属性:
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" converter="shortDate" />
<binding property="checkoutDate" converter="shortDate" />
<binding property="creditCard" />
<binding property="creditCardName" />
<binding property="creditCardExpiryMonth" />
<binding property="creditCardExpiryYear" />
</binder>
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
在前面的示例中,shortDate
converter 绑定到checkinDate
和checkoutDate
性能。
您可以使用应用程序的ConversionService
.
如果用户提供的值在表单回发时为 null,则每个绑定还可以应用必需的检查以生成验证错误,如下所示:
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" converter="shortDate" required="true" />
<binding property="checkoutDate" converter="shortDate" required="true" />
<binding property="creditCard" required="true" />
<binding property="creditCardName" required="true" />
<binding property="creditCardExpiryMonth" required="true" />
<binding property="creditCardExpiryYear" required="true" />
</binder>
<transition on="proceed" to="reviewBooking">
<transition on="cancel" to="bookingCancelled" bind="false" />
</view-state>
在前面的示例中,所有绑定都是必需的。 如果绑定了一个或多个空白输入值,则会生成验证错误,并且视图会使用这些错误重新呈现。
13.9. 验证模型
模型验证由针对模型对象指定的约束驱动。 Web Flow 支持以编程方式以及使用 JSR-303 Bean Validation 注解以声明方式强制执行此类约束。
13.9.1. JSR-303 Bean 验证
Web Flow 为 JSR-303 Bean 验证 API 提供了内置支持,构建在 Spring MVC 中提供的等效支持之上。
要启用 JSR-303 验证,请使用 Spring MVC 的LocalValidatorFactoryBean
如下:
<webflow:flow-registry flow-builder-services="flowBuilderServices" />
<webflow:flow-builder-services id="flowBuilderServices" validator="validator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
有了前面的示例,配置的验证器将在数据绑定后应用于所有模型属性。
请注意,JSR-303 bean 验证和按约定验证(将在下一节中解释)并不是互斥的。 换句话说,Web Flow 应用所有可用的验证机制。
部分验证
JSR-303 Bean Validation 支持通过验证组进行部分验证。 以下示例定义部分验证:
@NotNull
@Size(min = 2, max = 30, groups = State1.class)
private String name;
在流程定义中,您可以在视图状态或转换上指定验证提示,这些提示将解析为验证组。 以下示例定义验证提示:
<view-state id="state1" model="myModel" validation-hints="'group1,group2'">
这validation-hints
attribute 是一个表达式,在前面的示例中,该表达式解析为逗号分隔的String
由两个提示组成:group1
和group2
.一个ValidationHintResolver
用于解决这些提示。
这BeanValidationHintResolver
used 尝试将这些字符串解析为基于类的 bean 验证组。
为此,它会在模型或其父级中查找匹配的内部类型。
例如,给定org.example.MyModel
带内部类型Group1
和Group2
,则提供简单的类型名称就足够了 — 即group1
和group2
.
您还可以提供完全限定的类型名称。
值为default
具有特殊含义,并被转换为 Bean Validation 中的默认验证组:jakarta.validation.groups.Default
.
您可以配置自定义ValidationHintResolver
,如有必要,通过validationHintResolver
属性的flow-builder-services
元素,如下所示:
<webflow:flow-registry flow-builder-services="flowBuilderServices" />
<webflow:flow-builder-services id="flowBuilderServices" validator=".." validation-hint-resolver=".." />
13.9.2. 编程验证
有两种方法可以以编程方式执行模型验证。
第一种是在模型对象中实现验证逻辑。
第二种是实现外部Validator
.
这两种方法都会为您提供一个ValidationContext
记录错误消息并访问有关当前用户的信息。
实现模型验证方法
在模型对象中定义验证逻辑是验证其状态的最简单方法。
一旦根据 Web 流约定构建了此类逻辑,Web Flow 就会在view-state
回传生命周期。
Web 流约定要求您通过以下方式构建模型验证逻辑view-state
,用于验证可在该视图上编辑的模型属性的子集。
为此,请创建一个名称为validate${state}
哪里${state}
是 IDview-state
您希望为其运行 Validation。
以下示例执行模型验证:
public class Booking {
private Date checkinDate;
private Date checkoutDate;
...
public void validateEnterBookingDetails(ValidationContext context) {
MessageContext messages = context.getMessageContext();
if (checkinDate.before(today())) {
messages.addMessage(new MessageBuilder().error().source("checkinDate").
defaultText("Check in date must be a future date").build());
} else if (!checkinDate.before(checkoutDate)) {
messages.addMessage(new MessageBuilder().error().source("checkoutDate").
defaultText("Check out date must be later than check in date").build());
}
}
}
在前面的示例中,当在enterBookingDetails
view-state
即编辑Booking
模型,则 Web Flow 会自动调用validateEnterBookingDetails(ValidationContext)
方法,除非已禁止对该转换进行验证。
以下示例显示了这样一个view-state
:
<view-state id="enterBookingDetails" model="booking">
<transition on="proceed" to="reviewBooking">
</view-state>
您可以定义任意数量的验证方法。
通常,流会编辑一系列视图上的模型。
在这种情况下,您将为每个view-state
需要为此运行验证。
实现验证器
执行编程验证的第二种方法是定义一个单独的对象,称为 validator,用于验证您的模型对象。
为此,首先创建一个名称具有 pattern${model}Validator
哪里${model}
是模型表达式的大写形式,例如Booking
.
然后定义一个名称为validate${state}
哪里${state}
是 IDview-state
如enterBookingDetails
.
然后,该类应部署为 Spring Bean。
可以定义任意数量的验证方法。
以下示例定义了这样的验证器:
@Component
public class BookingValidator {
public void validateEnterBookingDetails(Booking booking, ValidationContext context) {
MessageContext messages = context.getMessageContext();
if (booking.getCheckinDate().before(today())) {
messages.addMessage(new MessageBuilder().error().source("checkinDate").
defaultText("Check in date must be a future date").build());
} else if (!booking.getCheckinDate().before(booking.getCheckoutDate())) {
messages.addMessage(new MessageBuilder().error().source("checkoutDate").
defaultText("Check out date must be later than check in date").build());
}
}
}
在前面的示例中,当在enterBookingDetails
view-state
即编辑Booking
模型,则 Web Flow 会自动调用validateEnterBookingDetails(Booking, ValidationContext)
方法,除非已禁止对该转换进行验证。
验证器也可以接受 Spring MVCErrors
对象,这是调用现有 Spring 验证器所必需的。
验证器必须注册为 Spring bean,使用${model}Validator
命名约定,以便自动检测和调用。
在前面的示例中, Spring 类路径扫描将检测@Component
并自动将其注册为名称为bookingValidator
.
然后,每当booking
model 需要验证,则此bookingValidator
实例。
默认验证方法
验证器类还可以定义一个名为validate
不与任何特定的view-state
.
以下示例定义了这样一种方法:
@Component
public class BookingValidator {
public void validate(Booking booking, ValidationContext context) {
//...
}
}
在前面的代码示例中,validate
method 每次调用类型为Booking
进行验证(除非已针对该转换取消验证)。如果需要,除了现有的特定于状态的方法之外,还可以调用 default 方法。
请考虑以下示例:
@Component
public class BookingValidator {
public void validate(Booking booking, ValidationContext context) {
//...
}
public void validateEnterBookingDetails(Booking booking, ValidationContext context) {
//...
}
}
在前面的代码示例中,validateEnterBookingDetails
method 的调用。
默认的validate
method 的调用。
13.9.3. 使用ValidationContext
接口
一个ValidationContext
允许您获取MessageContext
在验证期间录制消息。
它还公开有关当前用户的信息,例如发出信号的userEvent
和当前用户的Principal
身份。
您可以使用此信息根据 UI 中激活的按钮或链接或经过身份验证的用户来自定义验证逻辑。
请参阅 API Javadoc 以获取ValidationContext
了解更多信息。
13.10. 抑制验证
您可以使用validate
属性来禁止对特定视图事件进行模型验证,如下所示:
<view-state id="chooseAmenities" model="booking">
<transition on="proceed" to="reviewBooking">
<transition on="back" to="enterBookingDetails" validate="false" />
</view-state>
在前面的示例中,数据绑定仍然发生在back
,但 validation 被禁止。
13.11. 定义视图过渡
您可以定义一个或多个transition
元素来处理 View 上可能发生的用户事件。
过渡可能会将用户带到另一个视图,或者它可以运行一个动作并重新渲染当前视图。
在处理 Ajax 事件时,过渡也可能请求渲染视图的各个部分(称为“片段”)。
最后,您还可以定义在所有视图之间共享的 “全局” 过渡。
以下各节讨论如何实现视图转换。
13.11.1. 过渡动作
一个view-state
transition 可以在运行之前调用一个或多个作。
这些作可能会返回错误结果,以防止 transition 退出当前view-state
.
如果出现错误结果,视图会重新呈现,并应向用户显示相应的消息。
如果 transition作调用普通 Java 方法,则调用的方法可能会返回一个布尔值,其值 (true
或false
) 指示是应进行过渡还是阻止运行。
方法还可以返回String
其中 Literal 值为success
,yes
或true
指示应发生过渡,任何其他值表示相反。
您可以使用此技术来处理服务层方法引发的异常。
以下示例调用调用服务并处理异常情况的作:
<transition on="submit" to="bookingConfirmed">
<evaluate expression="bookingAction.makeBooking(booking, messageContext)" />
</transition>
public class BookingAction {
public boolean makeBooking(Booking booking, MessageContext context) {
try {
bookingService.make(booking);
return true;
} catch (RoomNotAvailableException e) {
context.addMessage(new MessageBuilder().error().
.defaultText("No room is available at this hotel").build());
return false;
}
}
}
当转换上定义了多个作时,如果一个作返回错误结果,则不会执行集中的其余作。 如果需要确保一个转换作的结果不会影响另一个转换作的执行,请定义一个转换作,该作调用封装所有作逻辑的方法。
13.11.2. 全局转换
您可以使用流的global-transitions
元素创建适用于所有视图的过渡。
全局过渡通常用于处理作为布局一部分的全局菜单链接。
以下示例定义了一个global-transition
元素:
<global-transitions>
<transition on="login" to="login" />
<transition on="logout" to="logout" />
</global-transitions>
13.12. 使用消息
Spring Web Flow 的MessageContext
是一个 API,用于在流程执行过程中记录消息。
您可以将纯文本消息添加到上下文中,以及由 Spring 解析的国际化消息MessageSource
.
消息可由视图呈现,并自动在流执行重定向后继续存在。
提供了三种不同的消息严重性:info
,warning
和error
.
此外,一个方便的MessageBuilder
存在以流畅地构造消息。
13.12.1. 添加纯文本消息
您可以将纯文本消息添加到上下文中。 以下示例显示了如何执行此作:
MessageContext context = ...
MessageBuilder builder = new MessageBuilder();
context.addMessage(builder.error().source("checkinDate")
.defaultText("Check in date must be a future date").build());
context.addMessage(builder.warn().source("smoking")
.defaultText("Smoking is bad for your health").build());
context.addMessage(builder.info()
.defaultText("We have processed your reservation - thank you and enjoy your stay").build());
13.12.2. 添加国际化消息
您可以将国际化(即本地化)消息添加到上下文中。 以下示例显示了如何执行此作:
MessageContext context = ...
MessageBuilder builder = new MessageBuilder();
context.addMessage(builder.error().source("checkinDate").code("checkinDate.notFuture").build());
context.addMessage(builder.warn().source("smoking").code("notHealthy")
.resolvableArg("smoking").build());
context.addMessage(builder.info().code("reservationConfirmation").build());
13.12.3. 使用消息包
国际化消息在 Spring 访问的消息包中定义MessageSource
.
要创建特定于流的消息捆绑包,请定义messages.properties
文件。
创建默认messages.properties
文件和.properties
文件Locale
你需要支持。
以下示例定义了一些消息:
#messages.properties
checkinDate=Check in date must be a future date
notHealthy={0} is bad for your health
reservationConfirmation=We have processed your reservation - thank you and enjoy your stay
在视图或流中,您还可以使用resourceBundle
EL 变量,如下所示:
<h:outputText value="#{resourceBundle.reservationConfirmation}" />
13.12.4. 了解系统生成的消息
Web Flow 本身会在多个位置生成要向用户显示的消息。 发生这种情况的一个重要位置是在视图到模型的数据绑定期间。 当发生绑定错误(例如类型转换错误)时,Web Flow 会将该错误映射到从资源包中自动检索的消息。 为了查找要显示的消息,Web Flow 会尝试包含绑定错误代码和目标属性名称的资源键。
例如,考虑将绑定到checkinDate
属性Booking
对象。
假设用户键入了一个字母字符串。
在这种情况下,会引发类型转换错误。
Web 流将typeMismatch
Error code 添加到消息中,首先在资源包中查询具有以下键的消息:
booking.checkinDate.typeMismatch
键的第一部分是模型类的短名称。 键的第二部分是属性名称。 第三部分是错误代码。 这允许在模型属性的绑定失败时查找唯一消息以向用户显示。 此类消息可能会说:
booking.checkinDate.typeMismatch=The check in date must be in the format yyyy-mm-dd.
如果找不到该形式的此类资源密钥,则尝试更通用的密钥。 此键是错误代码。 属性的字段名称作为 message 参数提供,如下所示:
typeMismatch=The {0} field is of the wrong type.
13.13. 显示弹出窗口
您可以使用popup
属性在模态弹出对话框中呈现视图,如下所示:
<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true">
将 Web Flow 与 Spring Javascript 库一起使用时,不需要客户端代码即可显示弹出窗口。 Web Flow 向客户端发送响应,以请求从弹出窗口重定向到视图,客户端接受该请求。