You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Joe Sunday <su...@csh.rit.edu> on 2008/06/17 20:32:47 UTC
REST + JSON + Namespaces
Sorry if this is obvious, but I can't find an answer. Spring 2.5, CXF
2.1, Jettison 1.0.1.
I've got a SOAP and a REST service both being configured in Spring..
REST works for XML, but I get an "Invalid JSON namespace" error if I
try to use JSON. I've tried to inject the correct Jettison mapping,
which doesn't seem to work. HOWEVER, it does seem to be doing the
right thing with the "cxf" namespace on error.
Spring config:
<util:map id="jsonNamespaceMap" map-class="java.util.Hashtable">
<entry key="http://www.acme.com/test" value="t"/>
<entry key="http://cxf.apache.org/bindings/xformat"
value="cxf"/>
</util:map>
<bean id="jsonInputFactory"
class="org.codehaus.jettison.mapped.MappedXMLInputFactory">
<constructor-arg ref="jsonNamespaceMap"/>
</bean>
<bean id="jsonOutputFactory"
class="org.codehaus.jettison.mapped.MappedXMLOutputFactory">
<constructor-arg ref="jsonNamespaceMap"/>
</bean>
<jaxrs:server id="systemEndpoint" address="/system">
<jaxrs:serviceBeans>
<ref bean="systemImpl"/>
</jaxrs:serviceBeans>
<jaxrs:properties>
<entry key="javax.xml.stream.XMLInputFactory">
<ref bean="jsonInputFactory"/>
</entry>
<entry key="javax.xml.stream.XMLOutputFactory">
<ref bean="jsonOutputFactory"/>
</entry>
</jaxrs:properties>
</jaxrs:server>
Return type;
@XmlRootElement(name = "JSONTest", namespace = "http://www.acme.com/
test")
@XmlType(name = "", propOrder = {"a", "b", "c"})
@XmlAccessorType(XmlAccessType.FIELD)
public class JSONTest {
@XmlElement
private String a;
@XmlElement
private String b;
@XmlElement
private String c;
REST impl:
@GET
@Path("/jupdate/")
public JSONTest jupdates() {
JSONTest b = new JSONTest("1", "2", "3");
return b;
}
$ curl -H "Accept: application/xml" http://localhost:8080/test/system/jupdate
<ns2:JSONTest xmlns:ns2="http://www.acme.com/test"><a>1</a><b>2</
b><c>3</c></ns2:JSONTest>
$ curl -H "Accept: application/json" http://localhost:8080/test/system/jupdate
{"cxf.XMLFault":{"cxf.faultstring":"java.lang.IllegalStateException:
Invalid JSON namespace: http:\/\/www.acme.com\/test"}}
Log file:
java.lang.IllegalStateException: Invalid JSON namespace: http://www.acme.com/test
at
org
.codehaus
.jettison
.mapped
.MappedNamespaceConvention
.getJSONNamespace(MappedNamespaceConvention.java:151)
at
org
.codehaus
.jettison
.mapped
.MappedNamespaceConvention.createKey(MappedNamespaceConvention.java:158)
at
org
.codehaus
.jettison
.mapped
.MappedXMLStreamWriter.writeStartElement(MappedXMLStreamWriter.java:241)
at
com
.sun
.xml
.bind
.v2
.runtime
.output.XMLStreamWriterOutput.beginStartTag(XMLStreamWriterOutput.java:
113)
...
If I remove the namespace declaration from JSONTest, I get a valid
answer, but the types on the wire are really JAXB generated and I want
namespaces on them for the XML domain:
$ curl -H "Accept: application/json" http://localhost:8080/test/system/jupdate
{"JSONTest":{"a":1,"b":2,"c":3}}
--Joe
Re: REST + JSON + Namespaces
Posted by Joe Sunday <su...@csh.rit.edu>.
Thanks for the hints. I added a setNamespaceMap(Map<String, String>)
setter to JSONProvider and set that with the map I had in spring, then
set that provider bean via jaxrs:entityProviders. I actually prefer
that, it's cleaner than creating the input and output factories like I
was attempting.
Is there an open JIRA for this or should I open one?
--Joe
On Jun 18, 2008, at 12:03 PM, Sergey Beryozkin wrote:
> Ok, sure, that can be fixed.
>
> In meantime, the simplest workaround is to copy and paste the
> existing JSONProvider, update it to pass the correct properties to
> the constructor, or possibly have the factory bean injected through
> spring, and then register the custom provider through
> jaxrs:providers, and it will be checked first...
>
> JAX-RS ContextResolvers will also be supported soon.
>
> Cheers, Sergey
>
>
>>
>> On Jun 18, 2008, at 11:35 AM, Sergey Beryozkin wrote:
>>> Just would like to clarify :
>>>
>>> Do you expect that the bean with id 'jsonOutputFactory' is to be
>>> used as a org.codehaus.jettison.mapped.MappedXMLOutputFactory
>>> instance ?
>>>
>>> At the moment, no jaxrs:properties are checked. But that can be
>>> fixed...
>>>
>>> Cheers, Sergey
>>>
>>
>> Yes.. I want my service to do JSON, but it doesn't work unless I
>> can configure jettison first with the namespace prefixes I need,
>> and I can't figure out how to inject that map via Spring anywhere.
>>
>> I see a couple examples on the web how to do it programatically,
>> but not how to do it in my spring container.
>>
>> --Joe
>
> ----------------------------
> IONA Technologies PLC (registered in Ireland)
> Registered Number: 171387
> Registered Address: The IONA Building, Shelbourne Road, Dublin 4,
> Ireland
Re: REST + JSON + Namespaces
Posted by Joe Sunday <su...@csh.rit.edu>.
I've opened up JIRA CXF-1671 and attached a patch against 2.1.. I will
generate a true SVN diff patch against the 2.1 trunk if you need it,
but it'll take me a little bit to update my current project to 2.1.1
first.
--Joe
On Jun 26, 2008, at 12:23 PM, Sergey Beryozkin wrote:
> Hi
>
> Thanks for trying these suggestions. Are you thinking of applying
> the changes you've referred to
> the existing JSONProvider ? That's are you explicitly configuring
> the existing JSONProvider in Spring ?
> Thats' probably a good idea - that way people can just reuse the
> existing provider rather than creating a duplicate...
> Please create a JIRA and attach your patch.
>
> Cheers, Sergey
>
> ----- Original Message ----- From: "Sergey Beryozkin" <sergey.beryozkin@iona.com
> >
> To: <us...@cxf.apache.org>
> Sent: Wednesday, June 18, 2008 5:03 PM
> Subject: Re: REST + JSON + Namespaces
>
>
> Ok, sure, that can be fixed.
>
> In meantime, the simplest workaround is to copy and paste the
> existing JSONProvider, update it to pass the correct properties to the
> constructor, or possibly have the factory bean injected through
> spring, and then register the custom provider through
> jaxrs:providers, and it will be checked first...
>
> JAX-RS ContextResolvers will also be supported soon.
>
> Cheers, Sergey
>
>
>>
>> On Jun 18, 2008, at 11:35 AM, Sergey Beryozkin wrote:
>>> Just would like to clarify :
>>>
>>> Do you expect that the bean with id 'jsonOutputFactory' is to be
>>> used as a org.codehaus.jettison.mapped.MappedXMLOutputFactory
>>> instance ?
>>>
>>> At the moment, no jaxrs:properties are checked. But that can be
>>> fixed...
>>>
>>> Cheers, Sergey
>>>
>>
>> Yes.. I want my service to do JSON, but it doesn't work unless I
>> can configure jettison first with the namespace prefixes I need,
>> and I can't figure out how to inject that map via Spring anywhere.
>>
>> I see a couple examples on the web how to do it programatically,
>> but not how to do it in my spring container.
>>
>> --Joe
>
> ----------------------------
> IONA Technologies PLC (registered in Ireland)
> Registered Number: 171387
> Registered Address: The IONA Building, Shelbourne Road, Dublin 4,
> Ireland
> ----------------------------
> IONA Technologies PLC (registered in Ireland)
> Registered Number: 171387
> Registered Address: The IONA Building, Shelbourne Road, Dublin 4,
> Ireland
Re: REST + JSON + Namespaces
Posted by Sergey Beryozkin <se...@iona.com>.
Hi
Thanks for trying these suggestions. Are you thinking of applying the changes you've referred to
the existing JSONProvider ? That's are you explicitly configuring the existing JSONProvider in Spring ?
Thats' probably a good idea - that way people can just reuse the existing provider rather than creating a duplicate...
Please create a JIRA and attach your patch.
Cheers, Sergey
----- Original Message -----
From: "Sergey Beryozkin" <se...@iona.com>
To: <us...@cxf.apache.org>
Sent: Wednesday, June 18, 2008 5:03 PM
Subject: Re: REST + JSON + Namespaces
Ok, sure, that can be fixed.
In meantime, the simplest workaround is to copy and paste the existing JSONProvider, update it to pass the correct properties to the
constructor, or possibly have the factory bean injected through spring, and then register the custom provider through
jaxrs:providers, and it will be checked first...
JAX-RS ContextResolvers will also be supported soon.
Cheers, Sergey
>
> On Jun 18, 2008, at 11:35 AM, Sergey Beryozkin wrote:
>> Just would like to clarify :
>>
>> Do you expect that the bean with id 'jsonOutputFactory' is to be used as a org.codehaus.jettison.mapped.MappedXMLOutputFactory
>> instance ?
>>
>> At the moment, no jaxrs:properties are checked. But that can be fixed...
>>
>> Cheers, Sergey
>>
>
> Yes.. I want my service to do JSON, but it doesn't work unless I can configure jettison first with the namespace prefixes I need,
> and I can't figure out how to inject that map via Spring anywhere.
>
> I see a couple examples on the web how to do it programatically, but not how to do it in my spring container.
>
> --Joe
----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland
----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland
Re: REST + JSON + Namespaces
Posted by Sergey Beryozkin <se...@iona.com>.
Ok, sure, that can be fixed.
In meantime, the simplest workaround is to copy and paste the existing JSONProvider, update it to pass the correct properties to the
constructor, or possibly have the factory bean injected through spring, and then register the custom provider through
jaxrs:providers, and it will be checked first...
JAX-RS ContextResolvers will also be supported soon.
Cheers, Sergey
>
> On Jun 18, 2008, at 11:35 AM, Sergey Beryozkin wrote:
>> Just would like to clarify :
>>
>> Do you expect that the bean with id 'jsonOutputFactory' is to be used as a org.codehaus.jettison.mapped.MappedXMLOutputFactory
>> instance ?
>>
>> At the moment, no jaxrs:properties are checked. But that can be fixed...
>>
>> Cheers, Sergey
>>
>
> Yes.. I want my service to do JSON, but it doesn't work unless I can configure jettison first with the namespace prefixes I need,
> and I can't figure out how to inject that map via Spring anywhere.
>
> I see a couple examples on the web how to do it programatically, but not how to do it in my spring container.
>
> --Joe
----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland
Re: REST + JSON + Namespaces
Posted by Joe Sunday <su...@csh.rit.edu>.
On Jun 18, 2008, at 11:35 AM, Sergey Beryozkin wrote:
> Just would like to clarify :
>
> Do you expect that the bean with id 'jsonOutputFactory' is to be
> used as a org.codehaus.jettison.mapped.MappedXMLOutputFactory
> instance ?
>
> At the moment, no jaxrs:properties are checked. But that can be
> fixed...
>
> Cheers, Sergey
>
Yes.. I want my service to do JSON, but it doesn't work unless I can
configure jettison first with the namespace prefixes I need, and I
can't figure out how to inject that map via Spring anywhere.
I see a couple examples on the web how to do it programatically, but
not how to do it in my spring container.
--Joe
Re: REST + JSON + Namespaces
Posted by Sergey Beryozkin <se...@iona.com>.
Hi
> Sorry if this is obvious, but I can't find an answer. Spring 2.5, CXF
> 2.1, Jettison 1.0.1.
It's ok, not obvious to me at all :-)
>
> I've got a SOAP and a REST service both being configured in Spring..
> REST works for XML, but I get an "Invalid JSON namespace" error if I
> try to use JSON. I've tried to inject the correct Jettison mapping,
> which doesn't seem to work. HOWEVER, it does seem to be doing the
> right thing with the "cxf" namespace on error.
>
> Spring config:
>
> <util:map id="jsonNamespaceMap" map-class="java.util.Hashtable">
> <entry key="http://www.acme.com/test" value="t"/>
> <entry key="http://cxf.apache.org/bindings/xformat"
> value="cxf"/>
> </util:map>
>
> <bean id="jsonInputFactory"
> class="org.codehaus.jettison.mapped.MappedXMLInputFactory">
> <constructor-arg ref="jsonNamespaceMap"/>
> </bean>
>
> <bean id="jsonOutputFactory"
> class="org.codehaus.jettison.mapped.MappedXMLOutputFactory">
> <constructor-arg ref="jsonNamespaceMap"/>
> </bean>
Just would like to clarify :
Do you expect that the bean with id 'jsonOutputFactory' is to be used as a org.codehaus.jettison.mapped.MappedXMLOutputFactory
instance ?
At the moment, no jaxrs:properties are checked. But that can be fixed...
Cheers, Sergey
>
> <jaxrs:server id="systemEndpoint" address="/system">
> <jaxrs:serviceBeans>
> <ref bean="systemImpl"/>
> </jaxrs:serviceBeans>
> <jaxrs:properties>
> <entry key="javax.xml.stream.XMLInputFactory">
> <ref bean="jsonInputFactory"/>
> </entry>
> <entry key="javax.xml.stream.XMLOutputFactory">
> <ref bean="jsonOutputFactory"/>
> </entry>
> </jaxrs:properties>
> </jaxrs:server>
>
> Return type;
> @XmlRootElement(name = "JSONTest", namespace = "http://www.acme.com/
> test")
> @XmlType(name = "", propOrder = {"a", "b", "c"})
> @XmlAccessorType(XmlAccessType.FIELD)
> public class JSONTest {
> @XmlElement
> private String a;
> @XmlElement
> private String b;
> @XmlElement
> private String c;
>
> REST impl:
> @GET
> @Path("/jupdate/")
> public JSONTest jupdates() {
> JSONTest b = new JSONTest("1", "2", "3");
> return b;
> }
>
> $ curl -H "Accept: application/xml" http://localhost:8080/test/system/jupdate
> <ns2:JSONTest xmlns:ns2="http://www.acme.com/test"><a>1</a><b>2</
> b><c>3</c></ns2:JSONTest>
>
> $ curl -H "Accept: application/json" http://localhost:8080/test/system/jupdate
> {"cxf.XMLFault":{"cxf.faultstring":"java.lang.IllegalStateException:
> Invalid JSON namespace: http:\/\/www.acme.com\/test"}}
>
> Log file:
> java.lang.IllegalStateException: Invalid JSON namespace: http://www.acme.com/test
> at
> org
> .codehaus
> .jettison
> .mapped
> .MappedNamespaceConvention
> .getJSONNamespace(MappedNamespaceConvention.java:151)
> at
> org
> .codehaus
> .jettison
> .mapped
> .MappedNamespaceConvention.createKey(MappedNamespaceConvention.java:158)
> at
> org
> .codehaus
> .jettison
> .mapped
> .MappedXMLStreamWriter.writeStartElement(MappedXMLStreamWriter.java:241)
> at
> com
> .sun
> .xml
> .bind
> .v2
> .runtime
> .output.XMLStreamWriterOutput.beginStartTag(XMLStreamWriterOutput.java:
> 113)
> ...
>
> If I remove the namespace declaration from JSONTest, I get a valid
> answer, but the types on the wire are really JAXB generated and I want
> namespaces on them for the XML domain:
>
> $ curl -H "Accept: application/json" http://localhost:8080/test/system/jupdate
> {"JSONTest":{"a":1,"b":2,"c":3}}
>
> --Joe
>
>
----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland