@Inject不能在AttributeConverter中工作 [英] @Inject not working in AttributeConverter

查看:217
本文介绍了@Inject不能在AttributeConverter中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 AttributeConverter 实现,我试图注入一个必须提供转换逻辑的对象,但是 @Inject 似乎不适用于这种情况。转换器类看起来像这样:

$ $ p $ $ $ c $ @字节[]>
{
@Inject
私人密码加密;

@Override
public byte [] convertToDatabaseColumn(String usrReadable)
{
return crypto.pg_encrypt(usrReadable);
}

@Override
public String convertToEntityAttribute(byte [] dbType)
{
return crypto.pg_decrypt(dbType);


@Converter 被触发后,它会抛出一个 NullPointerException ,因为属性 crypto 没有从容器中初始化。这是为什么?



我使用的是Glassfish 4,在所有其他情况下, @Inject 都可以工作。



在转换器上使用CDI是不可能的?



任何帮助都将被赞赏:






我的问题的口音更多的是AttributeConverter部分。我明白,要让CDI工作,bean必须符合这里描述的条件 http ://docs.oracle.com/javaee/6/tutorial/doc/gjfzi.html
我也尝试通过实现以下构造函数来强制CDI工作:

  @Inject 
public String2ByteArrayConverter(Crypto crypto)
{
this.crypto = crypto;
}

现在我得到了下面的例外,它并不给我任何线索:

  2015-07-23T01:03:24.835 + 0200 |严重:生命周期处理过程中出现异常
org.glassfish .deployment.common.DeploymentException:异常[EclipseLink-28019](Eclipse持久性服务 - 2.5.2.v20140319-9ad6abd):org.eclipse.persistence.exceptions.EntityManagerSetupException
异常说明:PersistenceUnit [PU_VMA]的部署失败。关闭此PersistenceUnit的所有工厂。
内部异常:异常[EclipseLink-7172](Eclipse持久性服务 - 2.5.2.v20140319-9ad6abd):org.eclipse.persistence.exceptions.ValidationException
异常说明:实例化类时遇到错误[类model.converter.String2ByteArrayConverter]。
内部异常:java.lang.InstantiationException:model.converter.String2ByteArrayConverter
在org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createDeployFailedPersistenceException(EntityManagerSetupImpl.java:820)
at org。 eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:760)
...



我甚至试图使用@Producer或@Decorator来让CDI在那个地方工作,但我仍然认为AttributeConverter有一些特定的东西,它不允许CDI。所以问题还没有解决。

CDI 仍然不适用于 AttributeConverter ,这将是最优雅的解决方案,但我找到了令人满意的解决方法。解决方法是使用 @FacesConverter 。不幸的是,每个默认的CDI在 faces转换器验证器 中都不起作用,但是感谢 Apache MyFaces CODI API ,你可以使它不工作 @Advaced 注释:)所以我想出了这样的实现:

  @Advanced 
@FacesConverter(cryptoConverter)
public class CryptoJSFConverter implements Converter
{
private CryptoController crypto = new CryptoController();

@Inject
PatientController ptCtrl;

public Object getAsObject(FacesContext fc,UIComponent uic,String value)
{
if(value!= null)
返回crypto.pg_encrypt(value,ptCtrl。 getSecretKey());
else
返回null;


$ b public String getAsString(FacesContext fc,UIComponent uic,Object object)
{
String res = crypto.pg_decrypt((byte []] )object,ptCtrl.getSecretKey());
return res;




$ b注入的托管bean必须用 @Named 和一些作用域定义。 faces-config.xml 中的声明不起作用!在我的解决方案中,它看起来像这样:

  @Named 
@SessionScoped
公共类PatientController扩展了PersistanceManager
{
...
}

信息在转换器中。在我的情况下,它是会话/用户特定的加密配置。



当然,在这样的解决方案中,很有可能定制 @FacesValidator 也是必要的,但是感谢 CODI ,这里也有可能使用CDI(模拟转换器)。

I have a simple AttributeConverter implementation in which I try to inject an object which have to provide the conversion logic, but @Inject seem not to work for this case. The converter class looks like this:

@Converter(autoApply=false)
public class String2ByteArrayConverter implements AttributeConverter<String, byte[]>
{
    @Inject
    private Crypto crypto;

    @Override
    public byte[] convertToDatabaseColumn(String usrReadable) 
    {
        return crypto.pg_encrypt(usrReadable);
    }

    @Override
    public String convertToEntityAttribute(byte[] dbType)
    {
        return crypto.pg_decrypt(dbType);
    }
}

When the @Converter is triggered it throws an NullPointerException because the property crypto is not being initialized from the container. Why is that?

I'm using Glassfish 4 and in all other cases @Inject works just fine.

Is it not possible to use CDI on converters?

Any help will be appreciated :)


The accent of my question is more the AttributeConverter part. I understand that for the CDI to work a bean must meet the conditions described here http://docs.oracle.com/javaee/6/tutorial/doc/gjfzi.html. I also have tried to force the CDI to work by implementing the following constructor:

@Inject
public String2ByteArrayConverter(Crypto crypto) 
{
    this.crypto = crypto;
}

And now I got the following exception which doesn't give me any clue:

2015-07-23T01:03:24.835+0200|Severe: Exception during life cycle processing
org.glassfish.deployment.common.DeploymentException: Exception [EclipseLink-28019] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Deployment of PersistenceUnit [PU_VMA] failed. Close all factories for this PersistenceUnit.
Internal Exception: Exception [EclipseLink-7172] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Error encountered when instantiating the class [class model.converter.String2ByteArrayConverter].
Internal Exception: java.lang.InstantiationException: model.converter.String2ByteArrayConverter
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.createDeployFailedPersistenceException(EntityManagerSetupImpl.java:820)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:760)
...

I even tried using @Producer or @Decorator in order to have the CDI working on that place, but I still think there is something specific with the AttributeConverter which doesn't allow CDI. So problem not solved yet.

解决方案

Well, CDI still doesn't work for AttributeConverter, which would be the most elegant solution, but I have found a satisfying workaround. The workaround is using @FacesConverter. Unfortunately per default CDI doesn't work in faces converters and validators either, but thanks to the Apache MyFaces CODI API you can make it work unsing the @Advaced annotation :) So I came up with an implementation like this:

@Advanced
@FacesConverter("cryptoConverter")
public class CryptoJSFConverter implements Converter
{
    private CryptoController crypto = new CryptoController();

    @Inject
    PatientController ptCtrl;

    public Object getAsObject(FacesContext fc, UIComponent uic, String value) 
    {
        if(value != null)
            return crypto.pg_encrypt(value, ptCtrl.getSecretKey());
        else
            return null;
     }


    public String getAsString(FacesContext fc, UIComponent uic, Object object) 
    {
        String res = crypto.pg_decrypt((byte[]) object, ptCtrl.getSecretKey());
        return res;
    }   
}

The injected managed bean has to be explicitly annotated with @Named and some scope definition. A declaration in faces-config.xml doesn't work! In my solution it looks like this:

@Named
@SessionScoped
public class PatientController extends PersistanceManager
{
   ...
}

Now one has a context information in the converter. In my case it is session/user specific cryptography configuration.

Of course in such a solution it is very likely that a custom @FacesValidator is also needed, but thanks to CODI one have the possibility for using CDI here also (analog to converter).

这篇关于@Inject不能在AttributeConverter中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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