如何在 JSF 2 中创建自定义转换器?

2023-12-22

我有一个名为“操作”的实体:

@Entity
@Table(name="operation")
public class Operation implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private Integer id;

    @NotNull(message="informe um tipo de operação")
    private String operation;

    //bi-directional many-to-one association to Product
    @OneToMany(mappedBy="operation")
    private List<Product> products;

    // getter and setters
}

我以这种方式检索操作:(可以通过 EJB 实例,但只是为了将其保留在本地并作为示例,好吗?;))

public Map<String, Object> getOperations() {
    operations = new LinkedHashMap<String, Object>();
    operations.put("Select an operation", new Operation());
    operations.put("Donation", new Operation(new Integer(1), "donation"));
    operations.put("Exchange", new Operation(new Integer(2), "exchange"));

    return operations;
}

所以我试图在这个中获取选定的操作selectOneMenu:

The productc is a ManagedBean其中有一个viewScope, productb是一个 ManagedBean,具有sessionScope其中有一个product这是我的实体。该产品含有一个operation,所以是这样的:

(这封信c有控制的意思,所有与我的实体产品相关的操作都应该由这个bean来处理,好吗?)

Product productc (ViewScope) 
-- ProductBean productb (SessionScope)
---- Product product (Entity)
-------- Operation operation (Entity)

转换器与之前建议的@BalusC相同:

@ManagedBean
@RequestScoped
public class OperationConverter implements Converter {

    @EJB
    private EaoOperation operationService;

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (!(value instanceof Operation) || ((Operation) value).getId() == null) {
            return null;
        }

        return String.valueOf(((Operation) value).getId());
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || !value.matches("\\d+")) {
            return null;
        }

        Operation operation = operationService.find(Integer.valueOf(value));
        System.out.println("Getting the operation value = " + operation.getOperation() );

        if (operation == null) {
            throw new ConverterException(new FacesMessage("Unknown operation ID: " + value));
        }

        return operation;
    }

检索日志中显示的所选操作:

FINE: SELECT ID, OPERATION FROM operation WHERE (ID = ?)
    bind => [1 parameter bound]
INFO: Getting the operation value = exchange

因此,当我尝试提交表单时出现以下错误:

form_add_product:operation: Validation error: the value is not valid

为什么会发生这种情况?


您正在尝试将一个复杂的对象作为 HTTP 请求参数传递,该参数只能是String。 JSF/EL 具有用于原语及其包装器的内置转换器(例如int, Integer)甚至枚举。但对于所有其他类型,您确实需要编写一个自定义转换器。在这种情况下,您需要编写一个转换器来在之间进行转换String and Operation. The String然后用作选项值(在浏览器中打开页面,右键单击并查看源代码并注意<option value>). The Operation然后用作模型值。这String应唯一标识Operation目的。您可以为此使用操作 ID。

但在这种特殊情况下,有了这样一个硬编码的地图和一个相对简单的模型,我认为使用enum反而。

public enum Operation {

    DONATION("Donation"), EXCHANGE("Exchange");

    private String label;

    private Operation(String label) {
        this.label = label;
    }

    public string getLabel() {
        return label;
    }

}

with

private Operation operation; // +getter +setter

public Operation[] getOperations() {
    return Operation.values();
}

and

<h:selectOneMenu value="#{bean.operation}">
    <f:selectItems value="#{bean.operations}" var="operation" itemValue="#{operation}" itemLabel="#{operation.label}" />
</h:selectOneMenu>

但如果这些值有actually要从数据库中检索并且其大小未定义,那么您仍然需要一个自定义转换器。你可以在getAsString()返回 ID 并输入getAsObject()使用操作 DAO/EJB 来获取Operation通过身份证件。

@ManagedBean
@RequestScoped
public class OperationConverter implements Converter {

    @EJB
    private OperationService operationService;

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        // Convert here Operation object to String value for use in HTML.
        if (!(value instanceof Operation) || ((Operation) value).getId() == null) {
            return null;
        }

        return String.valueOf(((Operation) value).getId());
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        // Convert here String submitted value to Operation object.
        if (value == null || !value.matches("\\d+")) {
            return null;
        }

        Operation operation = operationService.find(Long.valueOf(value));

        if (operation == null) {
            throw new ConverterException(new FacesMessage("Unknown operation ID: " + value));
        }

        return operation;
    }

}

使用方法如下:

<h:selectOneMenu ... converter="#{operationConverter}">

至于为什么它是一个@ManagedBean代替@FacesConverter, 读这个:转换并验证 GET 请求参数 http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#ConvertingAndValidatingGETRequestParameters.


Update至于Validation Error: value not valid错误,这意味着equals()的方法Operation类损坏或丢失。在验证期间,JSF 将提交的值与可用值列表进行比较Object#equals()。如果列表中没有一个与提交的值匹配,那么您将看到此错误。所以,请确保equals()得到正确实施。这是一个通过数据库技术特性进行比较的基本示例。

public boolean equals(Object other) {
    return (other instanceof Operation) && (id != null) 
         ? id.equals(((Operation) other).id) 
         : (other == this);
}

不要忘记实施hashCode()还有:

