users@jersey.java.net

Re: [Jersey] entities encoding issues in the response

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 22 May 2008 17:32:34 +0200

Arul Dhesiaseelan wrote:
> No. writeTo() is not even not even invoked.
>

Hmmm... what version of Jersey are you using?

I cannot recall when i changed it but application-declared
readers/writers take precedence over Jersey defined ones.

I just added some unit tests that test overriding using String and JAXB
beans and they pass with no errors.

Paul.

> Thanks!
> Arul
>
> Paul Sandoz wrote:
>> Is the CDATAProvider.writeTo getting invoked?
>>
>> Paul.
>>
>> Arul Dhesiaseelan wrote:
>>> Paul,
>>>
>>> Thanks for your help.
>>>
>>> I tried this approach, but I am not seeing the SOP made it to my
>>> console. I suspect whether my custom stream writer is used at the
>>> first place. Is there a way to tell Jersey/Java to use my custom
>>> writer instead of the default writer?
>>>
>>> I see this in the console, which tells that at least my message body
>>> writer was loaded properly.
>>>
>>> INFO: Provider classes found:
>>> class impl.rest.jaxb.CDATAProvider
>>>
>>> Here is my MBW writer which uses the custom stream writer.
>>>
>>> @ProduceMime("application/xml")
>>> @Provider
>>> public class CDATAProvider implements MessageBodyWriter<CellType> {
>>>
>>> public void writeTo(CellType cellType,
>>> Class<?> type, Type genericType, Annotation annotations[],
>>> MediaType mediaType, MultivaluedMap<String, Object> headers,
>>> OutputStream out) throws IOException {
>>> try {
>>> JAXBContext jc = JAXBContext.newInstance(CellType.class);
>>> Marshaller marshaller = jc.createMarshaller();
>>> XMLStreamWriter swImpl =
>>> XMLOutputFactory.newInstance().createXMLStreamWriter(out);
>>> XMLStreamWriter sw = new MyStreamWriter(swImpl);
>>> marshaller.marshal(cellType, sw);
>>> } catch (XMLStreamException xse) {
>>> System.out.println(xse.getMessage());
>>> } catch (JAXBException je) {
>>> System.out.println(je.getMessage());
>>> }
>>> }
>>>
>>> public boolean isWriteable(Class<?> type, Type genericType,
>>> Annotation annotations[]) {
>>> return CellType.class.isAssignableFrom(type);
>>> }
>>>
>>> public long getSize(CellType cellType) {
>>> return -1;
>>> }
>>> }
>>>
>>>
>>> Best regards,
>>> Arul
>>>
>>> Paul Sandoz wrote:
>>>> As i understand it your use-case is you want to embed some generic
>>>> HTML content in some XML.
>>>>
>>>> Can you try the following code instead:
>>>>
>>>> private Rows processRowsResponse() {
>>>> List<RowType> rows = new ArrayList<RowType>();
>>>> RowType row = new RowType();
>>>> CellType cell = new CellType();
>>>> final String cdata = new StringBuilder().append("<div
>>>> class=\"progressOuterRow\"><div class=\"progressInnerRow\"
>>>> style=\"width: ").append(result.toString()).append("px;\"></div><div
>>>> class=\"progressText\">").append(used).append("/").append(total).append("
>>>> MB</div></div>").toString();
>>>> cell.setValue(cdata);
>>>> row.getCell().add(cell);
>>>> rows.add(row);
>>>> return rows;
>>>> }
>>>>
>>>> public class MyStreamWriter implements XMLStreamWriter {
>>>> private XMLStreamWriter mImpl;
>>>>
>>>> public MyStreamWriter(XMLStreamWriter xmlStreamWriter) throws
>>>> XMLStreamException {
>>>> this.mImpl = xmlStreamWriter;
>>>> }
>>>>
>>>> public void writeCharacters(String s) throws XMLStreamException {
>>>> System.out.println("writeCharacters: " + s);
>>>> mImpl.writeCData(s);
>>>> }
>>>>
>>>> //removed other methods
>>>> }
>>>>
>>>>
>>>> and check the output to see if the "writeCharacters: " string is
>>>> being printed and check if the content is escaped or not before the
>>>> delegated call.
>>>>
>>>> Paul.
>>>>
>>>> Arul Dhesiaseelan wrote:
>>>>> Tatu,
>>>>>
>>>>> I have the CDATA set in my resource class.
>>>>>
>>>>> @GET
>>>>> @Path("/list")
>>>>> @ProduceMime({"application/xml"})
>>>>> public Response getRows() {
>>>>> final Rows rows;
>>>>> rows = processRowsResponse();
>>>>> return Response.ok(rows).build();
>>>>> }
>>>>>
>>>>> private Rows processRowsResponse() {
>>>>> List<RowType> rows = new ArrayList<RowType>();
>>>>> RowType row = new RowType();
>>>>> CellType cell = new CellType();
>>>>> final String cdata = new
>>>>> StringBuilder().append("<![CDATA[<div
>>>>> class=\"progressOuterRow\"><div class=\"progressInnerRow\"
>>>>> style=\"width:
>>>>> ").append(result.toString()).append("px;\"></div><div
>>>>> class=\"progressText\">").append(used).append("/").append(total).append("
>>>>> MB</div></div>]]>").toString();
>>>>> cell.setValue(cdata);
>>>>> row.getCell().add(cell);
>>>>> rows.add(row);
>>>>> return rows;
>>>>> }
>>>>>
>>>>> I assume this CDATA will be sent as a string to the
>>>>> XMLStreamWriter.writeCharacters() when the
>>>>> MessageBodyWriter<CellType> is invoked.
>>>>>
>>>>> May be I missing something here?
>>>>>
>>>>> Thanks!
>>>>> Arul
>>>>>
>>>>> Tatu Saloranta wrote:
>>>>>> Code below looks correct, but where does that "CDATA"
>>>>>> come into String? Is it just added for testing?
>>>>>>
>>>>>> What seems to be happening is that for some reason
>>>>>> content you are getting is already xml-escaped (or is
>>>>>> fed to another xml stream writer); like OutputStream
>>>>>> or Writer passing its content back to xml writer.
>>>>>>
>>>>>> -+ Tatu +-
>>>>>>
>>>>>> --- Arul Dhesiaseelan <arul_at_fluxcorp.com> wrote:
>>>>>>
>>>>>>
>>>>>>> Paul,
>>>>>>>
>>>>>>> Here is my custom Stream writer. I just delegate
>>>>>>> writeCData to XMLStreamWriter. I will try with a standalone test.
>>>>>>>
>>>>>>> public class MyStreamWriter implements
>>>>>>> XMLStreamWriter {
>>>>>>> private XMLStreamWriter mImpl;
>>>>>>>
>>>>>>> public MyStreamWriter(XMLStreamWriter
>>>>>>> xmlStreamWriter) throws XMLStreamException {
>>>>>>> this.mImpl = xmlStreamWriter;
>>>>>>> }
>>>>>>>
>>>>>>> public void writeCData(String s) throws
>>>>>>> XMLStreamException {
>>>>>>> mImpl.writeCData(s);
>>>>>>> }
>>>>>>>
>>>>>>> public void writeCharacters(String s) throws
>>>>>>> XMLStreamException {
>>>>>>> if (shouldUseCData(s)) {
>>>>>>> System.out.println("Using CDATA");
>>>>>>> mImpl.writeCData(s);
>>>>>>> } else {
>>>>>>> mImpl.writeCharacters(s);
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> private boolean shouldUseCData(String s) {
>>>>>>> if (s.contains("CDATA")) {
>>>>>>> return true;
>>>>>>> } else return false;
>>>>>>> }
>>>>>>> //removed other methods
>>>>>>> }
>>>>>>>
>>>>>>> Am I missing something here?
>>>>>>>
>>>>>>> Thanks!
>>>>>>> Arul
>>>>>>>
>>>>>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109