Wednesday Mar 11, 2009

I've been having a great experience using Jersey 1.0.2 so far, along with jersey-json.jar

I've run into an issue today, and I just wanted to post my resolution here for people that might run into the same problem.  The issue is that if somewhere in a class, you were to state:

@XmlElementWrapper (name="attributes")
private List<Attribute> attribute;

in search of the marshalling (JSON)

{"attributes":
{"attribute":
[
{...},
{...}
]
}
}

The result of this code is exactly what you wanted when the size of the list (attribute) is greater than 1 (>1).  However, if that list happens to contain only a single element, JAXB-json will simplify the representation to be:

{"attributes":
{"attribute":
{...}
}
}

The issue here isn't so apparent, but as most people will understand, unless the implementation calls for it, this places an extra burden on the client (who expects "attributes" to be an array).  Now the client needs to do an extra check to check whether it got a JSONObject or a JSONArray.  Adding the following class will provide the proper functionality.

package com.sun.isaas.response;

import com.sun.jersey.api.json.JSONJAXBContext;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;


@Provider
public class MyJAXBContextResolver implements ContextResolver<JAXBContext> {

    private JAXBContext context;

    private Class[] types = {
        Response.class
    };

   public MyJAXBContextResolver() throws Exception {
        Map props = new HashMap<String, Object>();
        props.put(JSONJAXBContext.JSON_NOTATION, JSONJAXBContext.JSONNotation.MAPPED);
        props.put(JSONJAXBContext.JSON_ARRAYS, new HashSet<String>(types.length){{
           add("attribute");
           add("message");
           add("setting");
        }});
        this.context = new JSONJAXBContext(types, props);
   }

   @Override
   public JAXBContext getContext(Class<?> objectType) {
       for(Class<?> x : types){
           if(x.equals(objectType)){
               return context;
           }
       }
       return null;
   }
   
}

types: The list of classes that will use this contextResolver.

Reference: http://cs.franklin.edu/~swartoud/655/doc/jersey/com/sun/jersey/api/json/JSONJAXBContext.html 

JSON_NOTATION - What type of notation to use.  It is important to note that JSON_ARRAYS will only affect the mapping: JSONJAXBContext.JSONNotation.MAPPED

JSON_ARRAYS - Which elements in this context are to be represented as arrays

Tuesday Mar 10, 2009

Lately I've been working with a few java applications and decided I'd really like a more convenient way of killing the processes.  What I wanted was essentially:

jkill <name>

With little help from http://ubuntuforums.org/member.php?u=93334, I decided on the following, which I like quite a bit:

#!/bin/bash
for pid in `ps -Ao pid,command | grep java | grep $1 | sed "s/^[ ]*//" | cut -d\  -f1`;
do 
   ps -p$pid --no-header -f 
   kill -@2 $pid
done

Monday Dec 22, 2008

I don't think there's even been a time in my life when I've read so much in such a short period of time.  I feel like my head is about to explode, leaving the floor with a scattering of details about OpenSSO, Jax-WS, REST Error Handling, and Network.com API Specs... its awesome.

This blog copyright 2009 by John Crepezzi