You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by K Fung <kf...@gmail.com> on 2011/10/09 22:49:41 UTC

JSON ignore namespace behavior in IgnoreContentJettisonWriter

Hi all,

(not sure if this belongs in cxf-dev or cxf-user; given the level of code
detail here though, I'm thinking cxf-dev but feel free to redirect if
appropriate)

I'm looking to get some advice on how to fix a WebApplicationException /
IllegalStateException inside CXF's JSON code. I've got a solution in mind
for the CXF code but I'm not an expert in JSON so I'm wondering if my code
is incorrect or if this is truely a bug in CXF?

In my scenario, CXF is generating the following exception:

WARNING: WebApplicationException has been caught : Invalid JSON namespace:
http://www.w3.org/2001/XMLSchema-instance
 even when I have JSONProvider.setIgnoreNamespaces to be true.

The XML output is fine:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <Library xmlns:ns2="http://example.com/2011/book">
<Book>
 <ns2:Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:nil="true"/>
 </Book>
</Library>

However, the JSON output fails with HTTP 500 due to the above
WebApplicationException.

Looking at the source code, I can see that it's failing in
IgnoreContentJettisonWriter:

public void writeAttribute(String prefix, String uri,
                           String local, String value) throws
XMLStreamException {
    if (!writeXsiType && "type".equals(local) && "xsi".equals(prefix)) {
        return;
    }
    super.writeAttribute(prefix, uri, local, value);

}

At the time of invocation for IgnoreContentJettisonWriter.writeAttribute, we
have the following values:

prefix = xsi
uri = http://www.w3.org/2001/XMLSchema-instance
 local = nil
value = true
writeXsiType = false

Given these values, we still call super.writeAttribute which then
consequently bombs with the IllegalStateException.

To me, the naive solution in this scenario would be the following: If
writeXsiType is set to false and local != "type", super.writeAttribute
should be called with a null value for uri. With this change, the JSON
output looks like the following:

{"Library":
{"Book":
{"Book":
 {"@nil":"true"}
}
}
 }

What are your thoughts? Would there be any issues with reading this JSON?

Regards,
kl

Appendix A: JAXB Classes

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"book"})
@XmlRootElement(name = "Library")
public class Library {

    @XmlElement(name = "Book", required = true)
    protected List<Book> book;

    public List<Book> getBook() {
        if (this.book == null) {
            this.book = new ArrayList<Book>();
        }
        return this.book;
    }

    public void setBook(List<Book> l) {
        this.book = l;
    }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="Book", propOrder={"book"})
public class Book
{

  @XmlElement(name="Book", namespace="http://example.com/2011/book",
required=true, nillable=true)
  protected String book;

  public String getBook()
  {
    return this.book;
  }

  public void setBook(String value)
  {
    this.book = value;
  }
}

Appendix B: Invocation Example

    @GET
    @Path("book")
    public Library getBook() throws JAXBException {

        final Book john = new Book();
        john.setBook(null);

        Library lib = new Library();
        List<Book> l = new ArrayList<Book>(1);
        l.add(john);
        docs.setBook(l);

        return lib;
    }

Re: JSON ignore namespace behavior in IgnoreContentJettisonWriter

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

On 10/10/11 17:44, K Fung wrote:
> Hi Sergey,
>
> I should have checked trunk before writing that e-mail :(

no problems :-)

>
> It is indeed fixed in trunk (and thus I assume the latest 2.3.x and 2.4.x).

Yes.
Cheers, Sergey


>
> Thanks for the timely reply!
>
> Regards,
> kl
>
> On Mon, Oct 10, 2011 at 1:54 AM, Sergey Beryozkin<sb...@gmail.com>wrote:
>
>> Hi
>>
>> I think I got that fixed for the now being released 2.4.3 and 2.3.7, I
>> updated that code to block 'nil' attribute too.
>>
>> so, now it looks like this
>>
>> if (!writeXsiType&&  "xsi".equals(prefix)
>>     ("type".equals(local) || "nill".equals(local))) {
>>           return;
>> }
>>
>> Alternatively you can set a namespaceMap containing an xsi namespace, but
>> the above should fix the issue...
>> Try please 2.4.3 when it's available
>> Cheers, Sergey
>>
>>
>> On 09/10/11 21:49, K Fung wrote:
>>
>>> Hi all,
>>>
>>> (not sure if this belongs in cxf-dev or cxf-user; given the level of code
>>> detail here though, I'm thinking cxf-dev but feel free to redirect if
>>> appropriate)
>>>
>>> I'm looking to get some advice on how to fix a WebApplicationException /
>>> IllegalStateException inside CXF's JSON code. I've got a solution in mind
>>> for the CXF code but I'm not an expert in JSON so I'm wondering if my code
>>> is incorrect or if this is truely a bug in CXF?
>>>
>>> In my scenario, CXF is generating the following exception:
>>>
>>> WARNING: WebApplicationException has been caught : Invalid JSON namespace:
>>> http://www.w3.org/2001/**XMLSchema-instance<http://www.w3.org/2001/XMLSchema-instance>
>>>   even when I have JSONProvider.**setIgnoreNamespaces to be true.
>>>
>>> The XML output is fine:
>>>
>>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>>>   <Library xmlns:ns2="http://example.com/**2011/book<http://example.com/2011/book>
>>> ">
>>> <Book>
>>>   <ns2:Book xmlns:xsi="http://www.w3.org/**2001/XMLSchema-instance<http://www.w3.org/2001/XMLSchema-instance>
>>> "
>>> xsi:nil="true"/>
>>>   </Book>
>>> </Library>
>>>
>>> However, the JSON output fails with HTTP 500 due to the above
>>> WebApplicationException.
>>>
>>> Looking at the source code, I can see that it's failing in
>>> IgnoreContentJettisonWriter:
>>>
>>> public void writeAttribute(String prefix, String uri,
>>>                             String local, String value) throws
>>> XMLStreamException {
>>>      if (!writeXsiType&&   "type".equals(local)&&   "xsi".equals(prefix)) {
>>>
>>>          return;
>>>      }
>>>      super.writeAttribute(prefix, uri, local, value);
>>>
>>> }
>>>
>>> At the time of invocation for IgnoreContentJettisonWriter.**writeAttribute,
>>> we
>>> have the following values:
>>>
>>> prefix = xsi
>>> uri = http://www.w3.org/2001/**XMLSchema-instance<http://www.w3.org/2001/XMLSchema-instance>
>>>   local = nil
>>> value = true
>>> writeXsiType = false
>>>
>>> Given these values, we still call super.writeAttribute which then
>>> consequently bombs with the IllegalStateException.
>>>
>>> To me, the naive solution in this scenario would be the following: If
>>> writeXsiType is set to false and local != "type", super.writeAttribute
>>> should be called with a null value for uri. With this change, the JSON
>>> output looks like the following:
>>>
>>> {"Library":
>>> {"Book":
>>> {"Book":
>>>   {"@nil":"true"}
>>> }
>>> }
>>>   }
>>>
>>> What are your thoughts? Would there be any issues with reading this JSON?
>>>
>>> Regards,
>>> kl
>>>
>>> Appendix A: JAXB Classes
>>>
>>> @XmlAccessorType(**XmlAccessType.FIELD)
>>> @XmlType(name = "", propOrder = {"book"})
>>> @XmlRootElement(name = "Library")
>>> public class Library {
>>>
>>>      @XmlElement(name = "Book", required = true)
>>>      protected List<Book>   book;
>>>
>>>      public List<Book>   getBook() {
>>>          if (this.book == null) {
>>>              this.book = new ArrayList<Book>();
>>>          }
>>>          return this.book;
>>>      }
>>>
>>>      public void setBook(List<Book>   l) {
>>>          this.book = l;
>>>      }
>>>
>>> }
>>>
>>> @XmlAccessorType(**XmlAccessType.FIELD)
>>> @XmlType(name="Book", propOrder={"book"})
>>> public class Book
>>> {
>>>
>>>    @XmlElement(name="Book", namespace="http://example.com/**2011/book<http://example.com/2011/book>
>>> ",
>>> required=true, nillable=true)
>>>    protected String book;
>>>
>>>    public String getBook()
>>>    {
>>>      return this.book;
>>>    }
>>>
>>>    public void setBook(String value)
>>>    {
>>>      this.book = value;
>>>    }
>>> }
>>>
>>> Appendix B: Invocation Example
>>>
>>>      @GET
>>>      @Path("book")
>>>      public Library getBook() throws JAXBException {
>>>
>>>          final Book john = new Book();
>>>          john.setBook(null);
>>>
>>>          Library lib = new Library();
>>>          List<Book>   l = new ArrayList<Book>(1);
>>>          l.add(john);
>>>          docs.setBook(l);
>>>
>>>          return lib;
>>>      }
>>>
>>>
>>
>


Re: JSON ignore namespace behavior in IgnoreContentJettisonWriter

Posted by K Fung <kf...@gmail.com>.
Hi Sergey,

I should have checked trunk before writing that e-mail :(

It is indeed fixed in trunk (and thus I assume the latest 2.3.x and 2.4.x).

Thanks for the timely reply!

Regards,
kl

On Mon, Oct 10, 2011 at 1:54 AM, Sergey Beryozkin <sb...@gmail.com>wrote:

> Hi
>
> I think I got that fixed for the now being released 2.4.3 and 2.3.7, I
> updated that code to block 'nil' attribute too.
>
> so, now it looks like this
>
> if (!writeXsiType && "xsi".equals(prefix)
>    ("type".equals(local) || "nill".equals(local))) {
>          return;
> }
>
> Alternatively you can set a namespaceMap containing an xsi namespace, but
> the above should fix the issue...
> Try please 2.4.3 when it's available
> Cheers, Sergey
>
>
> On 09/10/11 21:49, K Fung wrote:
>
>> Hi all,
>>
>> (not sure if this belongs in cxf-dev or cxf-user; given the level of code
>> detail here though, I'm thinking cxf-dev but feel free to redirect if
>> appropriate)
>>
>> I'm looking to get some advice on how to fix a WebApplicationException /
>> IllegalStateException inside CXF's JSON code. I've got a solution in mind
>> for the CXF code but I'm not an expert in JSON so I'm wondering if my code
>> is incorrect or if this is truely a bug in CXF?
>>
>> In my scenario, CXF is generating the following exception:
>>
>> WARNING: WebApplicationException has been caught : Invalid JSON namespace:
>> http://www.w3.org/2001/**XMLSchema-instance<http://www.w3.org/2001/XMLSchema-instance>
>>  even when I have JSONProvider.**setIgnoreNamespaces to be true.
>>
>> The XML output is fine:
>>
>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>>  <Library xmlns:ns2="http://example.com/**2011/book<http://example.com/2011/book>
>> ">
>> <Book>
>>  <ns2:Book xmlns:xsi="http://www.w3.org/**2001/XMLSchema-instance<http://www.w3.org/2001/XMLSchema-instance>
>> "
>> xsi:nil="true"/>
>>  </Book>
>> </Library>
>>
>> However, the JSON output fails with HTTP 500 due to the above
>> WebApplicationException.
>>
>> Looking at the source code, I can see that it's failing in
>> IgnoreContentJettisonWriter:
>>
>> public void writeAttribute(String prefix, String uri,
>>                            String local, String value) throws
>> XMLStreamException {
>>     if (!writeXsiType&&  "type".equals(local)&&  "xsi".equals(prefix)) {
>>
>>         return;
>>     }
>>     super.writeAttribute(prefix, uri, local, value);
>>
>> }
>>
>> At the time of invocation for IgnoreContentJettisonWriter.**writeAttribute,
>> we
>> have the following values:
>>
>> prefix = xsi
>> uri = http://www.w3.org/2001/**XMLSchema-instance<http://www.w3.org/2001/XMLSchema-instance>
>>  local = nil
>> value = true
>> writeXsiType = false
>>
>> Given these values, we still call super.writeAttribute which then
>> consequently bombs with the IllegalStateException.
>>
>> To me, the naive solution in this scenario would be the following: If
>> writeXsiType is set to false and local != "type", super.writeAttribute
>> should be called with a null value for uri. With this change, the JSON
>> output looks like the following:
>>
>> {"Library":
>> {"Book":
>> {"Book":
>>  {"@nil":"true"}
>> }
>> }
>>  }
>>
>> What are your thoughts? Would there be any issues with reading this JSON?
>>
>> Regards,
>> kl
>>
>> Appendix A: JAXB Classes
>>
>> @XmlAccessorType(**XmlAccessType.FIELD)
>> @XmlType(name = "", propOrder = {"book"})
>> @XmlRootElement(name = "Library")
>> public class Library {
>>
>>     @XmlElement(name = "Book", required = true)
>>     protected List<Book>  book;
>>
>>     public List<Book>  getBook() {
>>         if (this.book == null) {
>>             this.book = new ArrayList<Book>();
>>         }
>>         return this.book;
>>     }
>>
>>     public void setBook(List<Book>  l) {
>>         this.book = l;
>>     }
>>
>> }
>>
>> @XmlAccessorType(**XmlAccessType.FIELD)
>> @XmlType(name="Book", propOrder={"book"})
>> public class Book
>> {
>>
>>   @XmlElement(name="Book", namespace="http://example.com/**2011/book<http://example.com/2011/book>
>> ",
>> required=true, nillable=true)
>>   protected String book;
>>
>>   public String getBook()
>>   {
>>     return this.book;
>>   }
>>
>>   public void setBook(String value)
>>   {
>>     this.book = value;
>>   }
>> }
>>
>> Appendix B: Invocation Example
>>
>>     @GET
>>     @Path("book")
>>     public Library getBook() throws JAXBException {
>>
>>         final Book john = new Book();
>>         john.setBook(null);
>>
>>         Library lib = new Library();
>>         List<Book>  l = new ArrayList<Book>(1);
>>         l.add(john);
>>         docs.setBook(l);
>>
>>         return lib;
>>     }
>>
>>
>

Re: JSON ignore namespace behavior in IgnoreContentJettisonWriter

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

I think I got that fixed for the now being released 2.4.3 and 2.3.7, I 
updated that code to block 'nil' attribute too.

so, now it looks like this

if (!writeXsiType && "xsi".equals(prefix)
     ("type".equals(local) || "nill".equals(local))) {
           return;
}

Alternatively you can set a namespaceMap containing an xsi namespace, 
but the above should fix the issue...
Try please 2.4.3 when it's available
Cheers, Sergey

On 09/10/11 21:49, K Fung wrote:
> Hi all,
>
> (not sure if this belongs in cxf-dev or cxf-user; given the level of code
> detail here though, I'm thinking cxf-dev but feel free to redirect if
> appropriate)
>
> I'm looking to get some advice on how to fix a WebApplicationException /
> IllegalStateException inside CXF's JSON code. I've got a solution in mind
> for the CXF code but I'm not an expert in JSON so I'm wondering if my code
> is incorrect or if this is truely a bug in CXF?
>
> In my scenario, CXF is generating the following exception:
>
> WARNING: WebApplicationException has been caught : Invalid JSON namespace:
> http://www.w3.org/2001/XMLSchema-instance
>   even when I have JSONProvider.setIgnoreNamespaces to be true.
>
> The XML output is fine:
>
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>   <Library xmlns:ns2="http://example.com/2011/book">
> <Book>
>   <ns2:Book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:nil="true"/>
>   </Book>
> </Library>
>
> However, the JSON output fails with HTTP 500 due to the above
> WebApplicationException.
>
> Looking at the source code, I can see that it's failing in
> IgnoreContentJettisonWriter:
>
> public void writeAttribute(String prefix, String uri,
>                             String local, String value) throws
> XMLStreamException {
>      if (!writeXsiType&&  "type".equals(local)&&  "xsi".equals(prefix)) {
>          return;
>      }
>      super.writeAttribute(prefix, uri, local, value);
>
> }
>
> At the time of invocation for IgnoreContentJettisonWriter.writeAttribute, we
> have the following values:
>
> prefix = xsi
> uri = http://www.w3.org/2001/XMLSchema-instance
>   local = nil
> value = true
> writeXsiType = false
>
> Given these values, we still call super.writeAttribute which then
> consequently bombs with the IllegalStateException.
>
> To me, the naive solution in this scenario would be the following: If
> writeXsiType is set to false and local != "type", super.writeAttribute
> should be called with a null value for uri. With this change, the JSON
> output looks like the following:
>
> {"Library":
> {"Book":
> {"Book":
>   {"@nil":"true"}
> }
> }
>   }
>
> What are your thoughts? Would there be any issues with reading this JSON?
>
> Regards,
> kl
>
> Appendix A: JAXB Classes
>
> @XmlAccessorType(XmlAccessType.FIELD)
> @XmlType(name = "", propOrder = {"book"})
> @XmlRootElement(name = "Library")
> public class Library {
>
>      @XmlElement(name = "Book", required = true)
>      protected List<Book>  book;
>
>      public List<Book>  getBook() {
>          if (this.book == null) {
>              this.book = new ArrayList<Book>();
>          }
>          return this.book;
>      }
>
>      public void setBook(List<Book>  l) {
>          this.book = l;
>      }
>
> }
>
> @XmlAccessorType(XmlAccessType.FIELD)
> @XmlType(name="Book", propOrder={"book"})
> public class Book
> {
>
>    @XmlElement(name="Book", namespace="http://example.com/2011/book",
> required=true, nillable=true)
>    protected String book;
>
>    public String getBook()
>    {
>      return this.book;
>    }
>
>    public void setBook(String value)
>    {
>      this.book = value;
>    }
> }
>
> Appendix B: Invocation Example
>
>      @GET
>      @Path("book")
>      public Library getBook() throws JAXBException {
>
>          final Book john = new Book();
>          john.setBook(null);
>
>          Library lib = new Library();
>          List<Book>  l = new ArrayList<Book>(1);
>          l.add(john);
>          docs.setBook(l);
>
>          return lib;
>      }
>