public int hashCode() {
    return (id != null) 
         ? (getClass().hashCode() + id.hashCode())
         : super.hashCode();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 JSF 2 中创建自定义转换器? 的相关文章

随机推荐

  • 将可绘制资源图像转换为位图

    我正在尝试使用Notification Builder setLargeIcon bitmap 需要一个位图图像 我的可绘制文件夹中有要使用的图像 那么如何将其转换为位图 你可能的意思是Notification Builder setLar
  • python 多个 json 字典

    我有一个包含多个 json 字典的 json 文件 格式如下 x 1 y 2 z 3 x 2 y 3 z 4 x 3 y 4 z 5 如何将其转换为一种 json 字典格式 如下所示 items x 1 y 2 z 3 x 2 y 3 z
  • 为什么在 EmailJS 中添加服务时出现错误?

    我在尝试在电子邮件 JS 中配置服务时收到 412 Gmail API 请求的身份验证范围不足 此外 在使用 React js 库发送电子邮件时收到相同的错误 下面是错误的屏幕截图 添加服务时图像显示错误 https i stack img
  • php switch case 语句来处理范围

    我正在解析一些文本并根据一些规则计算权重 所有角色都具有相同的权重 这会使 switch 语句变得非常长 我可以在 case 语句中使用范围吗 我看到其中一个提倡关联数组的答案 weights array a z A Z gt 10 0 9
  • C++ 丢弃限定符

    我有这个错误 BSPArduino cpp 316 错误 将 const BSPArduino 传递为 this virtual void BSPArduino enableWdt const 的参数 WATCHDOG TIMER DELA
  • Java 应用程序如何部署在“现实世界”中?

    作为 Java 编程世界的新手 这个问题一直困扰着我 我首先相信所有的Java文件都被压缩成applets然后就跑了 但我很快意识到情况并非总是如此 有人可以向我解释一下我们如何将 Java 应用程序融入到日常生活的真实产品中吗 TL DR
  • g++ -std=c++0x 出现意外编译问题

    使用 g std c 0x 编译时 我遇到一些编译问题 将 T 类型的元素推回向量 这是一个最小的例子 include
  • Shell 脚本 If [ -f ./file ]

    我正在自学 shell 脚本 我正在研究如何执行 If 但我不明白一个例子 if f NAME tar then do something else something else 现在我做了一些实验 我给 NAME 提供了我目录中的一个文件
  • 使用 SimpleXMLElement 从对象获取数组

    我在获取这些对象中的数组时遇到一些问题 当我 print r 时 会打印以下代码 message object 是对象的名称 SimpleXMLElement Object header gt SimpleXMLElement Object
  • 在 iOS 中绘制多点路线

    我正在尝试在提供的地图应用程序中显示具有多个点的路线 我已经弄清楚如何显示以下两点之间的路线这个帖子 https stackoverflow com q 4609340 620197 我正在建立以下多个点的列表这些方向 http mapki
  • 从旋转的 UIImageView 创建 UIImage

    我有一个 UIImageView 里面有一张图片 我在显示之前通过将 UIImageView 的变换属性设置为 CGAffineTransformMakeRotation angle 来旋转图像 其中 angle 是以弧度为单位的角度 我希
  • 从 LAN 网络中的另一台 PC 访问 Wamp 2.5 phpmyadmin

    我可以从另一台电脑访问 wamp localhost 但是从这台电脑访问 phpmyadmin 时我无法访问如下图 在 WAMPServer 上 配置了 phpMyAdmin 工具 以便除了运行 WAMPServer 的 IP 之外 无法从
  • 如何使用 Angular 的 ngFor 实现项目重新排序/随机播放动画?

    Vue 用户很容易实现这样的 item shuffle 动画 请参阅他们的官方文档 我搜索了很多 但找不到适合 Angular 用户的解决方案 ngFor似乎在洗牌时切换项目内容而不是移动项目 这是我的演示 http embed plnkr
  • 在 PHP 中获取给定一周的开始天和结束天

    我正在尝试使用星期日作为开始日期和参考日期来获取周范围 例如 date 但我似乎无法弄清楚 例如 如果 date 为 2009 05 01 我将得到 2009 04 26 和 2009 05 02 2009 05 10 将产生 2009 0
  • ember 中具有多个步骤的手风琴向导

    我正在使用 ember 构建一个 巫师手风琴 基本上我想要的是 始终显示的手风琴 手风琴包含所有步骤 一个步骤处于活动状态 但也可能更改先前步骤的标题 每个步骤都有自己的模型 例如 第一步从国家 地区中选择 第二步从产品中选择 应该可以在步
  • UIView autoresizingMask问题

    在 iPad 中 我有一个 UIViewController 里面有另一个 UIview 位于底部 UIView Controller X UIView 是 X 我在 UIViewController 的 viewDidLoad 上为其定义
  • 数据库设计中的多对多关系

    我目前有一个数据库 其中有两个表 分别称为 Articles 和 Tags 为了允许文章属于多个类别 我有多对多的关系 这样的设计从性能上来说是不是一个错误呢 或者我应该删除这两个表之间的关系并添加第三个表作为桥梁 articlesTags
  • 如何在单击按钮时通过动画显示视图?

    我是编码新手 我正在制作一个应用程序 我需要在单击按钮时显示一个视图 并且该视图应该看起来像是来自按钮本身 再次单击该按钮时 视图应返回到按钮 动画 我有翻转 卷曲等动画 但我不知道该怎么做 这是一个简单的例子 放showView 作为按钮
  • 如何访问django项目之外的目录文件?

    我的 Django 项目在 RHEL 7 操作系统上运行 项目在路径中 root project 项目托管在 httpd 服务器上 现在我正在尝试访问目录之外的文件 例如 root data info test txt 我应该如何访问vie
  • 如何在 JSF 2 中创建自定义转换器?

    我有一个名为 操作 的实体 Entity Table name operation public class Operation implements Serializable private static final long seria