参数< f:viewParam>和CDI的FacesConverter [英] parameter with <f:viewParam> and FacesConverter from CDI

查看:109
本文介绍了参数< f:viewParam>和CDI的FacesConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不清楚为什么我会得到这个特殊的例外,这是我认为的一个红鲱鱼。根本问题可能与异常的最后一行有关: MessageConverter.getAsObject..0 实际上应该是1501(消息ID)。那么,为什么MessageConverter.getAsObject有错误的ID?我认为这可能与Detail构造函数有关,它可能将错误的参数传递给MessageConvert.getAsObject (),特别是UIComponent对象 - 可能需要实例化引用。



相关EL:

 < h:outputLink id =link1value =detail.xhtml> 
< f:param name =idvalue =#{m.getMessageNumber()}/>
< h:outputText value =#{m.getMessageNumber()}/>
< / h:outputLink>

glassfish显示:

  INFO:MessageConverter.getAsObject..1501 
INFO:SingletonNNTP.forward..11
警告:1501
java.lang.ArrayIndexOutOfBoundsException:1501
at java .util.Arrays $ ArrayList.get(Arrays.java:2866)
at net.bounceme.dur.nntp.SingletonNNTP.getMessage(SingletonNNTP.java:86)
at net.bounceme.dur.nntp .MessageConverter.getAsObject(MessageConverter.java:21)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:171)
at javax.faces.component.UIViewParameter.getConvertedValue (UIViewParameter.java:394)
在javax.faces.component.UIInput.validate(UIInput.java:960)
在javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
at javax.faces.component.UIInput.processValidators(UIInput.java:698)
at javax.faces.component.UIViewParameter.processValidators(UIViewParameter.java:273)
在javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
在javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
在javax.faces.component.UIViewRoot .processValidators(UIViewRoot.java:1172)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase .java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
位于org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
位于org.apache。 catalina.core.St andardPipeline.invoke(StandardPipeline.java:595)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
at org.apache.catalina.connector.CoyoteAdapter.doService( CoyoteAdapter.java:331)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper $ AdapterCallable。在com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)上调用(ContainerMapper.java:317)
在com.sun.grizzly.http.ProcessorTask上
。 invokeAdapter(ProcessorTask.java:849)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask。 java:1045)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
在com.sun.grizzly.Def aultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain。
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532)
at com.sun .grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513)$ b $在java.lang.Thread.run(Thread.java:722)

INFO:MessageConverter.getAsObject。 .0
INFO:SingletonNNTP.forward..11

MessageConverter,我认为这个类到目前为止它是好的:

  package net.bounceme.dur.nntp; 

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.mail.Message;

