JAXBException: класс, неизвестный контексту в клиенте CXF JAX-WS с вызовом параметра anyType - PullRequest
2 голосов
/ 14 декабря 2011

Я получаю это исключение, когда пытаюсь вызвать веб-сервис .NET:

 javax.xml.bind.JAXBException: class com.pixelware.mdv.tramites.TramiteXML nor any of its super class is known to this context.

Клиент - это библиотека Java, созданная с использованием внешнего интерфейса CFX JAX-WS (классы, предварительно созданные с помощью WSDL)

Метод, который я пытаюсь вызвать, принимает (вложенный в другой объект) объект (anyType в WSDL)

Похоже, движок JAXB внутри CXF не может маршалировать (сериализовать в XML) мой класс,Это потому, что JAXB не может сериализовать класс, если он не зарегистрирован в своем контексте, а передаваемый класс является частью основной программы, а не клиентской библиотеки.

Документация CXF показывает множество параметров конфигурации,и, похоже, это можно сделать, добавив свойство AdditionalContextClasses к свойствам службы.Я не могу добавить это свойство по конфигурации, потому что мой клиент - это отдельная библиотека с классами, сгенерированными CFX.

Я попытался добавить свойство программно с помощью этого кода:

Map<String, Object> ctx = (BindingProvider)ws.getWSSoap()).getRequestContext();
ctx.put("jaxb.additionalContextClasses", new Class[] {TramiteXML.class});

Но этоне работаетПохоже, что эта конфигурация должна быть сделана до создания клиента.

Я также нашел эту запись , с той же (или очень похожей) проблемой, и предлагаемые решения далекоот простого.

Разве это не должно быть намного проще?Может быть, я что-то упустил.Есть предложения?

1 Ответ

1 голос
/ 15 декабря 2011

Ну, я нашел это.

Я заставил его работать, используя "сырой" API DIspatcher, который предоставляет CXF. Я создал такой метод:

public ReturnType registrar(RequestType request)
    {
        // That's the call that didn't worked. Registrar is the name of the method
    // return serviceCLient.registrar(user, password, request);

        try {
            JAXBContext context = JAXBContext.newInstance(RequestType.class, ReturnType.class, 
                    request.geGenericContent().getClass());

            Dispatch<Object> registrarDispatch = service.createDispatch(
                    RegistroElectronico.RegistroElectronicoSoap, context, Mode.PAYLOAD);

            registrarDispatch.getRequestContext().put(Dispatch.SOAPACTION_USE_PROPERTY, Boolean.TRUE );
            registrarDispatch.getRequestContext().put(Dispatch.SOAPACTION_URI_PROPERTY, "http://pixelware.com/RegistroTelematico/Registrar" );

            Registrar registrar = new Registrar();
            registrar.setLogin(this.user);
            registrar.setPassword(this.password);
            registrar.setSolicitud(request);

            RegistrarResponse response = (RegistrarResponse) registrarDispatch.invoke(registrar);
        return response.getRegistrarResult();


        } catch (JAXBException e) {
            throw new RuntimeException(e);
        } 
    }

Наконец, API Dispatcher оказалось проще в использовании, чем я думал (к счастью, для каждого вызова метода веб-службы существует класс).

Хитрость заключалась в том, чтобы добавить мой тип динамического объекта в JAXBContext.

В любом случае, мне интересно, почему что-то подобное не может быть сделано автоматически в CXF framework

...