gpt4 book ai didi

json - 在 Jersey 2.2 JAX-RS 下使用 JAXB 和 JSON 的命名空间

转载 作者:行者123 更新时间:2023-12-04 16:54:56 24 4
gpt4 key购买 nike

我正在使用 xjc 编译带有命名空间和任何元素的 XML 模式。我将根据需要包含来自外部命名空间的元素,并需要处理包含元素定义的新版本的情况,或者可能包含来自具有相同名称的另一个命名空间的元素。显然,此 XML 版本运行良好,我为客户端的所有元素获得了正确的 QNAME,但是,对于 JSON,我获得了一个仅包含元素名称的非限定 QNAME。这意味着我无法区分来自一个命名空间的名为“bob”的元素与来自第二个命名空间的名为“bob”的不同元素。

我已经阅读了我能找到的所有 Material ,并相信这是我在服务器端需要做的事情,但是,我不知道我在客户端需要什么:

@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, ".");
}

谢谢!

最佳答案

您还需要设置 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。

感谢您的帮助!!

关于json - 在 Jersey 2.2 JAX-RS 下使用 JAXB 和 JSON 的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18475977/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com