@FacesConverter(messageConverter)
公共类MessageConverter实现Converter {

private static final Logger logger = Logger.getLogger(MessageConverter.class.getName() );
private static final Level level = Level.INFO;
private SingletonNNTP nntp = SingletonNNTP.INSTANCE;

@Override
public Object getAsObject(FacesContext context,UIComponent component,String value){
logger.log(level,MessageConverter.getAsObject .. {0},value );
Message message = nntp.getMessage(Integer.parseInt(value));
返回消息;

$ b @Override
public String getAsString(FacesContext context,UIComponent component,Object value){
Message message =(Message)value;
return String.valueOf(message.getMessageNumber());




$ b

这是带有构造函数的问题类Detail, ,特别是怀疑:

  package net.bounceme.dur.nntp; 

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.mail.Message;

@Named
public class Detail {b
$ b private static final Logger logger = Logger.getLogger(Detail.class.getName());
private static final Level level = Level.INFO;
private int id = 0;
私人消息消息= null;
private SingletonNNTP nntp = SingletonNNTP.INSTANCE;

public Detail(){
MessageConverter mc = new MessageConverter();
FacesContext fc = FacesContext.getCurrentInstance();
String value = String.valueOf(id);
UIComponent ui = null;
Object obj = mc.getAsObject(fc,ui,value);
message =(Message)obj;

$ b $ public int forward(){
logger.log(level,Detail.forward .. {0},id);
id = id + 1;
logger.log(level,..Detail.forward {0},id);
return id;


public int back(){
logger.log(level,Detail.back .. {0},id);
id = id - 1;
logger.log(level,..Detail.back {0},id);
return id;
}

public Message getMessage(){
return message;
}

public String getContent()throws Exception {
return message.getContent()。toString();


$ / code $ / pre
$ b $参考:

viewparam-vs-managedpropertyvalue-param-id 其中没有'因为我正在使用CDI,@Named,所以不能使用@ManagedProperty,这是真正的问题。我想我没有看到CDI的好处,因为@ManagedProperty看起来很不错。


$ b ProcessingGETRequestParameters 有一个关键段落:


是的,这是@ManagedBean而不是@FacesConverter!有多么尴尬,但
无法在@FacesConverter中以
的顺序注入@EJB来执行数据库交互作业。当您使用
CDI @Inject注入一个属性时,会出现同样的问题,您需要使用@Name来代替@FacesConverter的
。 Java EE / JSF / CDI团队正在为未来的JSF 2.2版本开发这个工具,另请参阅JSF规范问题763.如果您确实
需要将其作为@FacesConverter(为了例如,利用
forClass属性),那么您总是可以从JNDI手动获取
EJB。

对于我来说,这可能与EJB有关,可能会略微偏离主题。然而,也许这是我遇到的确切难度?解析方案

转换器应该用于< F:viewParam>

 < f:viewParam name =idvalue =#{detail.message}converter =messageConverter/ > 

这将基本上将请求参数 id 将对象 Message ,然后将其设置在#{detail.message} 后面的属性中。你只应该在 Detail 类中为它提供一个setter,我没有在你的bean中看到任何一个。



您不应在 Detail 类的构造函数中执行转换作业。您应该只有 Message 属性,而不是 id nntp 。删除整个构造函数。

  @Named 
public class详细信息{
$ b $ private消息消息;

// Getters + setters + actions
}


It's not clear to me why I'm getting this particular exception, it's a red-herring I think. The underlying problem could be related to the last line of the exception: MessageConverter.getAsObject..0 which should actually be 1501 (the Message ID). So, why does MessageConverter.getAsObject have the wrong id?

I think that this could be related to the Detail constructor, which is probably passing the wrong parameters to MessageConvert.getAsObject(), in particular the UIComponent object -- probably that reference needs to get instantiated.

relevant EL:

        <h:outputLink id="link1" value="detail.xhtml">
            <f:param name="id" value="#{m.getMessageNumber()}" />
             <h:outputText value="#{m.getMessageNumber()}" />
        </h:outputLink>

glassfish shows:

INFO: MessageConverter.getAsObject..1501
INFO: SingletonNNTP.forward..11
WARNING: 1501
java.lang.ArrayIndexOutOfBoundsException: 1501
    at java.util.Arrays$ArrayList.get(Arrays.java:2866)
    at net.bounceme.dur.nntp.SingletonNNTP.getMessage(SingletonNNTP.java:86)
    at net.bounceme.dur.nntp.MessageConverter.getAsObject(MessageConverter.java:21)
    at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:171)
    at javax.faces.component.UIViewParameter.getConvertedValue(UIViewParameter.java:394)
    at javax.faces.component.UIInput.validate(UIInput.java:960)
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
    at javax.faces.component.UIInput.processValidators(UIInput.java:698)
    at javax.faces.component.UIViewParameter.processValidators(UIViewParameter.java:273)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
    at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172)
    at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722)

INFO: MessageConverter.getAsObject..0
INFO: SingletonNNTP.forward..11

MessageConverter, I think that this class is fine so far is it goes:

package net.bounceme.dur.nntp;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.mail.Message;

@FacesConverter("messageConverter")
public class MessageConverter implements Converter {

    private static final Logger logger = Logger.getLogger(MessageConverter.class.getName());
    private static final Level level = Level.INFO;
    private SingletonNNTP nntp = SingletonNNTP.INSTANCE;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        logger.log(level, "MessageConverter.getAsObject..{0}", value);
        Message message = nntp.getMessage(Integer.parseInt(value));
        return message;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        Message message = (Message) value;
        return String.valueOf(message.getMessageNumber());
    }
}

This is the problem class, Detail, with the constructor, in particular, being suspect:

package net.bounceme.dur.nntp;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.mail.Message;

@Named
public class Detail {

    private static final Logger logger = Logger.getLogger(Detail.class.getName());
    private static final Level level = Level.INFO;
    private int id = 0;
    private Message message = null;
    private SingletonNNTP nntp = SingletonNNTP.INSTANCE;

    public Detail() {
        MessageConverter mc = new MessageConverter();
        FacesContext fc = FacesContext.getCurrentInstance();
        String value = String.valueOf(id);
        UIComponent ui = null;
        Object obj = mc.getAsObject(fc, ui, value);
        message = (Message) obj;
    }

    public int forward() {
        logger.log(level, "Detail.forward..{0}", id);
        id = id + 1;
        logger.log(level, "..Detail.forward {0}", id);
        return id;
    }

    public int back() {
        logger.log(level, "Detail.back..{0}", id);
        id = id - 1;
        logger.log(level, "..Detail.back {0}", id);
        return id;
    }

    public Message getMessage() {
        return message;
    }

    public String getContent() throws Exception {
        return message.getContent().toString();
    }
}

reference:

viewparam-vs-managedpropertyvalue-param-id which doesn't quite seem to apply as I'm using CDI, @Named, and so cannot use @ManagedProperty, which is the "real" problem. I suppose I'm not seeing the CDI benefit, as @ManagedProperty looks very nice.

ProcessingGETRequestParameters has a, perhaps, key paragraph:

Yes, it's a @ManagedBean instead of @FacesConverter! How awkward, but it's not possible to inject an @EJB inside a @FacesConverter in order to do the DB interaction job. The same problem manifests when you use the CDI @Inject to inject a property, you'd need to use @Named instead of @FacesConverter. The Java EE/JSF/CDI guys are working on that for the future JSF 2.2 version, see also JSF spec issue 763. If you really need to have it to be a @FacesConverter (in order to utilize the forClass attribute, for example), then you can always manually grab the EJB from JNDI. See also the next chapter.

which, is, for my purposes, perhaps slightly off-topic as it's EJB related. However, perhaps that is the exact difficulty which I'm encountering?

解决方案

The converter is supposed to be used in the <f:viewParam>.

<f:viewParam name="id" value="#{detail.message}" converter="messageConverter" />

This will basically convert the request parameter id to object Message and then set it in the property behind #{detail.message}. You should only supply a setter for it in the Detail class, I don't see any one in your bean.

You should not do the conversion job in the constructor of Detail class. You should only have a Message property, not the id or nntp. Remove the entire constructor.

@Named
public class Detail {

    private Message message; 

    // Getters+setters+actions
}

这篇关于参数&lt; f:viewParam&gt;和CDI的FacesConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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