Renomear nó da resposta do XML de um serviço REST

7 respostas
J

Pessoal, sou novo em java e em REST, mas não completamente leigo, pois criei um serviço REST que lê os dados de uma determinada base de dados e os exibe em formato XML.

Bem, acontece que eu possuo um problema, na minha base de dados existe uma tabela chamada Products, a qual é utilizada para recuperar os dados e exibi-los em XML, mas quando eu exibo um resultado, o mesmo é exibido da seguinte forma:

<products>
    <business>KMAP</business>
    <productId>53824519</productId>
    <productNumber>Kohler Mobile App</productNumber>
    <recordType>ROOTVAR</recordType>
    <timeStamp>2012-03-01T12:14:16-03:00</timeStamp>
</products>

Observe que há um atributo chamado recordType, e é baseado no valor dele que eu gostaria de alterar o nó do XML, onde ao invés de chamá-lo de <products>, chamá-lo pelo valor desse atributo recordType, nesse caso ficaria assim:

<ROOTVAR>
    <business>KMAP</business>
    <productId>53824519</productId>
    <productNumber>Kohler Mobile App</productNumber>
    <recordType>ROOTVAR</recordType>
    <timeStamp>2012-03-01T12:14:16-03:00</timeStamp>
</ROOTVAR>

É possível?

Se alguém precisar do código eu posto aqui.

Obrigado.

7 Respostas

heatcold

Acredito que a representação correta utilizando XML seria:

<product> <business>KMAP</business> <productId>53824519</productId> <productNumber>Kohler Mobile App</productNumber> <recordType> <id>1</id> <name>TYPE1</name> </recordType> <timeStamp>2012-03-01T12:14:16-03:00</timeStamp> </product> Considerando que record type é composto por ID e NAME.

Caso, você precise de uma lista, deve ficar algo assim:

<products> <product> <business>KMAP</business> <productId>53824519</productId> <productNumber>Kohler Mobile App</productNumber> <recordType> <id>1</id> <name>TYPE1</name> </recordType> <timeStamp>2012-03-01T12:14:16-03:00</timeStamp> </product> <product> <business>KMAP</business> <productId>53824519</productId> <productNumber>Kohler Mobile App</productNumber> <recordType> <id>1</id> <name>TYPE1</name> </recordType> <timeStamp>2012-03-01T12:14:16-03:00</timeStamp> </product> </products> _

J

Não, talvez eu não tenha conseguido ser claro, o que eu quero é que o nome do nó so invés de ser products, seja o valor do record type.

heatcold

entendi! foi mal o desentendimento

Minduin

Opa,

Fiquei curioso sobre o porque mudar o nome da tag…

J

Então, eu tenho essa base e ela é genérica e outras aplicações utilizam ela, porém, para esse caso, um product ora vai ser um coelho, ora vai ser um elefante (isso foi só uma analogia).

Os Products são entidades que se relacionam com outra entidade ProductsAttributes, o que podemos perceber que terão atributos diferentes, por isso quero mudar o nome da tag, para fornecer ao cliente que vai consumir o meu serviço uma tag já formatada no tipo do dado que ele está consumindo, e que ele não precise fazer esse tratamento qundo receber a informação.

Minduin

Por não ter toda a informação do que você tem ai hoje não consigo entender o motivo dessa troca, mas isso é só curiosidade, o que importa é ver um meio de realizar essa mudança, como hoje você transforma o que veio do banco em xml, JAXB?

J

Vou postar a classe pra ver se ajuda!

Entidade:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import com.sun.xml.bind.CycleRecoverable;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author gregori
 */
@Entity
@Table(name = "PRODUCTS")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Products.findAll", query = "SELECT p FROM Products p"),
    @NamedQuery(name = "Products.findByProductId", query = "SELECT p FROM Products p WHERE p.productId = :productId"),
    @NamedQuery(name = "Products.findByProductNumber", query = "SELECT p FROM Products p WHERE p.productNumber = :productNumber"),
    @NamedQuery(name = "Products.findByDescription", query = "SELECT p FROM Products p WHERE p.description = :description"),
    @NamedQuery(name = "Products.findByRecordType", query = "SELECT p FROM Products p WHERE p.recordType = :recordType"),
    @NamedQuery(name = "Products.findByBusiness", query = "SELECT p FROM Products p WHERE p.business = :business"),
    @NamedQuery(name = "Products.findByTimeStamp", query = "SELECT p FROM Products p WHERE p.timeStamp = :timeStamp")})
