|
View:
New views
3 Messages
—
Rating Filter:
Alert me
|
|
|
Json ConverterOk, I have tried running this down in the group but I haven't really found anything that speaks to it directly, so I apologize if this is a repost.
There are numerous situations where I want to store Json data 'on' a user and retrieve that information unmolested in the future (mostly for interface component states which can take any form). As far as I can tell, there are no converters provided by default that allow you to have a field, say User.settings of type JsonValue, and have it handled in the described manner. So I've started writing one which works, mostly, but I am having issues with line 89 in the attached file. The internals of the JsonUtil.parse are supposed to take the value and return a JsonNull, JsonString, or JsonNumber depending on the provided input. Only strings that get to this line are not encapsolated by quotation marks which trips up the parser and makes type detection a little more difficult. Ideally, I would like to drop the parsing all together and use the type information that is ON the InboundVariable, but it is not exposed. So, my questions are: 1. Why is the type information of an InboundVariable not exposed. 2. Is there is there a better (potentially obvious) way to do this? Thanks, --Steve Skrla [JsonValueConverter.java] package com.qualys.common.dwr; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import java.util.Map.Entry; import org.directwebremoting.ConversionException; import org.directwebremoting.extend.ArrayOutboundVariable; import org.directwebremoting.extend.ConvertUtil; import org.directwebremoting.extend.Converter; import org.directwebremoting.extend.ConverterManager; import org.directwebremoting.extend.InboundContext; import org.directwebremoting.extend.InboundVariable; import org.directwebremoting.extend.NonNestedOutboundVariable; import org.directwebremoting.extend.ObjectOutboundVariable; import org.directwebremoting.extend.OutboundContext; import org.directwebremoting.extend.OutboundVariable; import org.directwebremoting.extend.ProtocolConstants; import org.directwebremoting.json.types.JsonArray; import org.directwebremoting.json.types.JsonObject; import org.directwebremoting.json.types.JsonValue; import com.qualys.common.util.JsonUtil; /** * Converts to and from <tt>JsonValue</tt>s. * * @author Steve Skrla */ public class JsonValueConverter implements Converter { private ConverterManager manager; @Override public Object convertInbound(Class<?> paramType, InboundVariable data) { return convert(data, data.getContext()); } private JsonValue convert(InboundVariable data, InboundContext inctx) { String value = data.getValue(); if(value.startsWith(ProtocolConstants.INBOUND_MAP_START)) { value = value.substring( value.indexOf(ProtocolConstants.INBOUND_MAP_START) + 1, value.lastIndexOf(ProtocolConstants.INBOUND_MAP_END)); JsonObject ret = new JsonObject(); StringTokenizer tokens = new StringTokenizer(value, ProtocolConstants.INBOUND_MAP_SEPARATOR); while(tokens.hasMoreTokens()) { String token = tokens.nextToken().trim(); if(token.length() == 0) { continue; } int splitIndx = token.indexOf(ProtocolConstants.INBOUND_MAP_ENTRY); if(splitIndx == 1) { throw new ConversionException(JsonObject.class); } String key = token.substring(0, splitIndx).trim(); JsonValue val = dereference(token.substring(splitIndx + 1), data, inctx); ret.put(key, val); } return ret; } else if(value.startsWith(ProtocolConstants.INBOUND_ARRAY_START)) { value = value.substring( value.indexOf(ProtocolConstants.INBOUND_ARRAY_START) + 1, value.lastIndexOf(ProtocolConstants.INBOUND_ARRAY_END)); JsonArray ret = new JsonArray(); StringTokenizer tokens = new StringTokenizer(value, ProtocolConstants.INBOUND_ARRAY_SEPARATOR); while(tokens.hasMoreTokens()) { String token = tokens.nextToken().trim(); if(token.length() > 0) ret.add(dereference(token, data, inctx)); } return ret; } else { return JsonUtil.parse(value); } } private JsonValue dereference(String value, InboundVariable data, InboundContext inctx) { String[] split = ConvertUtil.splitInbound(value); String splitValue = split[ConvertUtil.INBOUND_INDEX_VALUE]; String splitType = split[ConvertUtil.INBOUND_INDEX_TYPE]; InboundVariable nested = new InboundVariable(data.getContext(), null, splitType, splitValue); nested.dereference(); return convert(nested, inctx); } @Override public OutboundVariable convertOutbound(Object data, OutboundContext outctx) { if(data instanceof JsonObject) { return convertObject((JsonObject) data, outctx); } else if(data instanceof JsonArray) { return convertArray((JsonArray) data, outctx); } else { return convertPrimative((JsonValue) data, outctx); } } @Override public void setConverterManager(ConverterManager converterManager) { this.manager = converterManager; } protected OutboundVariable convertArray(JsonArray array, OutboundContext ctx) { ArrayOutboundVariable ov = new ArrayOutboundVariable(ctx); List<OutboundVariable> items = new ArrayList<OutboundVariable>(); ctx.put(array, ov); for(JsonValue value: array) { items.add(manager.convertOutbound(value, ctx)); } ov.setChildren(items); return ov; } protected OutboundVariable convertObject(JsonObject object, OutboundContext ctx) { ObjectOutboundVariable ov = new ObjectOutboundVariable(ctx); Map<String, OutboundVariable> items = new HashMap<String, OutboundVariable>(); ctx.put(object, ov); for(Entry<String, JsonValue> entry: object.entrySet()) { items.put( entry.getKey(), manager.convertOutbound(entry.getValue(), ctx)); } ov.setChildren(items); return ov; } protected OutboundVariable convertPrimative(JsonValue object, OutboundContext ctx) { return new NonNestedOutboundVariable(object.toExternalRepresentation()); } } --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Json ConverterCorrect me if I am wrong, you just want to store a representation of the
object as a JSON string? If this is the case, I think you are going through too much trouble. If you are working with the latest code from trunk take a look at dwr/ui/demo/web/json/jquery/people/edit.js. It illustrates an example of jquery making a DWR request and encoding a JSON object (using the jquery, jquery.json plugin): $.post("../../../dwr/jsonp/People/setPerson?param0=" + encodeURIComponent($.toJSON(person)), { }, You can do the same sort of thing and just pass your remoted method a JSON String. If it is a String DWR won't muck with it. Steve Skrla wrote: > Ok, I have tried running this down in the group but I haven't really > found anything that speaks to it directly, so I apologize if this is a > repost. > > There are numerous situations where I want to store Json data 'on' a > user and retrieve that information unmolested in the future (mostly > for interface component states which can take any form). As far as I > can tell, there are no converters provided by default that allow you > to have a field, say User.settings of type JsonValue, and have it > handled in the described manner. So I've started writing one which > works, mostly, but I am having issues with line 89 in the attached > file. The internals of the JsonUtil.parse are supposed to take the > value and return a JsonNull, JsonString, or JsonNumber depending on > the provided input. Only strings that get to this line are not > encapsolated by quotation marks which trips up the parser and makes > type detection a little more difficult. Ideally, I would like to drop > the parsing all together and use the type information that is ON the > InboundVariable, but it is not exposed. > > So, my questions are: > 1. Why is the type information of an InboundVariable not exposed. > 2. Is there is there a better (potentially obvious) way to do this? > > Thanks, > > --Steve Skrla > ------------------------------------------------------------------------ > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscribe@... > For additional commands, e-mail: users-help@... > > > __________ Information from ESET NOD32 Antivirus, version of virus signature database 4494 (20091009) __________ > > The message was checked by ESET NOD32 Antivirus. > > http://www.eset.com > __________ Information from ESET NOD32 Antivirus, version of virus signature database 4494 (20091009) __________ The message was checked by ESET NOD32 Antivirus. http://www.eset.com --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@... |
|
|
Re: Json ConverterSorry, I am not familiar with mailing list mechanics (apparently I am not automatically subscribed to responses to my original message?). Hopefully this gets where it is supposed to go ^.^ In case it doesn't match up, this is in response to http://markmail.org/message/yeshifqpfdxq7xdc
David: Thanks for the response. You are correct in your understanding / solution, and I did say that I did not want the data to be modified. However, I would like to allow for the possibility of modification and I feel that storing input from a post directly in the database is ... dangerous. I guess I could run the provided string through a quick JSON parse to see if it validates before persisting certain objects, but I would feel much safer it it was implicit. A side note: I am using a reflection hack to get at the type information. I can open a improvment ticket to ask for a getter if there is not some design decision keeping this information hidden. |
| Free embeddable forum powered by Nabble | Forum Help |