users@jersey.java.net

Re: [Jersey] can i use jersey's json Unmarshaller?

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 11 Dec 2008 11:11:10 +0100

Hi,

It looks like your MessageBodyReader should work OK with one
modification. In the readFrom method you need to create a new instance
of new HashMap<String, List<E>>() and not use the one on the field.
The MapReader is a singleton class.

Jersey supports Jettison's JSONObject and JSONArray directly for
resource methods, but i do not think this helps you.

If i understand correctly you have a JSON document that consists of
methods to be applied to an array of JSON objects. Each JSON objects
need to be unmarshaled to a Java bean or in your case you want to
unmarshal them to JAXB objects? is that correct?

If so i think there are ways you can do this. But i would like to know
if i have understood your use-case correctly before proposing a
solution (which i would involve reusing the JAXB message body readers
in your own MapReader.

Paul.


On Dec 11, 2008, at 2:35 AM, beanor wrote:

>
> paul:
>
> I am very Sorry for sending a bad code to you, Because that code
> include
> some chinese character.I had read the entity-provider-1.0.1-
> project.zip when
> sending the thread before, and i had wrote the code following the
> entity-provider example.
>
> Following the right code:
>
> ====================================
> package com.jersey.sample.provider;
>
> import java.io.IOException;
> import java.io.InputStream;
> import java.io.InputStreamReader;
> import java.io.Reader;
> import java.lang.annotation.Annotation;
> import java.lang.reflect.Type;
> import java.util.ArrayList;
> import java.util.HashMap;
> import java.util.List;
> import java.util.Map;
>
> import javax.ws.rs.Consumes;
> import javax.ws.rs.WebApplicationException;
> import javax.ws.rs.core.MediaType;
> import javax.ws.rs.core.MultivaluedMap;
> import javax.ws.rs.ext.MessageBodyReader;
> import javax.ws.rs.ext.Provider;
>
> import net.sf.json.JSONArray;
> import net.sf.json.JSONObject;
> import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
>
> import com.jersey.sample.Constant;
>
> /**
> *
> * @author Jack Dou
> * @since Dec 10, 2008
> */
> @Consumes("application/json")
> @Provider
> public class MapReader<E> implements MessageBodyReader<Map<String,
> List<E>>>
> {
> private static String[] methods = { "add", "delete", "update" };
> private Map<String, List<E>> returnMap = new HashMap<String,
> List<E>>();
>
> public boolean isReadable(Class<?> type, Type genericType,
> Annotation[] annotations, MediaType mediaType) {
> return type.isAssignableFrom(Map.class);
> }
>
> @SuppressWarnings("unchecked")
> public Map<String, List<E>> readFrom(Class<Map<String, List<E>>>
> type,
> Type genericType, Annotation[] annotations, MediaType
> mediaType,
> MultivaluedMap<String, String> httpHeaders, InputStream
> entityStream)
> throws IOException, WebApplicationException {
> String formData = readAsString(entityStream);
> JSONObject fromObj = JSONObject.fromObject(formData);
> Class<E> cls = getActualClass(genericType);
> for (String method : methods) {
> boolean isHasTheMethod = fromObj.containsKey(method);
> if (isHasTheMethod) {
> JSONArray arr = fromObj.getJSONArray(method);
> List<E> list = new ArrayList<E>();
> for (int i=0,size = arr.size(); i<size; i++) {
> JSONObject tempObj = (JSONObject)arr.get(i);
> JSONObject.toBean(tempObj, cls);
> list.add((E)JSONObject.toBean(tempObj, cls));
> }
> returnMap.put(method, list);
> }
> }
> return returnMap;
> }
>
> @SuppressWarnings("unchecked")
> public Class<E> getActualClass(Type genericType) {
> ParameterizedTypeImpl pti = (ParameterizedTypeImpl)
> genericType;
> Type[] types = pti.getActualTypeArguments();
> ParameterizedTypeImpl type = (ParameterizedTypeImpl) types[1];
> Type[] types2 = type.getActualTypeArguments();
> Class<E> type2 = (Class<E>) types2[0];
> return type2;
> }
>
> public final String readAsString(InputStream in) throws
> IOException {
> Reader reader = new InputStreamReader(in,Constant.CHARSET);
> StringBuilder sb = new StringBuilder();
> char[] c = new char[1024];
> int l;
> while ((l = reader.read(c)) != -1) {
> sb.append(c, 0, l);
> }
> return sb.toString();
> }
> }
> =====================================
>
>
> Paul Sandoz wrote:
>>
>> Why are you passing methods in the request? The methods "add",
>> "delete", "update" can correspond to POST, DELETE and PUT methods in
>> HTTP.
>>
>
> We want deal batch,So we sent a HTTP POST method from browser
> client, This
> idea is from google restful api:
> http://code.google.com/apis/calendar/developers_guide_protocol.html#batch
>
> I don't my way is right or not , Do you point it ?
>
> whether or not , I want implement convert a json string to java Map
> Object,
> Can you give me a example if you can, your entity-provider example is
> consucesing a application/x-www-form-urlencoded MidiaType, not is
> application/json.
>
> Ps: Is Converting json string to Java Set Object implemented for
> jersey1.0.1
> default?
>
> I am very thanks for your so soon replay. expacting your replay again.
>
> Best Regards!
>
> yours Jack from beijing.
>
>
>
> Paul Sandoz wrote:
>>
>> Hi,
>>
>> The source code you sent looks like it is corrupted, namely the
>> readFrom method has the following:
>>
>> for (int i=0,size = arr.size(); i getActualClass(Type
>> genericType) {
>> ParameterizedTypeImpl pti = (ParameterizedTypeImpl)
>> genericType;
>> Type[] types = pti.getActualTypeArguments();
>> ParameterizedTypeImpl type = (ParameterizedTypeImpl)
>> types[1];
>> Type[] types2 = type.getActualTypeArguments();
>> Class type2 = (Class) types2[0];
>> return type2;
>>
>> So i cannot evaluate the code properly.
>>
>> There is no existing functionality to return a Map instance for a
>> JSON
>> entity. The closest supported Java type is JSONObject from the
>> jettison library.
>>
>> Why are you passing methods in the request? The methods "add",
>> "delete", "update" can correspond to POST, DELETE and PUT methods in
>> HTTP.
>>
>> For an example of implementing providers you can look at the
>> following
>> sample:
>>
>>
>> http://download.java.net/maven/2/com/sun/jersey/samples/entity-provider/1.0.1/entity-provider-1.0.1-project.zip
>>
>> Paul.
>> On Dec 10, 2008, at 11:39 AM, beanor wrote:
>>
>>> hi paul: I want Unmarshall a json string to Map param of Resource'
>>> method,now , I do it as follow:
>>> package com.jersey.sample.provider;
>>>
>>> import java.io.IOException;
>>> import java.io.InputStream;
>>> import java.io.InputStreamReader;
>>> import java.io.Reader;
>>> import java.lang.annotation.Annotation;
>>> import java.lang.reflect.Type;
>>> import java.util.ArrayList;
>>> import java.util.HashMap;
>>> import java.util.List;
>>> import java.util.Map;
>>>
>>> import javax.ws.rs.Consumes;
>>> import javax.ws.rs.WebApplicationException;
>>> import javax.ws.rs.core.MediaType;
>>> import javax.ws.rs.core.MultivaluedMap;
>>> import javax.ws.rs.ext.MessageBodyReader;
>>> import javax.ws.rs.ext.Provider;
>>>
>>> import net.sf.json.JSONArray;
>>> import net.sf.json.JSONObject;
>>> import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
>>>
>>> import com.jersey.sample.Constant;
>>>
>>> /**
>>> *
>>> * @author Jack Dou
>>> * @since Dec 10, 2008
>>> */
>>> @Consumes("application/json")
>>> @Provider
>>> public class MapReader implements MessageBodyReader>> {
>>> private static String[] methods = { "add", "delete", "update" };
>>> private Map> returnMap = new HashMap>();
>>>
>>> public boolean isReadable(Class type, Type genericType,
>>> Annotation[] annotations, MediaType mediaType) {
>>> return type.isAssignableFrom(Map.class);
>>> }
>>>
>>> @SuppressWarnings("unchecked")
>>> public Map> readFrom(Class>> type,
>>> Type genericType, Annotation[] annotations, MediaType
>>> mediaType,
>>> MultivaluedMap httpHeaders, InputStream entityStream)
>>> throws IOException, WebApplicationException {
>>> String formData = readAsString(entityStream);
>>> JSONObject fromObj = JSONObject.fromObject(formData);
>>> Class cls = getActualClass(genericType);
>>> for (String method : methods) {
>>> boolean isHasTheMethod = fromObj.containsKey(method);
>>> if (isHasTheMethod) {
>>> JSONArray arr = fromObj.getJSONArray(method);
>>> List list = new ArrayList();
>>> for (int i=0,size = arr.size(); i
>>> getActualClass(Type genericType) {
>>> ParameterizedTypeImpl pti = (ParameterizedTypeImpl)
>>> genericType;
>>> Type[] types = pti.getActualTypeArguments();
>>> ParameterizedTypeImpl type = (ParameterizedTypeImpl)
>>> types[1];
>>> Type[] types2 = type.getActualTypeArguments();
>>> Class type2 = (Class) types2[0];
>>> return type2;
>>> }
>>>
>>> /**
>>> * 转化读取输入流中的数据为字符串型
>>> *
>>> * @param in 输入流
>>> * @return 输入流转化后的字符串
>>> * @throws IOException 输入流转化字符串失败,则报IO
>>> 异常
>>> */
>>> public final String readAsString(InputStream in) throws
>>> IOException {
>>> Reader reader = new InputStreamReader(in,Constant.CHARSET);
>>> StringBuilder sb = new StringBuilder();
>>> char[] c = new char[1024];
>>> int l;
>>> while ((l = reader.read(c)) != -1) {
>>> sb.append(c, 0, l);
>>> }
>>> return sb.toString();
>>> }
>>> }
>>> But I use json-lib.jar ,not jettison.jar, Can you gei me a demo for
>>> manual Unmarshall a json string to Map param using jersey default
>>> way? My English is poor,Sorry,Do you understand my meaning?
>>> View this message in context: can i use jersey's json Unmarshaller?
>>> Sent from the Jersey mailing list archive at Nabble.com.
>>
>>
>>
>
> --
> View this message in context: http://n2.nabble.com/can-i-use-jersey%27s-json-Unmarshaller--tp1638158p1641498.html
> Sent from the Jersey mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>