错误可迭代实现GWTP-Rest Jackson

时间:2014-08-05 14:09:36

标签: gwt jackson gwtp iterable

我使用GWT 2.6.1和GWTP-Rest Api,当我编译时,我收到一个错误。

我的课程页面实现了Iterable&序列化。这个类来自spring框架,但适用于GWT(这个类由另一个与RPC一起使用的项目使用。错误来自另一个实现相同接口的类“Sort”。请参阅下面的代码。

错误来自创建例外的com.github.nmorel.gwtjackson.rebind.ObjectMapperGenerator

如果删除Iterator的{​​{1}}实施,则不会发生错误。

控制台出错:

OrderMobile

排序代码:

Creating deserializer for **.***.**.**.**.***.*****.Page
[INFO]                   [ERROR] Wrong number of argument for a java.lang.Iterable implementation

OrderMobile是一个简单的dto:

public class SortMobile implements Serializable, Iterable<OrderMobile>
{

    private static final long serialVersionUID = -8226494389482286795L;

    public static final Direction DEFAULT_DIRECTION = Direction.ASC;

    private List<OrderMobile> orders = new ArrayList<OrderMobile>();

    SortMobile() {

    }

    /**
     * Creates a new {@link Sort} instance using the given {@link Order}s.
     * 
     * @param orders must not be {@literal null}.
     */
    public SortMobile(final OrderMobile... orders) {
        this(Arrays.asList(orders));
    }

    /**
     * Creates a new {@link SortMobile} instance.
     * 
     * @param list must not be {@literal null} or contain {@literal null}.
     */
    public SortMobile(final List<OrderMobile> list) {

        if (null == list || list.isEmpty()) {
            throw new IllegalArgumentException("You have to provide at least one sort property to sort by!");
        }

        this.orders = list;
    }

    /**
     * Creates a new {@link SortMobile} instance. Order defaults to {@value Direction#ASC}.
     * 
     * @param properties must not be {@literal null} or contain {@literal null} or empty strings
     */
    public SortMobile(final String... properties) {
        this(DEFAULT_DIRECTION, properties);
    }

    /**
     * Creates a new {@link SortMobile} instance.
     * 
     * @param direction defaults to {@linke Sort#DEFAULT_DIRECTION} (for {@literal null} cases, too)
     * @param properties must not be {@literal null} or contain {@literal null} or empty strings
     */
    public SortMobile(final Direction direction, final String... properties) {
        this(direction, properties == null ? new ArrayList<String>() : Arrays.asList(properties));
    }

    /**
     * Creates a new {@link SortMobile} instance.
     * 
     * @param direction
     * @param properties
     */
    public SortMobile(final Direction direction, final List<String> properties) {

        if (properties == null || properties.isEmpty()) {
            throw new IllegalArgumentException("You have to provide at least one property to sort by!");
        }

        this.orders = new ArrayList<OrderMobile>(properties.size());

        for (String property : properties) {
            this.orders.add(new OrderMobile(direction, property));
        }

    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {

        if (this == obj) {
            return true;
        }

        if (!(obj instanceof SortMobile)) {
            return false;
        }

        SortMobile that = (SortMobile) obj;

        return this.orders.equals(that.orders);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {

        int result = 17;
        result = 31 * result + orders.hashCode();
        return result;
    }

    // GETTER SETTER
    public void setOrders(final List<OrderMobile> orders) {
        this.orders = orders;
    }

    public List<OrderMobile> getOrders() {
        return orders;
    }

    public static Direction getDefaultDirection() {
        return DEFAULT_DIRECTION;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return Arrays.toString(orders.toArray(new OrderMobile[orders.size()]));
    }

    // ### elements of iterator implementation

    @Override
    public Iterator<OrderMobile> iterator() {

        return this.orders.iterator();
    }

    /**
     * Returns a new {@link Sort} consisting of the {@link Order}s of the current {@link Sort} combined with the given
     * ones.
     * 
     * @param sort can be {@literal null}.
     * @return
     */
    public SortMobile and(final SortMobile sort) {

        if (sort == null) {
            return this;
        }

        ArrayList<OrderMobile> these = new ArrayList<OrderMobile>(this.orders);

        for (OrderMobile order : sort) {
            these.add(order);
        }

        return new SortMobile(these);
    }

    /**
     * Returns the order registered for the given property.
     * 
     * @param property
     * @return
     */
    public OrderMobile getOrderFor(final String property) {

        for (OrderMobile order : this) {
            if (order.getProperty().equals(property)) {
                return order;
            }
        }

        return null;
    }

}

3.Code of Page:

public class OrderMobile implements Serializable {
    private static final long serialVersionUID = 1522511010900108987L;

    private static final Direction DEFAULT_DIRECTION = Direction.ASC;

    private Direction direction;
    private String property;

    OrderMobile() {
        super();
    }

    /**
     * Creates a new {@link OrderMobile} instance. if order is {@literal null} then order defaults to
     * {@link SortMobile#DEFAULT_DIRECTION}
     * 
     * @param direction can be {@literal null}, will default to {@link SortMobile#DEFAULT_DIRECTION}
     * @param property must not be {@literal null} or empty.
     */
    public OrderMobile(final Direction direction, final String property) {

        if (!hasText(property)) {
            throw new IllegalArgumentException("Property must not null or empty!");
        }

        this.direction = direction == null ? DEFAULT_DIRECTION : direction;
        this.property = property;
    }

    private boolean hasText(final String s) {
        return s != null && s.trim().length() > 0;
    }

    /**
     * Creates a new {@link OrderMobile} instance. Takes a single property. Direction defaults to
     * {@link SortMobile#DEFAULT_DIRECTION}.
     * 
     * @param property must not be {@literal null} or empty.
     */
    public OrderMobile(final String property) {
        this(DEFAULT_DIRECTION, property);
    }

    /**
     * Returns the order the property shall be sorted for.
     * 
     * @return
     */

    public Direction getDirection() {
        return direction;
    }

    public void setDirection(final Direction direction) {
        this.direction = direction;
    }

    /**
     * Returns the property to order for.
     * 
     * @return
     */

    public String getProperty() {
        return property;
    }

    public void setProperty(final String property) {
        this.property = property;
    }

    /**
     * Returns whether sorting for this property shall be ascending.
     * 
     * @return
     */
    public boolean isAscending() {
        return this.direction.equals(Direction.ASC);
    }

    /**
     * Returns a new {@link OrderMobile} with the given {@link OrderMobile}.
     * 
     * @param order
     * @return
     */
    public OrderMobile with(final Direction order) {
        return new OrderMobile(order, this.property);
    }

    /**
     * Returns a new {@link SortMobile} instance for the given properties.
     * 
     * @param properties
     * @return
     */
    public SortMobile withProperties(final String... properties) {
        return new SortMobile(this.direction, properties);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {

        int result = 17;

        result = 31 * result + direction.hashCode();
        result = 31 * result + property.hashCode();

        return result;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {

        if (this == obj) {
            return true;
        }

        if (!(obj instanceof OrderMobile)) {
            return false;
        }

        OrderMobile that = (OrderMobile) obj;

        return this.direction.equals(that.direction) && this.property.equals(that.property);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return property + ":" + direction;
    }  

}

包装回应:

public class PageMobile<T> implements Iterable<T>, Serializable {

    private static final long serialVersionUID = 867755909294344406L;

    private List<T> content = new ArrayList<T>();
    private PageRequestMobile pageable;
    private long total;

    // for serialization
    PageMobile() {

    }

    /**
     * Constructor of {@code Page}.
     * 
     * @param content the content of this page, must not be {@literal null}.
     * @param pageable the paging information, can be {@literal null}.
     * @param total the total amount of items available
     */
    public PageMobile(final List<T> content, final PageRequestMobile pageable, final long total) {

        if (null == content) {
            throw new IllegalArgumentException("Content must not be null!");
        }

        this.content.addAll(content);
        this.total = total;
        this.pageable = pageable;
    }

    /**
     * Creates a new {@link PageMobile} with the given content. This will result in the created {@link PageMobile} being
     * identical
     * to the entire {@link List}.
     * 
     * @param content must not be {@literal null}.
     */
    public PageMobile(final List<T> content) {
        this(content, null, null == content ? 0 : content.size());
    }

    /**
     * Returns the number of the current page. Is always non-negative and less that {@code Page#getTotalPages()}.
     * 
     * @return the number of the current page
     */
    public int getNumber() {
        return pageable == null ? 0 : pageable.getPageNumber();
    }

    /**
     * Returns the size of the page.
     * 
     * @return the size of the page
     */
    public int getSize() {
        return pageable == null ? 0 : pageable.getPageSize();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Page#getTotalPages()
     */

    public int getTotalPages() {
        return getSize() == 0 ? 0 : (int) Math.ceil((double) total / (double) getSize());
    }

    /**
     * Returns the number of elements currently on this page.
     * 
     * @return the number of elements currently on this page
     */
    public int getNumberOfElements() {
        return content.size();
    }

    /**
     * Returns the total amount of elements.
     * 
     * @return the total amount of elements
     */
    public long getTotalElements() {
        return total;
    }

    /**
     * set the total amount of elements.
     * 
     * 
     */
    public void setTotalElements(final Long total) {
        this.total = total;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Page#hasPreviousPage()
     */

    public boolean hasPreviousPage() {
        return getNumber() > 0;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Page#isFirstPage()
     */

    public boolean isFirstPage() {
        return !hasPreviousPage();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Page#hasNextPage()
     */

    public boolean hasNextPage() {
        return (getNumber() + 1) * getSize() < total;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Page#isLastPage()
     */

    public boolean isLastPage() {
        return !hasNextPage();
    }

    /**
     * Returns the page content as {@link List}.
     * 
     * @return
     */
    public List<T> getContent() {
        return Collections.unmodifiableList(content);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Page#hasContent()
     */

    public boolean hasContent() {
        return !content.isEmpty();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Page#getSort()
     */
    // FIXME to the version in
    public SortMobile getSort() {
        return pageable == null ? null : pageable.getSort();
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */

    @Override
    public String toString() {

        String contentType = "UNKNOWN";

        if (content.size() > 0) {
            contentType = content.get(0).getClass().getName();
        }

        return "Page " + getNumber() + " of " + getTotalPages() + " containing " + contentType + " instances";
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */

    @Override
    public boolean equals(final Object obj) {

        if (this == obj) {
            return true;
        }

        if (!(obj instanceof PageMobile<?>)) {
            return false;
        }

        PageMobile<?> that = (PageMobile<?>) obj;

        boolean totalEqual = this.total == that.total;
        boolean contentEqual = this.content.equals(that.content);
        boolean pageableEqual = this.pageable == null ? that.pageable == null : this.pageable.equals(that.pageable);

        return totalEqual && contentEqual && pageableEqual;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */

    @Override
    public int hashCode() {

        int result = 17;

        result = 31 * result + (int) (total ^ total >>> 32);
        result = 31 * result + (pageable == null ? 0 : pageable.hashCode());
        result = 31 * result + content.hashCode();

        return result;
    }

    /**
     * Adjust the page size, distributing items equally (+/- 1 item) on each page, given a maximum page size.
     * 
     * WARNING: this function reverse pages order.
     * TODO: delegate page order reversing to another function, to limit a single behavior for a given function.
     * 
     * @param page The page
     * @param request The associated page request
     * @param maxPageSize The maximum page size
     * @return The new ajusted page
     */
    public static <T> PageMobile<T> adjustPageSize(final PageMobile<T> page, final PageRequestMobile request, final int maxPageSize) {
        int totalElnts = (int) page.getTotalElements();
        int currentPageNumber = request.getPageNumber();
        if (totalElnts == 0) {
            List<T> newContent = new ArrayList<T>(0);
            PageRequestMobile newRequest = new PageRequestMobile(currentPageNumber, maxPageSize);
            return new PageMobile<T>(newContent, newRequest, totalElnts);
        }
        int nbPages = (int) Math.ceil((double) totalElnts / maxPageSize);
        int pageSize = totalElnts / nbPages;
        int nbOrphans = totalElnts % nbPages;
        if (nbOrphans > 0) {
            ++pageSize;
        }
        int startIndex = totalElnts;
        int endIndex = totalElnts;
        for (int pageNumber = 0; pageNumber <= currentPageNumber; ++pageNumber) {
            int currentPageSize = nbOrphans == 0 || pageNumber < nbOrphans ? pageSize : pageSize - 1;
            startIndex -= currentPageSize;
            endIndex = startIndex + currentPageSize;
        }

        List<T> newContent = page.getContent().subList(startIndex, endIndex);
        PageRequestMobile newRequest = new PageRequestMobile(currentPageNumber, pageSize);
        return new PageMobile<T>(newContent, newRequest, totalElnts);
    }

    // GETTER SETTER

    public void setContent(final List<T> content) {
        this.content = content;
    }

    public void setPageable(final PageRequestMobile pageable) {
        this.pageable = pageable;
    }

    public PageRequestMobile getPageable() {
        return pageable;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(final long total)
    {
        this.total = total;
    }

    @Override
    public Iterator<T> iterator() {

        return this.content.iterator();
    }

}

1 个答案:

答案 0 :(得分:0)

使用当前版本的gwt-jackson(0.6.1),您肯定无法将SortMobile用作类中的属性。我会看看如何解决它。

gwt-jackson无法解析SortMobile,因为它直接Iterable<OrderMobile>而不是Iterable<T> SortMobile<T>实现。

作为一种解决方法,您有一些解决方案:

  • 您可以在Iterable<OrderMobile>中将该属性声明为Page。这样,gwt-jackson将使用Iterable的序列化器/解串器,但解串器创建的实例将是ArrayList
  • 将SortMobile更改为SortMobile<T extends OrderMobile> implements Iterable<T>
  • 按照wikiSortMobile声明您自己的序列化程序/反序列化程序。

修改: 从版本0.6.2开始,您应该能够使用SortMobile而不会出现编译错误。