通用 JSF 实体转换器 [英] Generic JSF entity converter

查看:18
本文介绍了通用 JSF 实体转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写我的第一个 Java EE 6 Web 应用程序作为学习练习.我没有使用框架,只是使用 JPA 2.0、EJB 3.1 和 JSF 2.0.

我有一个自定义转换器将存储在 SelectOne 组件中的 JPA 实体转换回实体.我正在使用 InitialContext.lookup 来获取对会话 Bean 的引用以查找相关实体.

我想创建一个通用的实体转换器,这样我就不必为每个实体创建一个转换器.我想我会创建一个抽象实体并让所有实体扩展它.然后为抽象实体创建一个自定义转换器,并将其用作所有实体的转换器.

这听起来合理和/或可行吗?

没有抽象实体,只是一个转换任何实体的转换器是否更有意义?在那种情况下,我不确定如何获得对适当会话 Bean 的引用.

我已经包含了我当前的转换器,因为我不确定我是否以最有效的方式获得了对我的会话 Bean 的引用.

package com.mycom.rentalstore.converters;导入 com.mycom.rentalstore.ejbs.ClassificationEJB;导入 com.mycom.rentalstore.entities.Classification;导入 javax.faces.application.FacesMessage;导入 javax.faces.component.UIComponent;导入 javax.faces.context.FacesContext;导入 javax.faces.convert.Converter;导入 javax.faces.convert.ConverterException;导入 javax.faces.convert.FacesConverter;导入 javax.naming.InitialContext;导入 javax.naming.NamingException;@FacesConverter(forClass = Classification.class)公共类 ClassificationConverter 实现 Converter {私有 InitialContext ic;私有分类EJB 分类EJB;@覆盖公共对象 getAsObject(FacesContext 上下文,UIComponent 组件,字符串值){尝试 {ic = 新的 InitialContext();categoryEJB = (ClassificationEJB) ic.lookup("java:global/com.mycom.rentalstore_RentalStore_war_1.0-SNAPSHOT/ClassificationEJB");} catch (NamingException e) {throw new ConverterException(new FacesMessage(String.format("无法获得 InitialContext - %s", e)), e);}尝试 {返回分类EJB.getClassificationById(Long.valueOf(value));} 捕获(异常 e){throw new ConverterException(new FacesMessage(String.format("Cannot convert %s to Classification - %s", value, e)), e);}}@覆盖public String getAsString(FacesContext 上下文,UIComponent 组件,对象值){return String.valueOf(((Classification) value).getId());}}

解决方案

我今天遇到了同样的问题,我通过创建一个通用的 ConversionHelper 并在转换器中使用它来解决它.为此,我有一个 EntityService,它是一个通用的 SLSB,我用它来为任何实体类型执行简单的 CRUD 操作.我的实体也实现了一个 PersistentEntity 接口,它有一个 getId 和 setId 方法,我用简单的主键保存它们.就是这样.

最后我的转换器看起来像这样:

<前><代码>@FacesConverter(value = "userConverter", forClass = User.class)公共类 UserConverter 实现 Converter {@覆盖public Object getAsObject(FacesContext ctx, UIComponent 组件, java.lang.String 值) {返回 ConversionHelper.getAsObject(User.class, value);}@覆盖public String getAsString(FacesContext ctx, UIComponent 组件, 对象值) {返回 ConversionHelper.getAsString(value);}}

我的转换助手看起来像这样:

<前><代码>公共最终类 ConversionHelper {私人转换助手(){}public static T getAsObject(Class returnType, String value) {如果(返回类型== null){throw new NullPointerException("尝试使用 null 返回类型获取 getAsObject.");}如果(值 == 空){throw new NullPointerException("试图用一个空值来获取AsObject.");}长 id = null;尝试 {id = Long.parseLong(value);} catch (NumberFormatException e) {throw new ConverterException("试图以错误的id格式获取getAsObject.");}尝试 {上下文initialContext = new InitialContext();EntityService entityService = (EntityService) initialContext.lookup("java:global/myapp/EntityService");T 结果 = (T) entityService.find(returnType, id);返回结果;} catch (NamingException e) {throw new ConverterException("EntityService 未找到.");}}公共静态字符串 getAsString(对象值){如果(PersistentEntity 的值实例){PersistentEntity 结果 = (PersistentEntity) 值;返回 String.valueOf(result.getId());}返回空;}}