public class Products implements Serializable,CycleRecoverable {
    private static final long serialVersionUID = 1L;
    // @Max(value=?)  @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
    @Id
    @Basic(optional = false)
    @NotNull
    @Column(name = "PRODUCT_ID")
    private BigDecimal productId;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 100)
    @Column(name = "PRODUCT_NUMBER")
    private String productNumber;
    @Size(max = 1000)
    @Column(name = "DESCRIPTION")
    private String description;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 20)
    @Column(name = "RECORD_TYPE")
    private String recordType;
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 10)
    @Column(name = "BUSINESS")
    private String business;
    @Column(name = "TIME_STAMP")
    @Temporal(TemporalType.TIMESTAMP)
    private Date timeStamp;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "productId")
    private Collection<RelatedItems> relatedItemsCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "relatedProductId")
    private Collection<RelatedItems> relatedItemsCollection1;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "groupId")
    private Collection<ProductGroups> productGroupsCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "productId")
    private Collection<ProductGroups> productGroupsCollection1;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "productId")
    private Collection<Copy> copyCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "productId")
    private Collection<Items> itemsCollection;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "productId")
    private Collection<ProductAttributes> productAttributesCollection;

    public Products() {
    }

    public Products(BigDecimal productId) {
        this.productId = productId;
    }

    public Products(BigDecimal productId, String productNumber, String recordType, String business) {
        this.productId = productId;
        this.productNumber = productNumber;
        this.recordType = recordType;
        this.business = business;
    }

    public BigDecimal getProductId() {
        return productId;
    }

    public void setProductId(BigDecimal productId) {
        this.productId = productId;
    }

    public String getProductNumber() {
        return productNumber;
    }

    public void setProductNumber(String productNumber) {
        this.productNumber = productNumber;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getRecordType() {
        return recordType;
    }

    public void setRecordType(String recordType) {
        this.recordType = recordType;
    }

    public String getBusiness() {
        return business;
    }

    public void setBusiness(String business) {
        this.business = business;
    }

    public Date getTimeStamp() {
        return timeStamp;
    }

    public void setTimeStamp(Date timeStamp) {
        this.timeStamp = timeStamp;
    }

    @XmlTransient
    public Collection<RelatedItems> getRelatedItemsCollection() {
        return relatedItemsCollection;
    }

    public void setRelatedItemsCollection(Collection<RelatedItems> relatedItemsCollection) {
        this.relatedItemsCollection = relatedItemsCollection;
    }

    @XmlTransient
    public Collection<RelatedItems> getRelatedItemsCollection1() {
        return relatedItemsCollection1;
    }

    public void setRelatedItemsCollection1(Collection<RelatedItems> relatedItemsCollection1) {
        this.relatedItemsCollection1 = relatedItemsCollection1;
    }

    @XmlTransient
    public Collection<ProductGroups> getProductGroupsCollection() {
        return productGroupsCollection;
    }

    public void setProductGroupsCollection(Collection<ProductGroups> productGroupsCollection) {
        this.productGroupsCollection = productGroupsCollection;
    }

    //@XmlTransient
    public Collection<ProductGroups> getProductGroupsCollection1() {
        return productGroupsCollection1;
    }

    public void setProductGroupsCollection1(Collection<ProductGroups> productGroupsCollection1) {
        this.productGroupsCollection1 = productGroupsCollection1;
    }

    @XmlTransient
    public Collection<Copy> getCopyCollection() {
        return copyCollection;
    }

    public void setCopyCollection(Collection<Copy> copyCollection) {
        this.copyCollection = copyCollection;
    }

    @XmlTransient
    public Collection<Items> getItemsCollection() {
        return itemsCollection;
    }

    public void setItemsCollection(Collection<Items> itemsCollection) {
        this.itemsCollection = itemsCollection;
    }

    @XmlTransient
    public Collection<ProductAttributes> getProductAttributesCollection() {
        return productAttributesCollection;
    }

    public void setProductAttributesCollection(Collection<ProductAttributes> productAttributesCollection) {
        this.productAttributesCollection = productAttributesCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (productId != null ? productId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Products)) {
            return false;
        }
        Products other = (Products) object;
        if ((this.productId == null && other.productId != null) || (this.productId != null && !this.productId.equals(other.productId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "entities.Products[ productId=" + productId + " ]";
    }

    @Override
    public Object onCycleDetected(Context cntxt) {
        Products prod = new Products(this.productId);
        return prod;
    }
    
}

Facade REST dos produtos

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package service;

import entities.Products;
import java.math.BigDecimal;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.*;

/**
 *
 * @author gregori
 */
@Stateless
@Path("entities.products")
public class ProductsFacadeREST extends AbstractFacade<Products> {
    @PersistenceContext(unitName = "teste1PU")
    private EntityManager em;

    public ProductsFacadeREST() {
        super(Products.class);
    }

    @POST
    @Override
    @Consumes({"application/xml", "application/json"})
    public void create(Products entity) {
        super.create(entity);
    }

    @PUT
    @Override
    @Consumes({"application/xml", "application/json"})
    public void edit(Products entity) {
        super.edit(entity);
    }

    @DELETE
    @Path("{id}")
    public void remove(@PathParam("id") BigDecimal id) {
        super.remove(super.find(id));
    }

    @GET
    @Path("{id}")
    @Produces({"application/xml", "application/json"})
    public Products find(@PathParam("id") BigDecimal id) {
        return super.find(id);
    }

    @GET
    @Override
    @Produces({"application/xml", "application/json"})
    public List<Products> findAll() {
        return super.findAll();
    }

    @GET
    @Path("{from}/{to}")
    @Produces({"application/xml", "application/json"})
    public List<Products> findRange(@PathParam("from") Integer from, @PathParam("to") Integer to) {
        return super.findRange(new int[]{from, to});
    }

    @GET
    @Path("count")
    @Produces("text/plain")
    public String countREST() {
        return String.valueOf(super.count());
    }

    @java.lang.Override
    protected EntityManager getEntityManager() {
        return em;
    }
    
}

Abstract Facade

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package service;

import java.util.List;
import javax.persistence.EntityManager;

/**
 *
 * @author gregori
 */
public abstract class AbstractFacade<T> {
    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }
    
}

Se ajudar, tá aí!

Criado 5 de março de 2012
Ultima resposta 5 de mar. de 2012
Respostas 7
Participantes 3