Pergunta

Estou trabalhando com o LMS (grandes serviços comerciais) do eBay e continuei correndo no erro:

org.xml.sax.saxException:
Simpledseserializer encontrou uma criança
elemento, o que não é esperado, em
algo que estava tentando
Desserialize.

Depois muito de tentativa e erro, rastreei o problema. Acontece que isso funciona:

<?xml version="1.0" encoding="UTF-8"?>
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents">
  <Header>
    <Version>583</Version>
    <SiteID>0</SiteID>
  </Header>
  <AddFixedPriceItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">

Enquanto isso (o que tenho enviado) não:

<?xml version="1.0" encoding="UTF-8"?>
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents">
  <Header>
    <Version>583</Version>
    <SiteID>0</SiteID>
  </Header>
  <AddFixedPriceItemRequest>

A diferença é o atributo xml namespace no AddFixedPriceItemRequest. Atualmente, todo o meu XML está sendo marcado via Jaxb e não tenho certeza de qual é a melhor maneira de adicionar um segundo atributo xmlns a um elemento diferente no meu arquivo.

Então essa é a pergunta. Como adicionar um atributo xmlns a outro elemento no JAXB?

package ebay.apis.eblbasecomponents;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AddFixedPriceItemRequestType", propOrder = {
    "item"
})
public class AddFixedPriceItemRequestType
    extends AbstractRequestType
{

    @XmlElement(name = "Item")
    protected ItemType item;

    public ItemType getItem() {
        return item;
    }

    public void setItem(ItemType value) {
        this.item = value;
    }
}

Definição de classe adicionada por solicitação.

Editou a classe acima como sem efeito:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(namespace = "urn:ebay:apis:eBLBaseComponents",
name = "AddFixedPriceItemRequestType", propOrder = {
    "item"
})
public class AddFixedPriceItemRequestType

Aqui está um trecho do BulkDataExchangeRequestsType classe. Eu tentei jogar um namespace="urn:ebay:apis:eBLBaseComponents" no @XmlElement por AddFixedPriceItemRequest Mas não fez nada.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "BulkDataExchangeRequestsType", propOrder = {
    "header",
    "addFixedPriceItemRequest"
})
public class BulkDataExchangeRequestsType {

    @XmlElement(name = "Header")
    protected MerchantDataRequestHeaderType header;
    @XmlElement(name = "AddFixedPriceItemRequest")
    protected List<AddFixedPriceItemRequestType> addFixedPriceItemRequest;
Foi útil?

Solução

Até onde eu sei, seus fragmentos XML são semanticamente idênticos. o xmlns atributo no AddFixedPriceItemRequest O elemento é redundante, pois herda implicitamente o espaço para nome do seu elemento pai. Jaxb sabe disso e, portanto, não se incomoda em adicionar o espaço para nome a AddFixedPriceItemRequest - simplesmente não é necessário.

Se o servidor do eBay estiver funcionando apenas quando o AddFixedPriceItemRequest xmlns está presente, então está quebrado e está fazendo demandas sobre a entrada acima das exigidas pelo XML e pelo esquema. Se esse é realmente o caso (o que é difícil de acreditar, mas possível), o uso de um modelo de documento Java XML como o JAXB será uma luta, pois isso assumirá que o XML é XML é XML. Peidando de baixo nível sobre quais elementos obtêm o xmlns As declarações não são expostas à API, pois não deve ser necessária.

Nenhum dos quais está ajudando você. Minha abordagem seria marcar o modelo Jaxb para um objeto DOM (usando um DOMResult passou para o Marshaller), e então veja se você pode fazer alguns ajustes manuais do DOM para forçar o xmlns no documento nos lugares apropriados. Você pode então serializar esse DOM para XML e enviar isso.

Você não deveria ter que fazer isso, e eu suspeito que você esteja fazendo algo mais errado em algum lugar; Isso é mais provável do que o serviço da Web do eBay sendo quebrado assim.


EDIT: Aqui está outra sugestão, um pouco menos horrível que a solução Jaxb-to-Dom-para-XML. Se a sua solicitação XML for uma estrutura estática razoável, com apenas os valores numéricos/strings alterando, defina -o como um modelo de string, substitua os valores em tempo de execução e envie isso. Você pode interpretar os resultados usando o JAXB. Eu fiz isso no OAST com os serviços da Web que exigiu prefixos exatos de namespace, ao convencer as bibliotecas Java XML a se conformar com isso irracionalmente.

Outras dicas

Tente usar a anotação de classe

@XmlType(namespace="urn:ebay:apis:eBLBaseComponents")

ou

@XmlElement(namespace="urn:ebay:apis:eBLBaseComponents")

Anotação de propriedades se você deseja especificar apenas namespace em alguns casos

Verifique se os campos em uma classe gerada estão faltando o @XmlElement anotação e, se presente, eles estão perdendo o atributo do espaço para nome. Esses dois devem estar presentes para obter o prefixo do espaço para o nome de todos os elementos do seu XML marechal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top