getAsString()jsf customed转换器无法转换对象 [英] getAsString() jsf customed converter fails to convert object

查看:164
本文介绍了getAsString()jsf customed转换器无法转换对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为jsf创建了一个自定义转换器。 getAsObject()工作正常,但getAsString()返回异常。我不确定问题出在哪里,我尝试以不同的方式将对象转换为字符串,但它一直在返回异常。

I created a custom converter for jsf. The getAsObject() works perfect but the getAsString() is returning an exception. I am not really sure where the problem is, and I have tried converting the object to string in different ways, but it keeps on returning exception.

这是我的转换器代码:

This my converters code:

    @Named
public class ProductConverter implements Converter{

    @EJB
    private ProductEJB productEjb;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if(value== null )
        {
            throw new ConverterException("There was an error at getAsObject()");
        }

        int id = Integer.parseInt(value);
        return productEjb.findProductById(id);
    }

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

        if (value == null || value.equals("")) 
        {
            return "";            
        }
        else
        {
            Integer id = ((Product)value).getProduct_id();
            return String.valueOf(id);
        }

    }

}

这是Product类(为简单起见,排除了Getters / Setters / equals()/ hash()):

This is the Product class (Getters/Setters/equals()/hash() excluded for simplicity):

@Entity
@NamedQueries({
    @NamedQuery(name="findAllProducts", query = "SELECT p from Product p")

})
public class Product implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue(strategy= GenerationType.AUTO)
    private int product_id;
    private String name;
    private String description;
    protected byte[] imageFile;
    private Float price;
    @Temporal(TemporalType.TIMESTAMP)
    private Date dateAdded;        
    @ManyToOne
    private Category category_fk;
    @ManyToOne
    private SaleDetails saleDetails_fk;

这是我得到的堆栈:

java.lang.NumberFormatException: For input string: ""
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:504)
    at java.lang.Integer.parseInt(Integer.java:527)
    at com.lv.Controllers.Converters.ProductConverter.getAsObject(ProductConverter.java:30)
    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:1550)
    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:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    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)

这是我使用转换器的jsf:

This is the jsf where I am using the converter:

<f:metadata>
    <f:viewParam name="product" value="#{productDelete.product}" converter="#{productConverter}"/>
</f:metadata>


推荐答案

在<$ c时不要抛出异常$ c> null 或收到空值。这毫无意义。它们可能代表合法有效的值,它们只代表无价值。然后返回 null 。如果您想强制要求,那么您应该使用 required =true代替或任何自定义 Validator ,但只是不要在转换器中这样做。

Just don't throw an exception when null or an empty value is received. This makes no sense. They may represent legitimately valid values which just represent "no value". Just return null then. If you'd like to force requireness, then you should be using required="true" instead or any custom Validator, but just don't do that in a Converter.

只有当值真正不可转换时,才应抛出 ConverterException 。我已经改进了你的转换器来做到这一点。您不是检查提交的值是否为有效数字,也不是检查获得的模型值是 Product 的实例。否则会导致 NumberFormatException ClassCastException 在代码中进一步向下,你应该事先通过抛出相应的 ConverterException

You should throw the ConverterException only when the value is really unconvertable. I've improved your converter to do exactly that. You are namely not checking if the submitted value is a valid number nor if the obtained model value is an instance of Product. It would otherwise have caused NumberFormatException or ClassCastException further down in the code which you should have prevented beforehand by throwing the appropriate ConverterException.

@Named
public class ProductConverter implements Converter {

    @EJB
    private ProductEJB productEjb;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        if (!value.matches("\\d+")) {
            throw new ConverterException("The value is not a valid ID number: " + value);
        }

        int id = Integer.parseInt(value);
        return productEjb.findProductById(id);
        // You may want to perform an additional check if it didn't return null
        // and otherwise throw ConverterException with "unknown Product ID".
    }

    @Override    
    public String getAsString(FacesContext context, UIComponent component, Object value) {        
        if (value == null) {
            return null; // Or an empty string, can also.
        }

        if (!(value instanceof Product)) {
            throw new ConverterException("The value is not a valid Product: " + value);
        }

        Integer id = ((Product)value).getProduct_id();
        return (id != null) ? String.valueOf(id) : null;
    }

}

这篇关于getAsString()jsf customed转换器无法转换对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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