1

名前空間と ANY 要素を含む XML スキーマをコンパイルするために xjc を使用しています。必要に応じて外部の名前空間から要素を含め、要素定義の新しいバージョンが含まれる状況、または同じ名前の別の名前空間からの要素が含まれる状況を処理する必要があります。明らかに、これの XML バージョンは完全に機能しており、クライアント側のすべての要素に対して正しい QNAME を取得しますが、JSON については、要素名のみが存在する修飾されていない QNAME を取得します。これは、ある名前空間の「bob」という要素と、2 番目の名前空間の「bob」という別の要素を区別できないことを意味します。

見つけたすべての資料を読みましたが、これがサーバー側で必要なことだと思いますが、クライアント側で何が必要かわかりません。

@Provider
final static class JsonMoxyConfigurationContextResolver implements ContextResolver<MoxyJsonConfig> {

    @Override
    public MoxyJsonConfig getContext(Class<?> objectType) {
        final MoxyJsonConfig configuration = new MoxyJsonConfig();

        Map<String, String> namespacePrefixMapper = new HashMap<String, String>(2);
        namespacePrefixMapper.put("http://schema.jaxbmoxy.examples.jersey.glassfish.org/2013/08/customer", "c");
        namespacePrefixMapper.put("http://schema.jaxbmoxy.examples.jersey.glassfish.org/2013/08/other", "o");

        configuration.setNamespacePrefixMapper(namespacePrefixMapper);
        configuration.setNamespaceSeparator('.');

        return configuration;
    }
}

"c" スキーマは私が定義したベース スキーマであり、"o" スキーマは ANY を通じて組み込む要素定義を保持します。以下の例では、外部名前空間から o.stats と o.email をインポートしています。以下は、サーバー側で生成される JSON です。

{"c.customer": [
    {
        "id": "3",
        "personal-info": {
            "name": "Bobby Boogie",
            "o.stats": [{
                "age": "45",
                "height": "160 cm",
                "weight": "70 kg"
            }]
        },
        "contact-info": {
            "address": {
                "city": "My Town",
                "street": "123 Any Street",
                "country": "CA"
            },
            "phone-number": [
                {
                    "type": "work",
                    "value": "613-555-1111"
                },
                {
                    "type": "cell",
                    "value": "613-555-2222"
                }
            ]
        }
    },
    {
        "id": "2",
        "personal-info": {
            "name": "Fred Finkleman",
            "o.stats": [{
                "age": "55",
                "height": "182 cm",
                "weight": "86 kg"
            }]
        },
        "contact-info": {
            "address": {
                "city": "Fredsville",
                "street": "1 Happy Street",
                "country": "US"
            },
            "phone-number": [
                {
                    "type": "work",
                    "value": "613-555-1111"
                },
                {
                    "type": "cell",
                    "value": "613-555-2222"
                }
            ],
            "o.email": ["fred@email.com"]
        }
    },
    {
        "id": "1",
        "personal-info": {
            "name": "Tom Dooley",
            "o.stats": [{
                "age": "45",
                "height": "160 cm",
                "weight": "70 kg"
            }]
        },
        "contact-info": {
            "address": {
                "city": "My Town",
                "street": "123 Any Street",
                "country": "CA"
            },
            "phone-number": [
                {
                    "type": "work",
                    "value": "613-555-1111"
                },
                {
                    "type": "cell",
                    "value": "613-555-2222"
                }
            ]
        }
    }
]}

これを正しく機能させるには、クライアント側でどのような構成コードが必要ですか? 現時点では、次のものがあります。

@Override
protected void configureClient(ClientConfig clientConfig) {
    clientConfig.register(new MoxyXmlFeature());
    new ResourceConfig().property(MarshallerProperties.JSON_NAMESPACE_SEPARATOR, ".");
}

ありがとうございました!

4

1 に答える 1

2

MarshallerProperties.NAMESPACE_PREFIX_MAPPERまた、サーバー側で設定したものと一致するようにプロパティを設定する必要があります。

編集:上記のBlaiseの答えは正しいと感じていますが、Jersey 2.2のバグであるとしか思えない別の問題が発生しています。Blaiseの回答に基づいて作成したクライアントコードセグメントは次のとおりです。

@Override
protected void configureClient(ClientConfig clientConfig) {
    Map<String, String> namespacePrefixMapper = new HashMap<String, String>(2);
    namespacePrefixMapper.put("http://schema.jaxbmoxy.examples.jersey.glassfish.org/2013/08/customer", "c");
    namespacePrefixMapper.put("http://schema.jaxbmoxy.examples.jersey.glassfish.org/2013/08/other", "o");

    clientConfig.register(new MoxyXmlFeature());
    clientConfig.register(new MoxyJsonFeature());
    clientConfig.property(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespacePrefixMapper);
    clientConfig.property(MarshallerProperties.JSON_NAMESPACE_SEPARATOR, '.');
}

クライアント側では、着信 JSON の処理中に NPE を取得しています。

javax.ws.rs.ProcessingException: Unexpected error during response processing.
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:767)
at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:90)
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:671)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:422)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:667)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:396)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:296)
at org.glassfish.jersey.examples.jaxbmoxy.MoxyAppTest.testJsonCustomer(MoxyAppTest.java:172)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:264)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:443)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:424)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:241)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:443)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:296)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:443)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:424)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:241)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:174)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:972)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:425)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:375)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:705)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:655)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:301)
at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.readFrom(MOXyJsonProvider.java:580)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:188)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:988)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:833)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:768)
at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:96)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:761)
... 41 more

今、すべてが失われたわけではありません。属性プレフィックス処理を追加することで問題を解決できました。サーバー側では、JsonMoxyConfigurationContextResolver.getContext()に追加しました:

configuration.setAttributePrefix("@"); 

クライアント側では、configureClient()に以下を追加しました。

clientConfig.property(MarshallerProperties.JSON_ATTRIBUTE_PREFIX, "@");

受信した JSON が正しく処理されるようになり、含まれている JAXB 要素の QNAME に名前空間が追加されました。

お手伝いありがとう!!

于 2013-08-28T12:57:31.173 に答える