现在为简单的 JPA 实体创建转换器是一个复制转换器并更改 3 个参数的问题.

这对我来说效果很好,但我不知道这是否是风格和性能方面的最佳方法.任何提示将不胜感激.

I'm writing my first Java EE 6 web app as a learning exercise. I'm not using a framework, just JPA 2.0, EJB 3.1 and JSF 2.0.

I have a Custom Converter to convert a JPA Entity stored in a SelectOne component back to an Entity. I'm using an InitialContext.lookup to obtain a reference to a Session Bean to find the relevant Entity.

I'd like to create a generic Entity Converter so I don't have to create a converter per Entity. I thought I'd create an Abstract Entity and have all Entities extend it. Then create a Custom Converter for the Abstract Entity and use it as the converter for all Entities.

Does that sound sensible and/or practicable?

Would it make more sense not to have an abstract entity, just a converter that converts any entity? In that case I'm not sure how I'd obtain a reference to the appropriate Session Bean.

I've included my current converter because I'm not sure I'm obtaining a reference to my Session Bean in the most efficient manner.

package com.mycom.rentalstore.converters;

import com.mycom.rentalstore.ejbs.ClassificationEJB;
import com.mycom.rentalstore.entities.Classification;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import javax.naming.InitialContext;
import javax.naming.NamingException;

@FacesConverter(forClass = Classification.class)
public class ClassificationConverter implements Converter {

    private InitialContext ic;
    private ClassificationEJB classificationEJB;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {

        try {
            ic = new InitialContext();
            classificationEJB = (ClassificationEJB) ic.lookup("java:global/com.mycom.rentalstore_RentalStore_war_1.0-SNAPSHOT/ClassificationEJB");

        } catch (NamingException e) {
            throw new ConverterException(new FacesMessage(String.format("Cannot obtain InitialContext - %s", e)), e);
        }

        try {
            return classificationEJB.getClassificationById(Long.valueOf(value));
        } catch (Exception e) {
            throw new ConverterException(new FacesMessage(String.format("Cannot convert %s to Classification - %s", value, e)), e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return String.valueOf(((Classification) value).getId());
    }
}

解决方案

Well I had the same problem today, and I solved it by creating a generic ConversionHelper and using it in the converter. For this purpose I have an EntityService which is a generic SLSB that I use to perform simple CRUD operations for any entity type. Also my entities implement a PersistentEntity interface, which has a getId and setId methods and I keep them with simple primary keys. That's it.

In the end my converter looks like this:


@FacesConverter(value = "userConverter", forClass = User.class)
public class UserConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext ctx, UIComponent component, java.lang.String value) {

        return ConversionHelper.getAsObject(User.class, value);
    }

    @Override
    public String getAsString(FacesContext ctx, UIComponent component, Object value) {

        return ConversionHelper.getAsString(value);
    }
}

And my conversion helper looks like this:


public final class ConversionHelper {

    private ConversionHelper() {
    }

    public static <T> T getAsObject(Class<T> returnType, String value) {

        if (returnType== null) {

            throw new NullPointerException("Trying to getAsObject with a null return type.");
        }

        if (value == null) {

            throw new NullPointerException("Trying to getAsObject with a null value.");
        }

        Long id = null;

        try {

            id = Long.parseLong(value);

        } catch (NumberFormatException e) {

            throw new ConverterException("Trying to getAsObject with a wrong id format.");
        }

        try {

            Context initialContext = new InitialContext();
            EntityService entityService = (EntityService) initialContext.lookup("java:global/myapp/EntityService");

            T result = (T) entityService.find(returnType, id);

            return result;

        } catch (NamingException e) {

            throw new ConverterException("EntityService not found.");
        }
    }

    public static String getAsString(Object value) {

        if (value instanceof PersistentEntity) {

            PersistentEntity result = (PersistentEntity) value;

            return String.valueOf(result.getId());
        }

        return null;
    }
}

Now creating converters for simple JPA entities is a matter of duplicate a converter and change 3 parameters.

This is working well for me, but I don't know if it is the best approach in terms of style and performance. Any tips would be appreciated.

这篇关于通用 JSF 实体转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